Implement new tests for security server (API speed of call)
authorRadoslaw Bartosiak <r.bartosiak@samsung.com>
Thu, 20 Jun 2013 07:30:48 +0000 (09:30 +0200)
committerMarcin Niesluchowski <m.niesluchow@samsung.com>
Thu, 23 Jan 2014 14:04:27 +0000 (15:04 +0100)
[Issue#]       SSDWSSP-288
[Feature]      Create test cases for security-server API speed of call.
[Cause]        N/A
[Solution]     Implement new tests for security server (API speed of call)
[Verification] Build, install, run on device to read the measured times.

Change-Id: I9afa5bbf28f0dc42f91626ec88f2371204b40f71

packaging/security-tests.spec
tests/security-server-tests/CMakeLists.txt
tests/security-server-tests/security_server_measurer_API_speed.cpp [new file with mode: 0644]
tests/security-tests.sh

index d0c23ab..e51b20e 100644 (file)
@@ -65,6 +65,7 @@ osp-installer --uninstall=V5LKqDFBXm
 /usr/bin/security-tests-all.sh
 /usr/bin/test-performance-check.sh
 /usr/bin/perf
+
 /usr/bin/libsmack-test
 /usr/bin/libprivilege-control-test
 /usr/bin/security-server-tests-client-smack
@@ -79,6 +80,7 @@ osp-installer --uninstall=V5LKqDFBXm
 /etc/smack/test_smack_rules3
 /etc/smack/test_smack_rules4
 /usr/bin/security-server-tests-mt
+/usr/bin/security-server-tests-api-speed
 /etc/smack/test_smack_rules
 /etc/smack/test_smack_rules_lnk
 /usr/share/privilege-control/*
index 5a894ae..eb4fd41 100644 (file)
@@ -40,6 +40,8 @@ SET(TARGET_SEC_SRV_TC_SERVER_TESTS "security-server-tests-server")
 SET(TARGET_SEC_SRV_PWD_TESTS "security-server-tests-password")
 SET(TARGET_SEC_SRV_MT_TESTS "security-server-tests-mt")
 SET(TARGET_SEC_SRV_DBUS_TESTS "security-server-tests-dbus")
+SET(TARGET_SEC_SRV_MEASURER "security-server-tests-api-speed")
+
 
 # Sources definition
 
@@ -72,6 +74,10 @@ SET(SEC_SRV_MT_SOURCES
 SET(SEC_SRV_DBUS_SOURCES
     ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_dbus.cpp
    )
+SET(SEC_SRV_MEASURER_SOURCES
+    ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_measurer_API_speed.cpp
+    ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_mockup.cpp
+   )
 
 INCLUDE_DIRECTORIES(
     ${SEC_SRV_TESTS_DEP_INCLUDE_DIRS}
@@ -88,7 +94,7 @@ ADD_EXECUTABLE(${TARGET_SEC_SRV_TC_SERVER_TESTS} ${SEC_SRV_TC_SERVER_SOURCES})
 ADD_EXECUTABLE(${TARGET_SEC_SRV_PWD_TESTS} ${SEC_SRV_PWD_SOURCES})
 ADD_EXECUTABLE(${TARGET_SEC_SRV_MT_TESTS} ${SEC_SRV_MT_SOURCES})
 ADD_EXECUTABLE(${TARGET_SEC_SRV_DBUS_TESTS} ${SEC_SRV_DBUS_SOURCES})
-
+ADD_EXECUTABLE(${TARGET_SEC_SRV_MEASURER} ${SEC_SRV_MEASURER_SOURCES})
 
 
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_CLIENT_SMACK_TESTS}
@@ -112,6 +118,9 @@ TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_MT_TESTS}
 TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_DBUS_TESTS}
     ${SEC_SRV_TESTS_DEP_LIBRARIES})
 
+TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_MEASURER}
+    ${SEC_SRV_TESTS_DEP_LIBRARIES})
+
 # Installation
 
 INSTALL(TARGETS ${TARGET_SEC_SRV_CLIENT_SMACK_TESTS} DESTINATION /usr/bin)
@@ -121,3 +130,4 @@ INSTALL(TARGETS ${TARGET_SEC_SRV_TC_SERVER_TESTS} DESTINATION /usr/bin)
 INSTALL(TARGETS ${TARGET_SEC_SRV_PWD_TESTS} DESTINATION /usr/bin)
 INSTALL(TARGETS ${TARGET_SEC_SRV_MT_TESTS} DESTINATION /usr/bin)
 INSTALL(TARGETS ${TARGET_SEC_SRV_DBUS_TESTS} DESTINATION /usr/bin)
+INSTALL(TARGETS ${TARGET_SEC_SRV_MEASURER} DESTINATION /usr/bin)
diff --git a/tests/security-server-tests/security_server_measurer_API_speed.cpp b/tests/security-server-tests/security_server_measurer_API_speed.cpp
new file mode 100644 (file)
index 0000000..b4299cd
--- /dev/null
@@ -0,0 +1,737 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@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    security_server_measurer_API_speed.cpp
+ * @author  Radoslaw Bartosiak (radoslaw.bartosiak@samsung.com)
+ * @version 1.0
+ * @brief   Log security server API functions average execution times and some aproximation of maximal and minimal execution time.
+ * @details The functions are run at least NUMBER_OF_CALLS times (time is measured at the beginning and at the end, the difference is taken as the execution time).
+ * @details One test case for one function of security-server. Test pass always when there was no connection error (API calls themselves may fail).
+ * @details Measured times are logged using DLP testing framework logging functions. Calls each API function many times to take the average.
+ * @details This file contains TEST_CASEs. Each TEST_CASE consist of one or more RUNs, each RUN consist of one or more function calls.
+ * @details Each test case contains RUNs of one function only. The time is being measured before & after each run.
+ */
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+#include <dpl/singleton.h>
+#include <dpl/singleton_safe_impl.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <errno.h>
+#include <float.h>
+#include <fcntl.h>
+#include <security-server.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/smack.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include "security_server_mockup.h"
+
+/*Number of calls in a single test*/
+#define NUMBER_OF_CALLS (5)
+#define MICROSECS_PER_SEC (1000000)
+/*the constant is defined in security-server-common.h, not accessable to the outside world*/
+#define SECURITY_SERVER_MAX_OBJ_NAME (30)
+/* number of miliseconds, process will be suspended for multiplications of this quantum */
+#define QUANTUM (10000)
+/*Strings used in tests*/
+/*name of existing user group on test device like "tel_gprs"*/
+#define EXISTING_GROUP_NAME "telephony_makecall"
+/*below labels should not be used in the system*/
+#define M60_OBJECT_LABEL "tc060MeasurerLabel"
+#define M60_SUBJECT_LABEL "tc060Subject"
+#define M70_OBJECT_LABEL "tc070MeasurerLabel"
+#define M70_SUBJECT_LABEL "tc070Subject"
+#define M160_CUSTOMER_LABEL "my_customer_label"
+#define M170_OBJECT_LABEL "myObject"
+
+
+IMPLEMENT_SAFE_SINGLETON(DPL::Log::LogSystem);
+
+namespace {
+void securityClientEnableLogSystem(void) {
+  DPL::Log::LogSystemSingleton::Instance().SetTag("SEC_SRV_API_SPEED");
+}
+}
+
+/** Store statistics from a set of function calls
+*/
+struct readwrite_stats
+{
+    timeval current_start_time; /*of last API call*/
+    timeval current_end_time;   /*of last API call*/
+    int number_of_calls;        /*till now*/
+    double total_duration;      /*of all API calls*/
+    double average_duration;
+    double minimal_duration;    /*minimum of averages*/
+    double maximal_duration;    /*maximum of averages*/
+};
+
+/*Auxiliary functions*/
+
+/**Sleep for the given time
+     @param seconds
+     @param nanoseconds
+     @return 0 on success, -1 on error if process woken earlier
+*/
+int my_nanosecsleep(long nanoseconds) {
+    timespec sleep_spec;
+    sleep_spec.tv_sec = 0;
+    sleep_spec.tv_nsec = nanoseconds;
+    return nanosleep(&sleep_spec, NULL);
+}
+
+/**Read from pipe descriptor to buffer; retries if less than count bytes were read.
+    @param fd descriptor
+    @param buf start of buffer
+    @param count number of bytes read
+    @return number of bytes read (count)
+*/
+int my_pipe_read(int fd, void *buf, size_t count) {
+    ssize_t readf = 0;
+    ssize_t rest = count;
+    ssize_t s;
+    while (rest > 0) {
+        RUNNER_ASSERT_MSG(0 < (s = TEMP_FAILURE_RETRY(read(fd, buf + readf, rest))), "Error in read from pipe");
+        rest -= s;
+        readf += s;
+    }
+    return readf;
+}
+
+/**Write from buffer to a pipe ; retries if less than count bytes were written.
+    @param fd descriptor
+    @param buf start of buffer
+    @param count number of bytes to write
+    @return number of bytes written (count)
+*/
+int my_pipe_write(int fd, void *buf, size_t count) {
+    ssize_t writef = 0;
+    ssize_t rest = count;
+    ssize_t s;
+    while (rest > 0) {
+        RUNNER_ASSERT_MSG(0 <= (s = TEMP_FAILURE_RETRY(write(fd, buf + writef, rest))), "Error in write to pipe");
+        rest -= s;
+        writef += s;
+    }
+    return writef;
+}
+
+
+/** Check whether there was connection error during function call (Security Server API) based on exit code
+    @param result_code the exit code of a function
+    @return -1 if the function result code indicated network error, 0 otherwise
+*/
+int communication_succeeded(int result_code) {
+    if ((result_code == SECURITY_SERVER_API_ERROR_SOCKET) ||
+        (result_code == SECURITY_SERVER_API_ERROR_SEND_FAILED) ||
+        (result_code == SECURITY_SERVER_API_ERROR_RECV_FAILED))
+        return -1;
+    else
+        return 0;
+}
+
+/** Returns current system time (wrapper for standard system function)
+    @return current system time
+*/
+timeval my_gettime() {
+    timeval t;
+    int res = gettimeofday(&t, NULL);
+    RUNNER_ASSERT_MSG(res == 0, "gettimeofday() returned error value: " << res);
+    return t;
+}
+
+/** Return a difference between two times (wrapper for standard system function)
+    @param time t1
+    @param time t2
+    @return t1 - t2
+*/
+timeval my_timersub(timeval t1, timeval t2) {
+    timeval result;
+    timersub(&t1, &t2, &result);
+    return result;
+}
+
+double timeval_to_secs(timeval t) {
+    return ((double)t.tv_sec) + (t.tv_usec / (double)MICROSECS_PER_SEC);
+}
+
+double timeval_to_microsecs(timeval t) {
+    return ((double)t.tv_sec * (double)MICROSECS_PER_SEC) + ((double)t.tv_usec);
+}
+
+timeval secs_to_timeval(double s) {
+    timeval t;
+    t.tv_sec = (time_t)s;
+    t.tv_usec = (__suseconds_t) ((s - (double)t.tv_sec) * MICROSECS_PER_SEC);
+    return t;
+}
+
+/** Initialize statistics at the beginning of a TEST_CASE
+    @param stats [in/out] statistics to be initialized
+*/
+void initialize_stats(readwrite_stats *stats) {
+    stats->number_of_calls = 0;
+    stats->total_duration = 0.0;
+    stats->average_duration = 0.0;
+    stats->minimal_duration = DBL_MAX;
+    stats->maximal_duration = 0.0;
+}
+
+/** Save time at the beginning of a RUN
+    @param stats [in/out] statistics
+*/
+void start_stats_update(readwrite_stats *stats) {
+    stats->current_start_time = my_gettime();
+    //LogDebug("start_stats_update at:    %ld.%06ld\n", stats->current_start_time.tv_sec, stats->current_start_time.tv_usec);
+}
+
+/** Save time at the end of a RUN and updates the statistics (current_end_time, number_of_calls, total_duration, minimal_duration, maximal_duration)
+    @param stats [in/out] statistics
+*/
+void end_stats_update(readwrite_stats *stats) {
+    stats->current_end_time = my_gettime();
+    double current_duration = timeval_to_microsecs(my_timersub(stats->current_end_time, stats->current_start_time));
+    stats->total_duration += current_duration;
+    stats->number_of_calls += 1;
+    if (current_duration < stats->minimal_duration)
+        (stats->minimal_duration) = current_duration;
+    if (current_duration > stats->maximal_duration)
+        (stats->maximal_duration) = current_duration;
+}
+
+/** Updates the statistics (average_duration, number_of_new_calls, total_duration, minimal_duration, maximal_duration)
+    Function is used instead of start_stats_update and end_stats_update (e.g when current_duration and number_of_new_calls are reported by child process.
+    @param stats [in/out] statistics
+    @param number_of_new_calls number of function calls in the RUN
+    @param current_duration (total) of number_of_new calls
+*/
+void stats_update(readwrite_stats *stats, int number_of_new_calls, double current_duration) {
+    if (number_of_new_calls > 0) {
+        double current_average = (double)current_duration / (double)number_of_new_calls;
+        stats->average_duration = (double)((stats->total_duration) / (stats->number_of_calls));
+        stats->total_duration += current_duration;
+        stats->number_of_calls += number_of_new_calls;
+        if (current_average < stats->minimal_duration)
+            (stats->minimal_duration) = current_average;
+        if    (current_average > stats->maximal_duration)
+            (stats->maximal_duration) = current_average;
+     }
+     else
+         LogDebug("stats_update called after zero successful function calls \n");
+}
+
+/** Calculate the average time and calculates statistics taken by a single function call.
+    Called at the end of a TEST_CASE.
+    @param stats [in/out] statistics
+    @param function_name of the function called in tests (to be printed)
+*/
+void finish_stats(readwrite_stats *stats, const char* function_name) {
+    if ((stats->number_of_calls) > 0) {
+        stats->average_duration = (double)((stats->total_duration) / (stats->number_of_calls));
+        printf("The approx (min, max, avg) execution times for function:\n%s are: \n---(%'.2fus, %'.2fus, %'.2fus)\n", function_name, stats->minimal_duration, stats->maximal_duration, stats->average_duration);
+    }
+    else
+        LogDebug("No function call succeeded\n");
+}
+
+/*TEST CASES*/
+RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_API_SPEED_MEASURER)
+
+/*
+ * test: Tests the tests
+ * expected: The minimum shall be about (QUANTUM) = 10^-2s = 10000 us, max about (NUMBER_OF_CALLS*QUANTUM) = 5*10^-2s = 50000us, avg (average) about (0.5*NUMBER_OF_CALLS+1*QUANTUM)=3*10^-2s = 30000us. Max is no more than 50% bigger than minimum.
+ */
+RUNNER_TEST(m000_security_server_test_the_tests) {
+    int ret;
+    readwrite_stats stats;
+    double expected_min_min = QUANTUM;
+    double expected_min_max = 1.5 * expected_min_min;
+    double expected_avarage_min = (((double)(NUMBER_OF_CALLS + 1)) / 2.0) * expected_min_min;
+    double expected_avarage_max = 1.5 * expected_avarage_min;
+    double expected_max_min = ((double)(NUMBER_OF_CALLS)) * expected_min_min;
+    double expected_max_max = 1.5 * expected_max_min;
+    initialize_stats(&stats);
+    for (int i=0; i < NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = my_nanosecsleep((long) ((i+1)*QUANTUM*1000));
+        RUNNER_ASSERT_MSG(ret == 0, "system sleep function returned premature wake-up; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "my_nanosecsleep");
+    RUNNER_ASSERT_MSG((stats.average_duration>expected_avarage_min) && (stats.average_duration<expected_avarage_max), "Avarage time is suspicious - check the issue; stats.average_duration=" << stats.average_duration);
+    RUNNER_ASSERT_MSG((stats.minimal_duration>expected_min_min) && (stats.minimal_duration<expected_min_max), "Minimal time is suspicious - check the issue; stats.minimal_duration=" << stats.minimal_duration);
+    RUNNER_ASSERT_MSG((stats.maximal_duration>expected_max_min) && (stats.maximal_duration<expected_max_max), "Maximal time is suspicious - check the issue; stats.maximal_duration=" << stats.maximal_duration);
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m010_security_server_security_server_get_gid) {
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_get_gid(EXISTING_GROUP_NAME);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_get_gid");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m020_security_server_get_object_name) {
+    int ret;
+    char obj_name[SECURITY_SERVER_MAX_OBJ_NAME];
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_get_object_name(6001, obj_name, sizeof(obj_name));
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_get_object_name");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m030_security_server_request_cookie) {
+    int ret;
+    size_t cookie_size;
+    cookie_size = security_server_get_cookie_size();
+    char cookie[cookie_size];
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_request_cookie(cookie, cookie_size);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_request_cookie");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ * Create new processes and measures times of first calls of security_server_request_cookie in them
+ *
+ */
+RUNNER_TEST(m031_security_server_request_cookie_first_time_only) {
+    int ret;
+    size_t cookie_size;
+    cookie_size = security_server_get_cookie_size();
+    char cookie[cookie_size];
+    readwrite_stats stats;
+
+    int pipefd[2];
+    int cpid;
+    int number_of_calls;
+    double duration_of_calls;
+    /*initialize pipes - one pipe for one child process*/
+    RUNNER_ASSERT_MSG(0 == pipe(pipefd), "error in pipe");
+    initialize_stats(&stats);
+    for (int i = 0; i < NUMBER_OF_CALLS; i++) {
+        RUNNER_ASSERT_MSG(-1 != (cpid = fork()), "error in fork    #i = " << i);
+        if (cpid == 0) {        /* Child*/
+             close(pipefd[0]);                 /* Close unused read end */
+             timeval start_time;
+             timeval end_time;
+             start_time = my_gettime();
+             ret = security_server_request_cookie(cookie, cookie_size);
+             end_time = my_gettime();
+             if (communication_succeeded(ret) == 0) {
+                 number_of_calls = 1;
+                 duration_of_calls = timeval_to_microsecs(my_timersub(end_time, start_time));
+
+             } else
+             {
+                 number_of_calls = 0;
+                 duration_of_calls = 0.0;
+             }
+             RUNNER_ASSERT_MSG(my_pipe_write(pipefd[1], &number_of_calls, sizeof(number_of_calls)) == sizeof(number_of_calls), "error in write number of calls to pipe");
+             RUNNER_ASSERT_MSG(my_pipe_write(pipefd[1], &duration_of_calls, sizeof(duration_of_calls)) == sizeof(duration_of_calls), "error in write duration of calls to pipe");
+             close(pipefd[1]);
+             exit(EXIT_SUCCESS);
+         } else
+         {   /* Parent */
+             RUNNER_ASSERT_MSG(my_pipe_read(pipefd[0], &number_of_calls, sizeof(number_of_calls)) == sizeof(number_of_calls), "error in read number of calls to pipe");
+             RUNNER_ASSERT_MSG(my_pipe_read(pipefd[0], &duration_of_calls, sizeof(duration_of_calls)) == sizeof(duration_of_calls), "error in read duration of calls to pipe");
+             wait(NULL);                                /* Wait for child */
+             RUNNER_ASSERT_MSG(number_of_calls > 0, "commmunication error");
+             stats_update(&stats, number_of_calls, duration_of_calls);
+         }
+        /*parent*/
+    }
+    close(pipefd[1]);                    /* Close parent descriptors */
+    close(pipefd[0]);
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m040_security_server_get_cookie_size) {
+    size_t cookie_size;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        cookie_size = security_server_get_cookie_size();
+        RUNNER_ASSERT_MSG(cookie_size > 0, "cookie_size = " << cookie_size);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_get_cookie_size");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m050_security_server_check_privilege) {
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    const char *existing_group_name = EXISTING_GROUP_NAME;
+    size_t cookie_size;
+    int call_gid;
+    // we use existing group name for the measurment, however this is not neccessary
+    call_gid = security_server_get_gid(existing_group_name);
+    cookie_size = security_server_get_cookie_size();
+    char recved_cookie[cookie_size];
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_check_privilege(recved_cookie, (gid_t)call_gid);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_check_privilege");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+
+RUNNER_TEST(m060_security_server_check_privilege_by_cookie) {
+    size_t cookie_size;
+    cookie_size = security_server_get_cookie_size();
+    char cookie[cookie_size];
+    const char *object_label = M60_OBJECT_LABEL;
+    const char *access_rights = "r";
+    const char *access_rights_ext = "rw";
+    const char *subject_label = M60_SUBJECT_LABEL;
+    smack_accesses *handle;
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    RUNNER_ASSERT_MSG(-1 != system("touch /opt/home/root/pid_cycle"),
+                "Cannot prepare environment for test.");
+    RUNNER_ASSERT_MSG(0 == smack_set_label_for_self(subject_label),
+                "Cannot prepare environment for test.");
+    RUNNER_ASSERT_MSG(0 == (ret = smack_accesses_new(&handle)), "Error in smack_accesses_new()");
+    RUNNER_ASSERT_MSG(0 == smack_accesses_add(handle,
+                               subject_label,
+                               object_label,
+                               access_rights), "Error in smack_accesses_add()" );
+    RUNNER_ASSERT_MSG(0 == (ret = smack_accesses_apply(handle)), "Error in smack_accesses_apply(); ret = " << ret);
+    smack_accesses_free(handle);
+    RUNNER_ASSERT_MSG(0 == (ret = smack_set_label_for_self(subject_label)), "Error in smack_set_label_for_self(); ret = " << ret);
+    RUNNER_ASSERT_MSG(SECURITY_SERVER_API_SUCCESS == security_server_request_cookie(cookie, cookie_size), "Error in security_server_request_cookie()");
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        /*odd(i) - ask for possessed privileges, even(i) ask for not possessed privileges */
+        if (i%2)
+            ret = security_server_check_privilege_by_cookie(
+                      cookie,
+                      object_label,
+                      access_rights);
+        else
+            ret = security_server_check_privilege_by_cookie(
+                      cookie,
+                      object_label,
+                      access_rights_ext);
+
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_check_privilege_by_cookie");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+
+RUNNER_TEST(m070_security_server_check_privilege_by_sockfd) {
+    const char *object_label = M70_OBJECT_LABEL;
+    const char *access_rights = "r";
+    const char *access_rights_ext = "rw";
+    const char *subject_label = M70_SUBJECT_LABEL;
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    smack_accesses *handle;
+    RUNNER_ASSERT(0 == smack_accesses_new(&handle));
+    RUNNER_ASSERT(0 == smack_accesses_add(handle,
+                           subject_label,
+                           object_label,
+                           access_rights));
+    RUNNER_ASSERT(0 == smack_accesses_apply(handle));
+    smack_accesses_free(handle);
+    int pid = fork();
+    RUNNER_ASSERT(-1 != pid);
+    if (0 == pid) {
+        // child
+        int sockfd = create_new_socket();
+        if (0 != smack_set_label_for_self(subject_label)) {
+            LogDebug("child, failed");
+            exit(EXIT_FAILURE);
+        }
+        if (listen(sockfd, 5) < 0) {
+            LogDebug("child, exit");
+            exit(EXIT_FAILURE);
+        }
+        struct sockaddr_un client_addr;
+        socklen_t client_len = sizeof(client_addr);
+        int csockfd;
+        while(0 <= (csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len))) {
+            close(csockfd);
+        }
+        exit(EXIT_SUCCESS);
+        //end child
+    }
+    else {
+        //parent
+        sleep(2);
+        int sockfd = connect_to_testserver();
+        LogDebug("Parent: sockfd: " << sockfd);
+        if (sockfd >= 0) {
+            for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+                start_stats_update(&stats);
+                /*odd(i) - ask for possessed privileges, even(i) ask for not possessed privileges */
+                if (i%2)
+                    ret = security_server_check_privilege_by_sockfd(
+                                sockfd,
+                                object_label,
+                                access_rights_ext);
+                else
+                    ret = security_server_check_privilege_by_sockfd(
+                                 sockfd,
+                                 object_label,
+                                 access_rights);
+                RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+                end_stats_update(&stats);
+            }
+            kill(pid, SIGKILL);
+            finish_stats(&stats, "check_privilege_by_sockfd");
+        }
+        int status;
+        waitpid(pid, &status, 0);
+        //end parent
+    }
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m080_security_server_get_cookie_pid) {
+    int ret;
+    size_t cookie_size;
+    cookie_size = security_server_get_cookie_size();
+    char cookie[cookie_size];
+    ret = security_server_request_cookie(cookie, cookie_size);
+    RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "security_server_request_cookie failed; ret = " << ret);
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_get_cookie_pid(cookie);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_request_cookie");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m090_security_server_is_pwd_valid) {
+    int ret;
+    unsigned int attempt, max_attempt, expire_sec;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_is_pwd_valid");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m100_security_server_set_pwd) {
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_set_pwd("this_is_current_pwd", "this_is_new_pwd", 20, 365);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_set_pwd");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m110_security_server_set_pwd_validity) {
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_set_pwd_validity(2);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_set_pwd_validity");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m120_security_server_set_pwd_max_challenge) {
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_set_pwd_max_challenge(3);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_set_pwd_max_challenge");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m130_security_server_reset_pwd) {
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_reset_pwd("apud", 1, 2);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_reset_pwd");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m140_security_server_chk_pwd) {
+    int ret;
+    unsigned int attempt, max_attempt, expire_sec;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_chk_pwd("is_this_password", &attempt, &max_attempt, &expire_sec);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_chk_pwd");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m150_security_server_set_pwd_history) {
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_set_pwd_history(100);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_set_pwd_history");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m160_security_server_app_give_access) {
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    const char* customer_label = M160_CUSTOMER_LABEL;
+    int customer_pid = getpid();
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_app_give_access(customer_label, customer_pid);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_app_give_access");
+}
+
+/*
+ * measurer: Fails only on connection error.
+ */
+RUNNER_TEST(m170_security_server_check_privilege_by_pid) {
+
+    int ret;
+    readwrite_stats stats;
+    initialize_stats(&stats);
+    int pid = getpid();
+    const char *object = M170_OBJECT_LABEL;
+    const char *access_rights = "rw";
+    for (int i = 1; i <= NUMBER_OF_CALLS; i++) {
+        start_stats_update(&stats);
+        ret = security_server_check_privilege_by_pid(pid, object, access_rights);
+        RUNNER_ASSERT_MSG(communication_succeeded(ret) == 0, "commmunication error; ret = " << ret);
+        end_stats_update(&stats);
+    }
+    finish_stats(&stats, "security_server_check_privilege_by_pid");
+}
+
+
+int main(int argc, char *argv[])
+{
+    securityClientEnableLogSystem();
+    DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+    return 0;
+}
index 2b554d4..bc09ce5 100644 (file)
@@ -59,6 +59,12 @@ case $1 in
     echo
     security-server-tests-server $2 $3
     ;;
+"ss-api-speed")
+    echo "========================================================================="
+    echo "SECURITY SERVER MEASURER SERVER"
+    echo
+    security-server-tests-api-speed  $2 $3
+    ;;
 "ss-password")
     echo "========================================================================="
     echo "SECURITY SERVER TEST PASSWORD"
@@ -77,7 +83,7 @@ case $1 in
     echo "    security_test.sh <module> <args_for_module>"
     echo
     echo "modules: smack, libprivilege-control, ss-clientsmack"
-    echo "         ss-label, ss-pid, ss-server, ss-password"
+    echo "         ss-label, ss-pid, ss-server, ss-api-speed, ss-password"
     ;;
 
 esac