--- /dev/null
+/*
+ * 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;
+}