Multiple security server clients stress test added.
[platform/core/test/security-tests.git] / tests / security-server-tests / security_server_tests_mt.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file       security_server_tests_mt.cpp
18  * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
19  * @version    1.0
20  * @ brief         This test creates multiple processes that connect to security
21  *                         server and perform random operations using its API. The purpose
22  *                         of this test is to check if security-server crashes when under
23  *                         heavy load. Test succeeds if all processes finish.
24  */
25
26 #include <dpl/log/log.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <security-server.h>
30 #include <sys/wait.h>
31 #include <random>
32 #include <functional>
33 #include <chrono>
34
35 namespace {
36 const size_t PROC_TOTAL = 1000; // total number of processes to spawn
37 const size_t PROC_MAX = 10;             // max number of processes working at the same time
38 const size_t LOOPS = 50;        // number of loop repeats
39
40 std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());
41
42 // common function data
43 struct Data {
44         char* cookie;   // not owned
45
46         Data(char* c): cookie(c) {}
47 };
48
49
50 // test functions
51 void request_cookie(const Data&) {
52         char cookie[20];
53         security_server_request_cookie(cookie, 20);
54 }
55
56 void check_privilege(const Data& d) {
57         int ret = security_server_get_gid("audio");
58         security_server_check_privilege(d.cookie, ret);
59 }
60
61 void check_privilege_by_cookie(const Data& d) {
62         security_server_check_privilege_by_cookie(d.cookie, "label", "rwxat");
63 }
64
65 void get_cookie_pid(const Data& d) {
66         security_server_get_cookie_pid(d.cookie);
67 }
68
69 void get_smack_label(const Data& d) {
70         char* label = security_server_get_smacklabel_cookie(d.cookie);
71         free(label);
72 }
73
74 void random_sleep(const Data&) {
75         std::uniform_int_distribution<size_t> distribution(0,100);
76         usleep(distribution(generator));
77 }
78
79
80 // list of test functions
81 std::vector<std::function<void(const Data&)> > functions = {
82                 random_sleep,
83                 request_cookie,
84                 check_privilege,
85                 check_privilege_by_cookie,
86                 get_cookie_pid,
87                 get_smack_label
88 };
89
90 } // namespace
91
92 // randomly calls test functions
93 void security_server_magic() {
94         char cookie[20];
95         security_server_request_cookie(cookie, 20);
96         Data d(cookie);
97
98         // random loop number
99         std::uniform_int_distribution<size_t> l_dist(0,LOOPS);
100         size_t loops = l_dist(generator);
101
102         // random function call
103         std::uniform_int_distribution<size_t> distribution(0,functions.size()-1);
104         auto rnd = std::bind(distribution, generator);
105         for (size_t i=0; i < loops;++i) {
106                 functions[rnd()](d);
107         }
108 }
109
110 int main()
111 {
112         size_t current = 0;
113         size_t spawned = 0;
114         for (;;) {
115                 if (current >= PROC_MAX || spawned >= PROC_TOTAL) {
116                         int status;
117                         int ret = wait(&status);
118
119                         // all processes spawned, no more children to wait for
120                         if (spawned >= PROC_TOTAL && ret <= 0)
121                                 break;
122
123                         current--;
124                 }
125
126                 // spawn predefined number of processes
127                 if (spawned < PROC_TOTAL) {
128                         pid_t pid = fork();
129                         if (pid == 0) {
130                                 LogDebug("START " << spawned);
131                                 security_server_magic();
132                                 LogError("STOP " << spawned);
133                                 exit(0);
134                         }
135                         else {
136                                 //LogWarning("PID " << pid);
137                                 spawned++;
138                                 current++;
139                         }
140                 }
141         }
142         LogInfo("Finished");
143     return 0;
144 }