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)
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
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)
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
%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
%{_libdir}/pkgconfig/*.pc
%{_libdir}/lib*.so
-
+%files test
+%attr(700,root,root) %{_bindir}/runtime-info-test
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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)));
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}