Add auto mode to the CAPI test app 18/140318/4
authorPiotr Sawicki <p.sawicki2@partner.samsung.com>
Mon, 24 Jul 2017 11:30:06 +0000 (13:30 +0200)
committerPiotr Sawicki <p.sawicki2@partner.samsung.com>
Wed, 26 Jul 2017 12:28:59 +0000 (14:28 +0200)
The client sends randomly generated privilege at random intervals
of time. The server responds with 'deny once' to all pending requests
also at random intervals. This mode allows to perform stress tests of
the IPC module.

Change-Id: I52aa284fef5d50daec6831b02f3bc34a6679d12a

src/capi/test/privacy_privilege_manager_test.cpp

index 5496cf9..a2c33f6 100644 (file)
  * @brief       This file contains test of CAPI for Privacy Privilege Manager
  */
 
+#include <functional>
 #include <map>
 #include <set>
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
+#include <random>
 #include <glib.h>
 #include <unistd.h>
 
@@ -196,6 +198,9 @@ void printAppHelp(const char *programName)
     printf("Options:\n");
     printf("-s  run as a server\n");
     printf("-c  run as a client (uses CAPI)\n");
+    printf("-a  run client or server in auto mode (stress testing)");
+    printf("    The client will send randomly generated requests at random intervals of time.");
+    printf("    The server will respond with 'deny once' to all pending requests at random intervals of time.");
     printf("-h  display this help end exit\n");
 }
 
@@ -212,6 +217,12 @@ void printServerHelp()
     printPrompt(Mode::SERVER);
 }
 
+std::function<int(void)> createRandomGenerator() {
+    std::uniform_int_distribution<int> distribution(0, 1000);
+    std::mt19937 engine(time(0));
+    return std::bind(distribution, engine);
+}
+
 struct ServerSimulator : public IServerCallbacks {
 
     ServerSimulator()
@@ -334,6 +345,16 @@ struct ServerSimulator : public IServerCallbacks {
         }
     }
 
+    void respondToAllRequests() {
+        for (const auto &reqSet : m_requests) {
+            for (const auto &req : reqSet.second) {
+                m_channel->popupResponse(reqSet.first, req.m_id, PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_ONCE);
+            }
+        }
+
+        m_requests.clear();
+    }
+
     void showPrivilegeRequests() {
         printf("fd          requestId   privilege\n");
         for (const auto &con : m_requests) {
@@ -394,9 +415,10 @@ public:
             throw std::logic_error("AppContext::initialize called with argc < 1");
         }
 
+        bool autoMode = false;
         int c;
         opterr = 0;
-        while ((c = getopt (argc, argv, "sch")) != -1) {
+        while ((c = getopt (argc, argv, "cash")) != -1) {
             switch (c) {
                 case 's':
                     m_mode = Mode::SERVER;
@@ -404,6 +426,9 @@ public:
                 case 'c':
                     m_mode = Mode::CLIENT;
                     break;
+                case 'a':
+                    autoMode = true;
+                    break;
                 case 'h':
                 default:
                     break;
@@ -429,6 +454,11 @@ public:
         GIOChannel *gio_channel = g_io_channel_unix_new(0);
         g_io_add_watch(gio_channel, static_cast<GIOCondition>(G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
                        &AppContext::mainLoopCallback, this);
+
+        if (autoMode) {
+            m_randomGenerator = createRandomGenerator();
+            g_timeout_add(0, &AppContext::timerCallback, this);
+        }
     }
 
     void run() {
@@ -601,10 +631,68 @@ private:
         return TRUE;
     }
 
+    static gboolean timerCallback(gpointer user_data) {
+        AppContext *ctx = static_cast<AppContext *>(user_data);
+
+        switch (ctx->m_mode) {
+            case Mode::CLIENT:
+                ctx->handleAutoClient();
+                break;
+            case Mode::SERVER:
+                ctx->handleAutoServer();
+                break;
+            case Mode::UNKNOWN:
+            default:
+                printf("Mode not set, exiting.\n");
+                exit(EXIT_FAILURE);
+        }
+
+        g_timeout_add(ctx->m_randomGenerator(), timerCallback, ctx);
+
+        return FALSE;
+    }
+
+    void handleAutoClient() {
+        int requests = m_randomGenerator() % 10;
+        static RequestId clientRequestId;
+
+        for (int ri = 0; ri < requests; ri++) {
+            std::string privilege = generateRandomString(1 + m_randomGenerator() % 128);
+
+            printf("sending localId: %d privilege: \"%s\"\n", clientRequestId, privilege.c_str());
+
+            ClientRequest *request = new ClientRequest{ clientRequestId++, m_mainloop, false };
+            ppm_error_e err = static_cast<ppm_error_e>(ppm_request_permission(privilege.c_str(),
+                                                       &AppContext::requestResponseCallback, request));
+            if (err != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) {
+                delete request;
+            }
+        }
+    }
+
+    void handleAutoServer() {
+        m_serverSimulator->respondToAllRequests();
+    }
+
+    std::string generateRandomString(int len) {
+        if (len > 1024)
+            throw std::logic_error("String too long " + std::to_string(len));
+
+        char tab[len + 1];
+
+        for (int i = 0; i < len; i++) {
+            tab[i] = 'a' + m_randomGenerator() % ('z' - 'a' + 1);
+        }
+        tab[len] = '\0';
+
+        return std::string(tab);
+    }
+
     GMainLoop *m_mainloop;
     ServerSimulator *m_serverSimulator;
     ServerChannel *m_channel;
     Mode m_mode;
+    std::function<int(void)> m_randomGenerator;
 };
 
 int main(int argc, char **argv)