Make unit test 52/138452/22
authorKichan Kwon <k_c.kwon@samsung.com>
Wed, 12 Jul 2017 07:40:16 +0000 (16:40 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Thu, 27 Jul 2017 06:46:43 +0000 (15:46 +0900)
- Existed TCs just check sanity
- This test read system data directly and compare with runtime-info result

Change-Id: I749bdad919f17c12ac6e5f7f395fd640016bb1d0
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
CMakeLists.txt
packaging/capi-system-runtime-info.spec
test/runtime_info_test.c [new file with mode: 0644]
test/runtime_info_test.h [new file with mode: 0644]
test/runtime_info_test_devices.c [new file with mode: 0644]
test/runtime_info_test_proc.c [new file with mode: 0644]
test/runtime_info_test_resourced.c [new file with mode: 0644]
test/runtime_info_test_vconf.c [new file with mode: 0644]

index 6cb90fc..653911a 100755 (executable)
@@ -10,7 +10,7 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 SET(INC_DIR include)
 INCLUDE_DIRECTORIES(${INC_DIR})
 
-SET(requires "dlog vconf capi-base-common capi-system-info")
+SET(requires "dlog vconf capi-base-common capi-system-info glib-2.0 gio-2.0")
 SET(pc_requires "capi-base-common")
 
 INCLUDE(FindPkgConfig)
@@ -67,10 +67,10 @@ IF(UNIX)
 
 ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
 ADD_CUSTOM_COMMAND(
-        DEPENDS clean 
+        DEPENDS clean
         COMMENT "distribution clean"
         COMMAND find
-        ARGS    . 
+        ARGS    .
         -not -name config.cmake -and \(
         -name tester.c -or
         -name Testing -or
@@ -94,3 +94,8 @@ ADD_CUSTOM_COMMAND(
 
 ENDIF(UNIX)
 
+SET(TEST_NAME "runtime-info-test")
+aux_source_directory(test TEST_SOURCES)
+ADD_EXECUTABLE(${TEST_NAME} ${TEST_SOURCES})
+TARGET_LINK_LIBRARIES(${TEST_NAME} ${${fw_name}_LDFLAGS} ${fw_name})
+INSTALL(TARGETS ${TEST_NAME} DESTINATION bin)
index 3abbda8..e219f78 100644 (file)
@@ -12,6 +12,7 @@ BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(vconf)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  pkgconfig(capi-system-info)
+BuildRequires:  pkgconfig(glib-2.0)
 Requires(post): /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
 
@@ -28,6 +29,13 @@ Requires:  pkgconfig(capi-base-common)
 %devel_desc
 
 
+%package test
+Summary:  A Runtime Information test binary
+Requires: %{name} = %{version}-%{release}
+
+%description test
+Binary for testing Runtime-info APIs
+
 
 %prep
 %setup -q
@@ -58,4 +66,5 @@ make %{?jobs:-j%jobs}
 %{_libdir}/pkgconfig/*.pc
 %{_libdir}/lib*.so
 
-
+%files test
+%attr(700,root,root) %{_bindir}/runtime-info-test
diff --git a/test/runtime_info_test.c b/test/runtime_info_test.c
new file mode 100644 (file)
index 0000000..1b66abf
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2011 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <signal.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <runtime_info.h>
+
+#include "runtime_info_test.h"
+
+static pid_t fork_child(void)
+{
+       int i, sum;
+       pid_t pid;
+
+       pid = fork();
+
+       switch (pid) {
+       case -1:
+               printf("Failed to fork child process (%d)\n", errno);
+               return -1;
+       case 0:
+               while (true) {
+                       /*
+                        * This calculation is meaningless.
+                        * Just for increasing utime to test getting CPU time.
+                        */
+                       sum = 0;
+                       for (i = 0; i < 1000000; i++)
+                               sum = (i % 2) ? sum + i : sum - i;
+                       sum /= 2;
+                       sleep(1);
+               }
+               return -1;
+       default:
+               return pid;
+       }
+}
+
+/* max_err : allowed max error (percent) */
+int check_value(int val1, int val2, int max_err)
+{
+       double div;
+       double max_err_percent = max_err / 100.0;
+
+       if (val2 == 0) {
+               if (val1 != 0) {
+                       printf("Incorrect value : runtime-info(%d), expected(%d)\n", val1, val2);
+                       return FAIL;
+               }
+
+               return SUCCESS;
+       }
+
+       div = (double)val1 / val2;
+       if (div > 1 + max_err_percent || div < 1 - max_err_percent) {
+               printf("Incorrect value : runtime-info(%d), expected(%d)\n", val1, val2);
+               return FAIL;
+       }
+
+       return SUCCESS;
+}
+
+int main(void)
+{
+       printf("=====================================================\n");
+       printf("              Runtime-info test program\n");
+       printf("=====================================================\n\n");
+
+       pid_t pid = fork_child();
+       if (pid < 0) {
+               printf("Failed to fork test process\n");
+               return 1;
+       }
+
+       runtime_info_test_get_value_bool();                  PRINT_LINE;
+       runtime_info_test_get_value_int();                   PRINT_LINE;
+       runtime_info_test_set_changed_cb();                  PRINT_LINE;
+       runtime_info_test_get_system_memory_info();          PRINT_LINE;
+       runtime_info_test_get_cpu_usage();                   PRINT_LINE;
+       runtime_info_test_get_physical_memory_size();        PRINT_LINE;
+       runtime_info_test_get_process_memory_info(pid);      PRINT_LINE;
+       runtime_info_test_get_process_cpu_usage(pid);        PRINT_LINE;
+       runtime_info_test_get_all_apps_memory_usage();       PRINT_LINE;
+       runtime_info_test_get_all_apps_cpu_rate();           PRINT_LINE;
+       runtime_info_test_get_processor_count();             PRINT_LINE;
+       runtime_info_test_get_processor_current_frequency(); PRINT_LINE;
+       runtime_info_test_get_processor_max_frequency();     PRINT_LINE;
+
+       kill(pid, SIGKILL);
+
+       return 0;
+}
diff --git a/test/runtime_info_test.h b/test/runtime_info_test.h
new file mode 100644 (file)
index 0000000..90a5742
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#ifndef __RUNTIME_INFO_TEST_H__
+#define __RUNTIME_INFO_TEST_H__
+
+#include <limits.h>
+
+#define BUF_SIZE 1024
+
+enum test_result {
+       SUCCESS,
+       FAIL,
+       ERROR,
+       NOT_SUPPORTED,
+};
+
+#define PRINT_RESULT(result) ((result) == SUCCESS) ? "\x1b[32mSUCCESS\x1b[0m" : (((result) == FAIL) ? "\x1b[31mFAIL\x1b[0m" : (((result) == ERROR) ? "\x1b[31mERROR\x1b[0m" : (((result) == NOT_SUPPORTED) ? "\x1b[34mNOT SUPPORTED\x1b[0m" : NULL)))
+#define PRINT_LINE     printf("\n-----------------------------------------------------\n\n");
+#define PRINT_NOTICE(msg) printf("\x1b[33mNOTICE : %s\x1b[0m\n", msg);
+
+/* Compare two values and judge */
+int check_value(int val1, int val2, int max_err);
+
+/* Vconf related TCs */
+void runtime_info_test_get_value_bool(void);
+void runtime_info_test_get_value_int(void);
+void runtime_info_test_set_changed_cb(void);
+
+/* /proc related TCs */
+void runtime_info_test_get_system_memory_info(void);
+void runtime_info_test_get_cpu_usage(void);
+void runtime_info_test_get_physical_memory_size(void);
+
+/* Resourced related TCs */
+void runtime_info_test_get_process_memory_info(pid_t pid);
+void runtime_info_test_get_process_cpu_usage(pid_t pid);
+void runtime_info_test_get_all_apps_memory_usage(void);
+void runtime_info_test_get_all_apps_cpu_rate(void);
+
+/* /sys/devices (CPU) related TCs */
+void runtime_info_test_get_processor_count(void);
+void runtime_info_test_get_processor_current_frequency(void);
+void runtime_info_test_get_processor_max_frequency(void);
+
+#endif /* __RUNTIME_INFO_TEST_H__ */
diff --git a/test/runtime_info_test_devices.c b/test/runtime_info_test_devices.c
new file mode 100644 (file)
index 0000000..c575e47
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2011 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <runtime_info.h>
+
+#include "runtime_info_test.h"
+
+#define CPU_CORE_FILE "/sys/devices/system/cpu/possible"
+#define CUR_FREQ_FILE "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"
+#define MAX_FREQ_FILE "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"
+#define CPUINFO_FILE "/proc/cpuinfo"
+
+enum freq_type {
+       CUR,
+       MAX,
+};
+
+void runtime_info_test_get_processor_count(void)
+{
+       int ret;
+       int num_core_r;
+       FILE *fp;
+       unsigned int from, to;
+       long long num_core;
+
+       printf("Runtime_info_get_processor_count test\n");
+
+       ret = runtime_info_get_processor_count(&num_core_r);
+       if (ret) {
+               printf("runtime_info_get_processor_count failed (%d)\n", ret);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       fp = fopen(CPU_CORE_FILE, "r");
+       if (!fp) {
+               printf("Failed to open %s\n", CPU_CORE_FILE);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       if (!fscanf(fp, "%u-%u", &from, &to)) {
+               printf("%s has invalid format\n", CPU_CORE_FILE);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               fclose(fp);
+               return;
+       }
+
+       if (to >= from)
+               num_core = (long long)to - from + 1;
+       else
+               num_core = 0;
+
+       fclose(fp);
+
+       printf("  The number of CPU core : %s\n",
+                       PRINT_RESULT(check_value(num_core_r, num_core, 0)));
+}
+
+static void runtime_info_test_helper_get_processor_frequency(
+               char *api_name, char *freq_file_name, int type)
+{
+       int ret;
+       int cpu_freq;
+       FILE *fp;
+       int freq;
+       char buf[BUF_SIZE];
+       char *start;
+
+       printf("%s test\n", api_name);
+
+       if (type == CUR)
+               ret = runtime_info_get_processor_current_frequency(0, &cpu_freq);
+       else
+               ret = runtime_info_get_processor_max_frequency(0, &cpu_freq);
+       if (ret) {
+               printf("%s failed (%d)\n\n", api_name, ret);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       if (access(freq_file_name, F_OK) == 0) {
+               fp = fopen(freq_file_name, "r");
+               if (!fp) {
+                       printf("Failed to open %s\n", freq_file_name);
+                       printf("  Result : %s\n", PRINT_RESULT(ERROR));
+                       return;
+               }
+
+               if (!fscanf(fp, "%d", &freq)) {
+                       printf("%s has invalid format\n", freq_file_name);
+                       printf("  Result : %s\n", PRINT_RESULT(ERROR));
+                       fclose(fp);
+                       return;
+               }
+
+               freq /= 1000;
+       } else if (access(CPUINFO_FILE, F_OK) == 0) {
+               fp = fopen(CPUINFO_FILE, "r");
+               if (!fp) {
+                       printf("Failed to open %s\n", CPUINFO_FILE);
+                       printf("  Result : %s\n", PRINT_RESULT(ERROR));
+                       return;
+               }
+
+               freq = -1;
+               while (fgets(buf, BUF_SIZE, fp)) {
+                       if (strncmp(buf, "cpu MHz", 7)) {
+                               start = strchr(buf, ':') + 2;
+                               sscanf(start, "%d", &freq);
+                               break;
+                       }
+               }
+
+               if (freq == -1) {
+                       printf("There is no information about cpu MHz in the %s\n", CPUINFO_FILE);
+                       printf("  Result : %s\n", PRINT_RESULT(ERROR));
+                       fclose(fp);
+                       return;
+               }
+       } else {
+               printf("There is no file providing CPU frequency\n");
+               printf("  Result : %s\n", PRINT_RESULT(NOT_SUPPORTED));
+               return;
+       }
+
+       fclose(fp);
+
+       printf("  %s CPU frequency of core 0 : %s\n",
+                       (type == CUR) ? "Current" : "Max",
+                       PRINT_RESULT(check_value(cpu_freq, freq, 0)));
+}
+
+void runtime_info_test_get_processor_current_frequency(void)
+{
+       runtime_info_test_helper_get_processor_frequency(
+                       "runtime_info_get_processor_current_frequency", CUR_FREQ_FILE, CUR);
+}
+
+void runtime_info_test_get_processor_max_frequency(void)
+{
+       runtime_info_test_helper_get_processor_frequency(
+                       "runtime_info_get_processor_max_frequency", MAX_FREQ_FILE, MAX);
+}
diff --git a/test/runtime_info_test_proc.c b/test/runtime_info_test_proc.c
new file mode 100644 (file)
index 0000000..f7e24cb
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2011 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <runtime_info.h>
+
+#include "runtime_info_test.h"
+
+#define KiBtoPage(kib)         (int)((kib) / 4.0)
+
+void runtime_info_test_get_system_memory_info(void)
+{
+       int ret;
+       runtime_memory_info_s info;
+       char buf[BUF_SIZE];
+       FILE *fp;
+       unsigned long mem_total, mem_used, mem_free, cached, swap;
+       unsigned long mem_available, swap_total, swap_free;
+
+       printf("Runtime_info_get_system_memory_info test\n");
+
+       ret = runtime_info_get_system_memory_info(&info);
+       if (ret) {
+               printf("runtime_info_get_system_memory_info failed (%d)\n", ret);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       fp = fopen("/proc/meminfo", "r");
+       if (!fp) {
+               printf("Failed to read /proc/meminfo\n");
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       mem_total = mem_free = cached = mem_available = swap_total = swap_free = 0;
+       while (fgets(buf, BUF_SIZE, fp)) {
+               if (sscanf(buf, "MemTotal: %lu", &mem_total) == 1)
+                       continue;
+               if (sscanf(buf, "MemFree: %lu", &mem_free) == 1)
+                       continue;
+               if (sscanf(buf, "Cached: %lu", &cached) == 1)
+                       continue;
+               if (sscanf(buf, "MemAvailable: %lu", &mem_available) == 1)
+                       continue;
+               if (sscanf(buf, "SwapTotal: %lu", &swap_total) == 1)
+                       continue;
+               if (sscanf(buf, "SwapFree: %lu", &swap_free) == 1)
+                       continue;
+       }
+
+       fclose(fp);
+
+       if (mem_available > 0) {
+               if (mem_total > mem_available)
+                       mem_used = mem_total - mem_available;
+               else
+                       mem_used = 0;
+       } else {
+               if (mem_total > mem_free && mem_total - mem_free > cached)
+                       mem_used = mem_total - mem_free - cached;
+               else
+                       mem_used = 0;
+       }
+
+       swap = (swap_total > swap_free) ? swap_total - swap_free : 0;
+
+       printf("  Total memory size : %s\n",
+               PRINT_RESULT(check_value(info.total, mem_total, 0)));
+       printf("  Used memory size  : %s\n",
+               PRINT_RESULT(check_value(info.used, mem_used, 0)));
+       printf("  Free memory size  : %s\n",
+               PRINT_RESULT(check_value(info.free, mem_free, 0)));
+       printf("  Cache memory size : %s\n",
+               PRINT_RESULT(check_value(info.cache, cached, 0)));
+       printf("  Swap memory size  : %s\n",
+               PRINT_RESULT(check_value(info.swap, swap, 0)));
+}
+
+void runtime_info_test_get_cpu_usage(void)
+{
+       int ret;
+       runtime_cpu_usage_s usage;
+       char buf[BUF_SIZE];
+       FILE *fp;
+       int total = 0;
+       unsigned long long user, nice, systime, idle, iowait, irq, softirq;
+
+       printf("Runtime_info_get_cpu_usage test\n");
+
+       ret = runtime_info_get_cpu_usage(&usage);
+       if (ret) {
+               printf("runtime_info_get_cpu_usage failed (%d)\n", ret);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       fp = fopen("/proc/stat", "r");
+       if (!fp) {
+               printf("Failed to read /proc/stat\n");
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       while (fgets(buf, BUF_SIZE, fp)) {
+               if (sscanf(buf, "cpu %llu %llu %llu %llu %llu %llu %llu",
+                               &user, &nice, &systime, &idle,
+                               &iowait, &irq, &softirq) == 7)
+                       break;
+       }
+
+       fclose(fp);
+
+       total = user + nice + systime + idle + iowait + irq + softirq;
+
+       user = (double)user * 100 / total;
+       nice = (double)nice * 100 / total;
+       systime = (double)systime * 100 / total;
+       iowait = (double)iowait * 100 / total;
+
+       printf("  User time       : %s\n",
+                       PRINT_RESULT(check_value(usage.user, user, 1)));
+       printf("  Niced user time : %s\n",
+                       PRINT_RESULT(check_value(usage.nice, nice, 1)));
+       printf("  System time     : %s\n",
+                       PRINT_RESULT(check_value(usage.system, systime, 1)));
+       printf("  IO wait time    : %s\n",
+                       PRINT_RESULT(check_value(usage.iowait, iowait, 1)));
+}
+
+void runtime_info_test_get_physical_memory_size(void)
+{
+       int ret;
+       int size;
+       char buf[BUF_SIZE];
+       FILE *fp;
+       unsigned long total, value;
+
+       printf("Runtime_info_get_physical_memory_size test\n");
+
+       ret = runtime_info_get_physical_memory_size(&size);
+       if (ret) {
+               printf("runtime_info_get_physical_memory_size failed (%d)\n\n", ret);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       fp = fopen("/proc/zoneinfo", "r");
+       if (!fp) {
+               printf("Failed to read /proc/zoneinfo\n");
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       total = 0;
+       while (fgets(buf, BUF_SIZE, fp))
+               if (sscanf(buf, " spanned %lu", &value) == 1)
+                       total += value;
+
+       fclose(fp);
+
+       printf("  Physical memory size : %s\n",
+                       PRINT_RESULT(check_value(KiBtoPage(size), total, 0)));
+}
diff --git a/test/runtime_info_test_resourced.c b/test/runtime_info_test_resourced.c
new file mode 100644 (file)
index 0000000..18b585c
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2011 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <runtime_info.h>
+
+#include "runtime_info_test.h"
+
+#define BytetoKiB(byte)        (byte) >> 10
+#define KBtoPage(kb)   ((kb) / 4)
+#define START_TIME_FILE        "/run/resourced/appinfo/%s/starttime"
+
+void runtime_info_test_get_process_memory_info(pid_t pid)
+{
+       int ret;
+       process_memory_info_s *info;
+       char buf[BUF_SIZE];
+       FILE *fp;
+       unsigned long vsz;
+       int code, data, pss;
+
+       printf("Runtime_info_get_process_memory_info test\n");
+
+       ret = runtime_info_get_process_memory_info(&pid, 1, &info);
+       if (ret) {
+               printf("runtime_info_get_process_memory_info failed (%d)\n\n", ret);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       /* Read /proc/PID/stat */
+       snprintf(buf, BUF_SIZE, "/proc/%u/stat", pid);
+       fp = fopen(buf, "r");
+       if (!fp) {
+               printf("Failed to open %s\n", buf);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       while (fgets(buf, BUF_SIZE, fp)) {
+               if (sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %lu",
+                                       &vsz) != 1) {
+                       printf("/proc/%u/stat has invalid format\n", pid);
+                       printf("  Result : %s\n", PRINT_RESULT(ERROR));
+                       fclose(fp);
+                       return;
+               }
+       }
+
+       fclose(fp);
+
+       snprintf(buf, BUF_SIZE, "memps -a | grep runtime-info-test | grep %u", pid);
+       fp = popen(buf, "r");
+       if (!fp) {
+               printf("popen failed\n");
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       if (!fscanf(fp, "%*d %d %d %*d %d", &code, &data, &pss)) {
+               printf("memps has invalid format\n");
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               fclose(fp);
+               return;
+       }
+
+       fclose(fp);
+
+       printf("  Virtual memory size   : %s\n",
+                       PRINT_RESULT(check_value(info[0].vsz, BytetoKiB(vsz), 0)));
+       printf("  Proportional set size : %s\n",
+                       PRINT_RESULT(check_value(info[0].pss, pss, 0)));
+       printf("  Clean memory size     : %s\n",
+                       PRINT_RESULT(check_value(info[0].shared_clean + info[0].private_clean,
+                                                                       code, 0)));
+       printf("  Dirty memory size     : %s\n",
+                       PRINT_RESULT(check_value(info[0].shared_dirty + info[0].private_dirty,
+                                                                       data, 0)));
+}
+
+void runtime_info_test_get_process_cpu_usage(pid_t pid)
+{
+       int ret;
+       process_cpu_usage_s *usage;
+       char buf[BUF_SIZE];
+       FILE *fp;
+       unsigned long utime, stime;
+
+       printf("Runtime_info_get_process_cpu_usage test\n");
+
+       ret = runtime_info_get_process_cpu_usage(&pid, 1, &usage);
+       if (ret) {
+               printf("runtime_info_get_process_cpu_usage failed (%d)\n\n", ret);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       snprintf(buf, BUF_SIZE, "/proc/%u/stat", pid);
+       fp = fopen(buf, "r");
+       if (!fp) {
+               printf("Failed to open %s\n", buf);
+               printf("  Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       while (fgets(buf, BUF_SIZE, fp)) {
+               if (sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %lu %lu",
+                                       &utime, &stime) != 2) {
+                       printf("/proc/%u/stat has invalid format\n", pid);
+                       printf("  Result : %s\n", PRINT_RESULT(ERROR));
+                       fclose(fp);
+                       return;
+               }
+       }
+
+       fclose(fp);
+
+       printf("  User time   : %s\n",
+                       PRINT_RESULT(check_value(usage[0].utime, utime, 0)));
+       printf("  System time : %s\n",
+                       PRINT_RESULT(check_value(usage[0].stime, stime, 0)));
+}
+
+static int runtime_info_test_helper_find_pid(app_usage_h *h, pid_t *pid)
+{
+       int ret;
+       int count;
+       char *appid = NULL;
+       char buf[BUF_SIZE];
+       FILE *fp = NULL;
+       app_usage_h handle = *h;
+       int result = ERROR;
+
+       ret = runtime_info_app_usage_get_count(handle, &count);
+       if (ret) {
+               printf("Failed to call runtime_info_app_usage_get_count (%d)\n\n", ret);
+               goto error;
+       } else if (count <= 0) {
+               printf("There is no launched app");
+               goto error;
+       }
+
+       ret = runtime_info_app_usage_get_appid(handle, 0, &appid);
+       if (ret) {
+               printf("Failed to call runtime_info_app_usage_get_appid (%d)\n\n", ret);
+               goto error;
+       }
+
+       /* Find the pid of test app */
+       snprintf(buf, BUF_SIZE, "/run/resourced/appinfo/%s/main_pid", appid);
+       fp = fopen(buf, "r");
+       if (!fp) {
+               printf("Failed to open %s\n", buf);
+               goto error;
+       }
+
+       if (!fscanf(fp, "%u", pid)) {
+               printf("There is no pid of %s in resourced appinfo\n", appid);
+               goto error;
+       }
+
+       result = SUCCESS;
+
+error:
+       if (fp)
+               fclose(fp);
+
+       if (appid)
+               free(appid);
+
+       return result;
+}
+
+void runtime_info_test_get_all_apps_memory_usage(void)
+{
+       int ret;
+       app_usage_h handle;
+       unsigned int usage_r;
+       long long usage;
+       char buf[BUF_SIZE];
+       FILE *fp = NULL;
+       pid_t pid_app;
+       unsigned long resident, shared;
+       int vmswap;
+
+       printf("Runtime_info_get_all_apps_memory_usage test\n");
+       PRINT_NOTICE("Resourced-headless doesn't support this API.\n");
+
+       /* Call runtime-info APIs */
+       ret = runtime_info_get_all_apps_memory_usage(&handle);
+       if (ret) {
+               printf("Failed to call runtime_info_get_all_apps_memory_usage (%d)\n\n", ret);
+               printf("Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       ret = runtime_info_app_usage_get_usage(handle, 0, &usage_r);
+       if (ret) {
+               printf("Failed to call runtime_info_app_usage_get_usage (%d)\n\n", ret);
+               goto error;
+       }
+
+       if (runtime_info_test_helper_find_pid(&handle, &pid_app) == ERROR)
+               goto error;
+
+       /* Read /proc/PID/statm */
+       snprintf(buf, BUF_SIZE, "/proc/%u/statm", pid_app);
+       fp = fopen(buf, "r");
+       if (!fp) {
+               printf("Failed to open %s\n", buf);
+               goto error;
+       }
+
+       resident = shared = 0;
+       while (fgets(buf, BUF_SIZE, fp)) {
+               if (sscanf(buf, "%*s %lu %lu", &resident, &shared) != 2) {
+                       printf("/proc/%u/statm has invalid format\n", pid_app);
+                       fclose(fp);
+                       goto error;
+               }
+       }
+
+       fclose(fp);
+
+       /* Read /proc/PID/status */
+       snprintf(buf, BUF_SIZE, "/proc/%u/status", pid_app);
+       fp = fopen(buf, "r");
+       if (!fp) {
+               printf("Failed to open %s\n", buf);
+               goto error;
+       }
+
+       vmswap = 0;
+       while (fgets(buf, BUF_SIZE, fp)) {
+               if (sscanf(buf, "VmSwap: %d kB", &vmswap) == 1)
+                       break;
+       }
+
+       if (resident < shared)
+               usage = 0;
+       else
+               usage = resident - shared + KBtoPage(vmswap);
+
+       fclose(fp);
+       ret = runtime_info_app_usage_destroy(handle);
+
+       printf("  App memory usage : %s\n",
+                       PRINT_RESULT(check_value(KBtoPage(usage_r), usage, 0)));
+       return;
+
+error:
+       printf("  Result : %s\n", PRINT_RESULT(ERROR));
+
+       ret = runtime_info_app_usage_destroy(handle);
+}
+
+void runtime_info_test_get_all_apps_cpu_rate(void)
+{
+       int ret;
+       app_usage_h handle;
+       unsigned int rate_r, rate;
+       char *appid = NULL;
+       char buf[BUF_SIZE];
+       FILE *fp = NULL;
+       pid_t pid_app;
+       unsigned int starttime, uptime;
+       unsigned long utime, stime, cputime;
+
+       printf("Runtime_info_get_all_apps_cpu_rate test\n");
+       PRINT_NOTICE("Resourced-headless doesn't support this API.\n");
+
+       /* Call runtime-info APIs */
+       ret = runtime_info_get_all_apps_cpu_rate(&handle);
+       if (ret) {
+               printf("Failed to call runtime_info_get_all_apps_memory_usage (%d)\n\n", ret);
+               printf("Result : %s\n", PRINT_RESULT(ERROR));
+               return;
+       }
+
+       ret = runtime_info_app_usage_get_usage(handle, 0, &rate_r);
+       if (ret) {
+               printf("Failed to call runtime_info_app_usage_get_usage (%d)\n\n", ret);
+               goto error;
+       }
+
+       ret = runtime_info_app_usage_get_appid(handle, 0, &appid);
+       if (ret) {
+               printf("Failed to call runtime_info_app_usage_get_appid (%d)\n\n", ret);
+               goto error;
+       }
+
+       if (runtime_info_test_helper_find_pid(&handle, &pid_app) == ERROR)
+               goto error;
+
+       /* Read starttime file */
+       snprintf(buf, BUF_SIZE, START_TIME_FILE, appid);
+       fp = fopen(buf, "r");
+       if (!fp) {
+               printf("Failed to open %s\n", buf);
+               goto error;
+       }
+
+       if (!fscanf(fp, "%u", &starttime)) {
+               printf("%s has invalid format\n", buf);
+               goto error;
+       }
+
+       fclose(fp);
+
+       /* Read /proc/uptime */
+       fp = fopen("/proc/uptime", "r");
+       if (!fp) {
+               printf("Failed to open %s\n", buf);
+               goto error;
+       }
+
+       if (!fscanf(fp, "%u", &uptime)) {
+               printf("%s has invalid format\n", buf);
+               goto error;
+       }
+
+       fclose(fp);
+
+       /* Read /proc/PID/stat  */
+       snprintf(buf, BUF_SIZE, "/proc/%u/stat", pid_app);
+       fp = fopen(buf, "r");
+       if (!fp) {
+               printf("Failed to open %s\n", buf);
+               goto error;
+       }
+
+       while (fgets(buf, BUF_SIZE, fp)) {
+               if (sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %lu %lu",
+                                       &utime, &stime) != 2) {
+                       printf("/proc/%u/stat has invalid format\n", pid_app);
+                       goto error;
+               }
+       }
+
+       if (uptime <= starttime)
+               rate = 0;
+       else {
+               cputime = (unsigned long)(((unsigned long long)utime + stime) % UINT_MAX);
+               rate = cputime / (uptime - starttime);
+       }
+
+       fclose(fp);
+       free(appid);
+       ret = runtime_info_app_usage_destroy(handle);
+
+       printf("  App CPU rate : %s\n",
+                       PRINT_RESULT(check_value(rate_r, rate, 5)));
+       return;
+
+error:
+       printf("  Result : %s\n", PRINT_RESULT(ERROR));
+
+       if (appid)
+               free(appid);
+
+       if (fp)
+               fclose(fp);
+
+       ret = runtime_info_app_usage_destroy(handle);
+}
diff --git a/test/runtime_info_test_vconf.c b/test/runtime_info_test_vconf.c
new file mode 100644 (file)
index 0000000..e5ba13a
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2011 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <vconf.h>
+
+#include <runtime_info.h>
+
+#include "runtime_info_test.h"
+
+#define LIST_SIZE                      5
+#define VCONF_KEY_OTHERS       -1234
+#define KEY_GROUP_END          -5678
+
+#define MAX_TRIAL                      5
+#define TIME_TO_WAIT_CB                (2 * 1000000) /* 2 seconds */
+
+static GCond cond;
+static GMutex mutex;
+
+/* key_list_bool[CB_TEST_IDX] */
+#define CB_TEST_IDX    9
+
+/**
+ * Lists are differently used depending on the tested type
+ *
+ *       |           bool             |               int
+ *----------------------------------------------------------------------
+ * list1 | Values considered as True  | Available vconf value list
+ * list2 | Values considered as False | Corresponded runtime-info value
+ */
+struct key_list {
+       char *name;
+       int key_r;
+       char *key_v;
+       int list1[LIST_SIZE];
+       int list2[LIST_SIZE];
+};
+
+static struct key_list key_list_bool[] = {
+       {
+               "Bluetooth",
+               RUNTIME_INFO_KEY_BLUETOOTH_ENABLED,
+               VCONFKEY_BT_STATUS,
+               { VCONFKEY_BT_STATUS_ON, VCONFKEY_BT_STATUS_BT_VISIBLE, VCONFKEY_BT_STATUS_TRANSFER, KEY_GROUP_END },
+               { VCONFKEY_BT_STATUS_OFF, KEY_GROUP_END },
+       },
+       {
+               "Packet data",
+               RUNTIME_INFO_KEY_PACKET_DATA_ENABLED,
+               VCONFKEY_3G_ENABLE,
+               { KEY_GROUP_END },
+               { KEY_GROUP_END },
+       },
+       {
+               "Data roaming",
+               RUNTIME_INFO_KEY_DATA_ROAMING_ENABLED,
+               VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL,
+               { KEY_GROUP_END },
+               { KEY_GROUP_END },
+       },
+       {
+               "Vibration",
+               RUNTIME_INFO_KEY_VIBRATION_ENABLED,
+               VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL,
+               { KEY_GROUP_END },
+               { KEY_GROUP_END },
+       },
+       {
+               "Audio jack connected",
+               RUNTIME_INFO_KEY_AUDIO_JACK_CONNECTED,
+               VCONFKEY_SYSMAN_EARJACK,
+               { VCONFKEY_SYSMAN_EARJACK_3WIRE, VCONFKEY_SYSMAN_EARJACK_4WIRE, KEY_GROUP_END },
+               { VCONF_KEY_OTHERS, KEY_GROUP_END },
+       },
+       {
+               "Battery charging",
+               RUNTIME_INFO_KEY_BATTERY_IS_CHARGING,
+               VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
+               { VCONF_KEY_OTHERS, KEY_GROUP_END },
+               { 0, KEY_GROUP_END },
+       },
+       {
+               "TV out",
+               RUNTIME_INFO_KEY_TV_OUT_CONNECTED,
+               VCONFKEY_SYSMAN_EARJACK,
+               { VCONFKEY_SYSMAN_EARJACK_TVOUT, KEY_GROUP_END },
+               { VCONF_KEY_OTHERS, KEY_GROUP_END },
+       },
+       {
+               "USB connection",
+               RUNTIME_INFO_KEY_USB_CONNECTED,
+               VCONFKEY_SYSMAN_USB_STATUS,
+               { VCONFKEY_SYSMAN_USB_AVAILABLE, KEY_GROUP_END },
+               { VCONFKEY_SYSMAN_USB_DISCONNECTED, VCONFKEY_SYSMAN_USB_CONNECTED, KEY_GROUP_END },
+       },
+       {
+               "Charger connection",
+               RUNTIME_INFO_KEY_CHARGER_CONNECTED,
+               VCONFKEY_SYSMAN_CHARGER_STATUS,
+               { VCONFKEY_SYSMAN_CHARGER_CONNECTED, KEY_GROUP_END },
+               { VCONFKEY_SYSMAN_CHARGER_DISCONNECTED, KEY_GROUP_END },
+       },
+       {
+               "Auto rotation",
+               RUNTIME_INFO_KEY_AUTO_ROTATION_ENABLED,
+               VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
+               { KEY_GROUP_END },
+               { KEY_GROUP_END },
+       },
+};
+
+static struct key_list key_list_int[] = {
+       {
+               "GPS status",
+               RUNTIME_INFO_KEY_GPS_STATUS,
+               VCONFKEY_LOCATION_GPS_STATE,
+               { VCONFKEY_LOCATION_GPS_OFF, VCONFKEY_LOCATION_GPS_SEARCHING, VCONFKEY_LOCATION_GPS_CONNECTED, KEY_GROUP_END },
+               { RUNTIME_INFO_GPS_STATUS_DISABLED, RUNTIME_INFO_GPS_STATUS_SEARCHING, RUNTIME_INFO_GPS_STATUS_CONNECTED, KEY_GROUP_END },
+       },
+       {
+               "Audiojack status",
+               RUNTIME_INFO_KEY_AUDIO_JACK_STATUS,
+               VCONFKEY_SYSMAN_EARJACK,
+               { VCONFKEY_SYSMAN_EARJACK_3WIRE, VCONFKEY_SYSMAN_EARJACK_4WIRE, VCONF_KEY_OTHERS, KEY_GROUP_END },
+               { RUNTIME_INFO_AUDIO_JACK_STATUS_CONNECTED_3WIRE, RUNTIME_INFO_AUDIO_JACK_STATUS_CONNECTED_4WIRE, RUNTIME_INFO_AUDIO_JACK_STATUS_UNCONNECTED, KEY_GROUP_END },
+       },
+};
+
+void runtime_info_test_get_value_bool(void)
+{
+       int i, j;
+       int size = sizeof(key_list_bool) / sizeof(struct key_list);
+       int ret;
+       bool value_r;
+       int value_v;
+       int result;
+
+       printf("Runtime_info_get_value_bool test\n");
+
+       for (i = 0; i < size; i++) {
+               result = SUCCESS;
+
+               ret = runtime_info_get_value_bool(key_list_bool[i].key_r, &value_r);
+               switch (ret) {
+               case RUNTIME_INFO_ERROR_NONE:
+                       if (key_list_bool[i].list1[0] == KEY_GROUP_END) {
+                               ret = vconf_get_bool(key_list_bool[i].key_v, &value_v);
+                               if (ret < 0) {
+                                       printf("vconf_get_bool error (%d)\n", ret);
+                                       result = ERROR;
+                                       break;
+                               }
+                       } else {
+                               ret = vconf_get_int(key_list_bool[i].key_v, &value_v);
+                               if (ret < 0) {
+                                       printf("vconf_get_int error (%d)\n", ret);
+                                       result = ERROR;
+                                       break;
+                               }
+
+                               if (key_list_bool[i].list2[0] == VCONF_KEY_OTHERS) {
+                                       for (j = 0; j < LIST_SIZE; j++) {
+                                               if (key_list_bool[i].list1[j] == KEY_GROUP_END) {
+                                                       value_v = false;
+                                                       break;
+                                               }
+                                               if (key_list_bool[i].list1[j] == value_v) {
+                                                       value_v = true;
+                                                       break;
+                                               }
+                                       }
+                               } else {
+                                       for (j = 0; j < LIST_SIZE; j++) {
+                                               if (key_list_bool[i].list2[j] == KEY_GROUP_END) {
+                                                       value_v = true;
+                                                       break;
+                                               }
+                                               if (key_list_bool[i].list2[j] == value_v) {
+                                                       value_v = false;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       if (value_r != value_v)
+                               result = FAIL;
+                       break;
+               case RUNTIME_INFO_ERROR_NOT_SUPPORTED:
+                       result = NOT_SUPPORTED;
+                       break;
+               default:
+                       printf("runtime_info_get_value_bool error (%d)\n", ret);
+                       result = ERROR;
+                       break;
+               }
+
+               printf("  %s : %s\n", key_list_bool[i].name, PRINT_RESULT(result));
+       }
+}
+
+void runtime_info_test_get_value_int(void)
+{
+       int i, j;
+       int size = sizeof(key_list_int) / sizeof(struct key_list);
+       int ret;
+       int value_r, value_v;
+       int result;
+
+       printf("Runtime_info_get_value_int test\n");
+
+       for (i = 0; i < size; i++) {
+               result = SUCCESS;
+
+               ret = runtime_info_get_value_int(key_list_int[i].key_r, &value_r);
+               switch (ret) {
+               case RUNTIME_INFO_ERROR_NONE:
+                       ret = vconf_get_int(key_list_int[i].key_v, &value_v);
+                       if (ret < 0) {
+                               printf("vconf_get_int error (%d)\n", ret);
+                               result = ERROR;
+                               break;
+                       }
+
+                       for (j = 0; j < LIST_SIZE; j++) {
+                               if (key_list_int[i].list1[j] == VCONF_KEY_OTHERS ||
+                                       key_list_int[i].list1[j] == value_v)
+                                       value_v = key_list_int[i].list2[j];
+                       }
+
+                       if (value_r != value_v)
+                               result = FAIL;
+                       break;
+               case RUNTIME_INFO_ERROR_NOT_SUPPORTED:
+                       result = NOT_SUPPORTED;
+                       break;
+               default:
+                       printf("runtime_info_get_value_int error (%d)\n", ret);
+                       result = ERROR;
+                       break;
+               }
+
+               printf("  %s : %s\n", key_list_int[i].name, PRINT_RESULT(result));
+       }
+}
+
+static void runtime_info_test_changed_cb(runtime_info_key_e key, void *user_data)
+{
+       g_cond_signal(&cond);
+}
+
+static gpointer runtime_info_test_cb_thread(gpointer data)
+{
+       int ret;
+       GMainLoop *mainloop = g_main_loop_new(NULL, FALSE);
+       if (!mainloop)
+               return NULL;
+
+       ret = runtime_info_set_changed_cb(key_list_bool[CB_TEST_IDX].key_r,
+                       runtime_info_test_changed_cb, key_list_bool[CB_TEST_IDX].name);
+       if (ret) {
+               printf("Failed to register callback. (%d)\n", ret);
+               return NULL;
+       }
+
+       g_main_loop_run(mainloop);
+
+       return NULL;
+}
+
+void runtime_info_test_set_changed_cb(void)
+{
+       int ret;
+       bool value = false, value_orig = false;
+       char buf_t[BUF_SIZE];
+       char buf_f[BUF_SIZE];
+       int result = ERROR;
+       int trial = MAX_TRIAL;
+
+       printf("Runtime_info_set_changed_cb test\n");
+
+       GThread *thread = g_thread_try_new(NULL, runtime_info_test_cb_thread, NULL, NULL);
+       if (!thread) {
+               printf("Failed to make callback thread\n");
+               goto judge;
+       }
+
+       ret = runtime_info_get_value_bool(key_list_bool[CB_TEST_IDX].key_r, &value_orig);
+       if (ret) {
+               printf("runtime_info_get_value_bool failed (%d)\n", ret);
+               goto judge;
+       }
+       value = value_orig;
+
+       g_cond_init(&cond);
+       g_mutex_init(&mutex);
+       g_mutex_lock(&mutex);
+
+       snprintf(buf_t, BUF_SIZE, "vconftool set -t bool %s -f 1",
+                       key_list_bool[CB_TEST_IDX].key_v);
+       snprintf(buf_f, BUF_SIZE, "vconftool set -t bool %s -f 0",
+                       key_list_bool[CB_TEST_IDX].key_v);
+
+       for (; trial > 0; trial--) {
+               if (value)
+                       ret = system(buf_f);
+               else
+                       ret = system(buf_t);
+               if (ret == -1) {
+                       printf("vconftool failed.\n");
+                       goto judge;
+               }
+               value = value ? false : true;
+
+               if (g_cond_wait_until(&cond, &mutex, g_get_monotonic_time() + TIME_TO_WAIT_CB)) {
+                       result = SUCCESS;
+                       ret = runtime_info_unset_changed_cb(key_list_bool[CB_TEST_IDX].key_r);
+                       break;
+               }
+       }
+
+       if (trial == 0) {
+               printf("Callback isn't be called.\n");
+               result = FAIL;
+       }
+
+judge:
+       printf("  Registering and calling callback : %s\n", PRINT_RESULT(result));
+
+       if (value != value_orig) {
+               if (value_orig)
+                       ret = system(buf_t);
+               else
+                       ret = system(buf_f);
+       }
+
+       g_mutex_unlock(&mutex);
+}