--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ *
+ * @file test_performance_db.cpp
+ * @author Ernest Borowski (e.borowski@partner.samsung.com)
+ * @version 1.0
+ * @brief This file is implementation of test_performance_db functions.
+ */
+
+#define BOOST_TEST_MODULE SecurityManagerTest
+
+#include <boost/test/results_reporter.hpp>
+#include <boost/test/unit_test.hpp>
+#include <chrono>
+#include <cmath>
+#include <ctime>
+#include <functional>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "privilege_db_fixture.h"
+
+const int AVG_LOOPS = 300;
+const int MANY_LOOPS = 3000;
+const int FEW_LOOPS = 10;
+using namespace std::chrono;
+using IncrementAppAll = std::function <void (int&, int&, int&, int&)>;
+using IncrementAppPart = std::function <void (int&, int&)>;
+
+std::vector<AppDefinedPrivilege> getPrivileges()
+{
+ static int uniqueNumber = 0;
+
+ uniqueNumber++;
+ std::string privilegeArray[] = {"org.tizen.my_app.gps", "org.tizen.my_app.maps",
+ "org.tizen.my_app.browser",
+ "org.tizen.my_app.nfc", "org.tizen.my_app.message",
+ "org.tizen.my_app.audio"};
+ AppDefinedPrivilegesVector privileges;
+
+ for (const std::string& privilege : privilegeArray) {
+ privileges.push_back(std::make_tuple(privilege + std::to_string(uniqueNumber),
+ SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED, ""));
+ }
+
+ return(privileges);
+}
+
+void incrementAppFull(int &appId, int &pkgId, int &uid, int &authorId)
+{
+ ++appId;
+ ++pkgId;
+ ++uid;
+ ++authorId;
+}
+void incrementAppPart(int &appId, int &uid)
+{
+ ++appId;
+ ++uid;
+}
+
+duration <double> measureAddAppTime(int appCount, PrivilegeDBFixture &pdf, int incStartVal = 0,
+ IncrementAppAll inc = incrementAppFull)
+{
+ int iApp = incStartVal, iPkg = incStartVal;
+ int iAuthor = incStartVal, iUid = incStartVal;
+
+ auto start = system_clock::now();
+
+ for (int j = 0; j < appCount; j++) {
+ inc(iApp, iPkg, iAuthor, iUid);
+ BOOST_REQUIRE_NO_THROW(pdf.addAppNoCheck(pdf.app(iApp), pdf.pkg(iPkg), pdf.uid(iUid),
+ pdf.tizenVer(1), pdf.author(iAuthor), pdf.Hybrid));
+ }
+ auto end = system_clock::now();
+ return (end - start);
+}
+
+duration <double> measureRemoveTime(int appCount, PrivilegeDBFixture &pdf, int incStartVal = 0,
+ IncrementAppPart inc = incrementAppPart)
+{
+ int iApp = incStartVal, iUid = incStartVal;
+ auto start = system_clock::now();
+
+ for (int j = 0; j < appCount; j++) {
+ inc(iApp, iUid);
+ BOOST_REQUIRE_NO_THROW(pdf.removeAppNoCheck(pdf.app(iApp), pdf.uid(iUid)));
+ }
+ auto end = system_clock::now();
+ return (end - start);
+}
+
+duration <double> measureAddPrivilegeTime(int appCount, PrivilegeDBFixture &pdf,
+ int incStartValue = 0, IncrementAppPart inc = incrementAppPart)
+{
+ int iApp = incStartValue, iUid = incStartValue;
+ auto start = system_clock::now();
+
+ for (int j = 0; j < appCount; j++) {
+ inc(iApp, iUid);
+ BOOST_REQUIRE_NO_THROW(pdf.addAppDefinedPrivileges(pdf.app(iApp), pdf.uid(iUid),
+ getPrivileges()));
+ }
+ auto end = system_clock::now();
+ return (end - start);
+}
+
+std::string convertDurationToString(const duration <double> &time)
+{
+ double t = double(duration_cast<microseconds>(time).count());
+ std::stringstream stream;
+
+ stream << std::setprecision(3);
+ if (t < 1e3) {
+ stream << t << "us";
+ } else if (t < 1e6) {
+ t /= 1e3;
+ stream << t << "ms";
+ } else {
+ t /= 1e6;
+ stream << t << "s";
+ }
+ return stream.str();
+}
+
+double getRatio(const duration<double> &largeDbAvgTime, const duration<double> &smallDbAvgTime)
+{
+ return double(duration_cast<microseconds>(largeDbAvgTime).count()) /
+ (duration_cast<microseconds>(smallDbAvgTime).count());
+}
+
+void displayResult(const std::string &msg, const duration<double> &largeDbAvgTime,
+ const duration<double> &smallDbAvgTime,
+ int fullCount = AVG_LOOPS)
+{
+ double ratio = getRatio(largeDbAvgTime, smallDbAvgTime);
+ BOOST_TEST_MESSAGE("\tAverage time for " << msg << convertDurationToString(smallDbAvgTime)
+ << "\n\tAverage time for " << fullCount
+ << " apps: " << convertDurationToString(largeDbAvgTime)
+ << "\n\tRatio: " << ratio);
+}
+
+std::string durationToMicroseconds(const duration <double> &time)
+{
+ return std::to_string(double(duration_cast<microseconds>(time).count()));
+}
+
+BOOST_AUTO_TEST_SUITE(PERFORMANCE_DB_TEST)
+
+BOOST_AUTO_TEST_CASE(TXX_db_perf_add)
+{
+ duration <double> addAppTimeSmallDb, addAppTimeLargeDb;
+ {
+ PrivilegeDBFixture pdf;
+ addAppTimeSmallDb = measureAddAppTime(FEW_LOOPS, pdf) / FEW_LOOPS;
+ }
+ {
+ PrivilegeDBFixture pdf;
+ addAppTimeLargeDb = measureAddAppTime(AVG_LOOPS, pdf);
+ displayResult("adding " + std::to_string(FEW_LOOPS) + " apps: ", addAppTimeLargeDb / AVG_LOOPS,
+ addAppTimeSmallDb);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TXX_db_perf_priv)
+{
+ duration <double> addPrivTimeSmallDb, addPrivTimeLargeDb;
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(FEW_LOOPS, pdf);
+ addPrivTimeSmallDb = measureAddPrivilegeTime(FEW_LOOPS, pdf) / FEW_LOOPS;
+ }
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(AVG_LOOPS, pdf);
+ addPrivTimeLargeDb = measureAddPrivilegeTime(AVG_LOOPS, pdf);
+
+ displayResult("adding privileges to " + std::to_string(FEW_LOOPS) + " apps: ",
+ addPrivTimeLargeDb / AVG_LOOPS, addPrivTimeSmallDb);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TXX_db_perf_remove)
+{
+ duration <double> rmAppTimeSmallDb, rmAppTimeLargeDb;
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(FEW_LOOPS, pdf);
+ measureAddPrivilegeTime(FEW_LOOPS, pdf);
+ rmAppTimeSmallDb = measureRemoveTime(FEW_LOOPS, pdf) / FEW_LOOPS;
+ }
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(AVG_LOOPS, pdf);
+ measureAddPrivilegeTime(AVG_LOOPS, pdf);
+ rmAppTimeLargeDb = measureRemoveTime(AVG_LOOPS, pdf);
+
+ displayResult("removing " + std::to_string(FEW_LOOPS) + " apps: ",
+ rmAppTimeLargeDb / AVG_LOOPS, rmAppTimeSmallDb);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TXX_db_perf_add_custom_author)
+{
+ duration <double> addAppTimeSmallDb, addAppTimeLargeDb;
+
+ auto incrementSetAuthor = [](int &appId, int &pkgId, int &authorId, int &uid) {
+ ++appId;
+ ++pkgId;
+ ++uid;
+ authorId = AVG_LOOPS + FEW_LOOPS;
+ };
+
+ {
+ PrivilegeDBFixture pdf;
+ addAppTimeSmallDb = measureAddAppTime(FEW_LOOPS, pdf, 0, incrementSetAuthor) / FEW_LOOPS;
+ }
+ {
+ PrivilegeDBFixture pdf;
+ addAppTimeLargeDb = measureAddAppTime(AVG_LOOPS, pdf, 0, incrementSetAuthor);
+ displayResult("adding " + std::to_string(FEW_LOOPS) + " apps: ",
+ addAppTimeLargeDb / AVG_LOOPS, addAppTimeSmallDb);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TXX_db_perf_priv_custom_author)
+{
+ duration <double> addPrivTimeSmallDb, addPrivTimeLargeDb;
+
+ auto incrementSetAuthor = [](int& appId, int& pkgId, int& authorId, int& uid) {
+ ++appId;
+ ++pkgId;
+ ++uid;
+ authorId = AVG_LOOPS + FEW_LOOPS;
+ };
+
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(FEW_LOOPS, pdf, 0, incrementSetAuthor);
+ addPrivTimeSmallDb = measureAddPrivilegeTime(FEW_LOOPS, pdf) / FEW_LOOPS;
+ }
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(AVG_LOOPS, pdf, 0, incrementSetAuthor);
+ addPrivTimeLargeDb = measureAddPrivilegeTime(AVG_LOOPS, pdf);
+
+ displayResult("adding privileges to " + std::to_string(FEW_LOOPS) + " apps: ",
+ addPrivTimeLargeDb / AVG_LOOPS, addPrivTimeSmallDb);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TXX_db_perf_remove_custom_author)
+{
+ duration <double> rmAppTimeSmallDb, rmAppTimeLargeDb;
+
+ auto incrementSetAuthor = [](int& appId, int& pkgId, int& authorId, int& uid) {
+ ++appId;
+ ++pkgId;
+ ++uid;
+ authorId = AVG_LOOPS + FEW_LOOPS;
+ };
+
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(FEW_LOOPS, pdf, 0, incrementSetAuthor);
+ measureAddPrivilegeTime(FEW_LOOPS, pdf);
+ rmAppTimeSmallDb = measureRemoveTime(FEW_LOOPS, pdf) / FEW_LOOPS;
+ }
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(AVG_LOOPS, pdf, 0, incrementSetAuthor);
+ measureAddPrivilegeTime(AVG_LOOPS, pdf);
+ rmAppTimeLargeDb = measureRemoveTime(AVG_LOOPS, pdf);
+
+ displayResult("removing " + std::to_string(FEW_LOOPS) + " apps: ",
+ rmAppTimeLargeDb / AVG_LOOPS, rmAppTimeSmallDb);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TXX_db_perf_add_large)
+{
+ //measures average add time of adding 300 apps when there is 2700 apps installed.
+ duration <double> addAppTimeSmallDb, addAppTimeLargeDb;
+ const int ADD_APP_COUNT = MANY_LOOPS * 0.1;
+ const int EXISTING_APP_COUNT = MANY_LOOPS * 0.9;
+ {
+ PrivilegeDBFixture pdf;
+ addAppTimeSmallDb = measureAddAppTime(FEW_LOOPS, pdf) / FEW_LOOPS;
+ }
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(EXISTING_APP_COUNT, pdf);
+ addAppTimeLargeDb = measureAddAppTime(ADD_APP_COUNT, pdf);
+
+ displayResult("adding " + std::to_string(FEW_LOOPS) + " apps: ",
+ addAppTimeLargeDb / ADD_APP_COUNT, addAppTimeSmallDb, ADD_APP_COUNT);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TXX_db_perf_priv_large)
+{
+ //measures average adding privileges time of adding 300 apps privileges when there is 2700 apps with privileges installed.
+ duration <double> addPrivTimeSmallDb, addPrivTimeLargeDb;
+ const int ADD_PRIV_COUNT = MANY_LOOPS * 0.1;
+ const int EXISTING_PRIV_COUNT = MANY_LOOPS * 0.9;
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(FEW_LOOPS, pdf);
+ addPrivTimeSmallDb = measureAddPrivilegeTime(FEW_LOOPS, pdf) / FEW_LOOPS;
+ }
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(MANY_LOOPS, pdf);
+ measureAddPrivilegeTime(EXISTING_PRIV_COUNT, pdf);
+ addPrivTimeLargeDb = measureAddPrivilegeTime(ADD_PRIV_COUNT, pdf);
+
+ displayResult("adding privileges to " + std::to_string(FEW_LOOPS) + " apps: ",
+ addPrivTimeLargeDb / ADD_PRIV_COUNT, addPrivTimeSmallDb, ADD_PRIV_COUNT);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TXX_db_perf_remove_large)
+{
+ //measures average remove time of 10% apps when there is 3000 apps installed.
+ duration <double> rmAppTimeSmallDb, rmAppTimeLargeDb;
+ const int REMOVE_APP_COUNT = MANY_LOOPS * 0.1;
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(FEW_LOOPS, pdf);
+ measureAddPrivilegeTime(FEW_LOOPS, pdf);
+ rmAppTimeSmallDb = measureRemoveTime(FEW_LOOPS, pdf) / FEW_LOOPS;
+ }
+ {
+ PrivilegeDBFixture pdf;
+ measureAddAppTime(MANY_LOOPS, pdf);
+ measureAddPrivilegeTime(MANY_LOOPS, pdf);
+ rmAppTimeLargeDb = measureRemoveTime(REMOVE_APP_COUNT, pdf);
+
+ displayResult("removing " + std::to_string(FEW_LOOPS) + " apps: ",
+ rmAppTimeLargeDb / REMOVE_APP_COUNT, rmAppTimeSmallDb, REMOVE_APP_COUNT);
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()