sensorctl: add options/features for usability
[platform/core/system/sensord.git] / src / sensorctl / test_bench.cpp
index 3b9cd51..db0b974 100644 (file)
  *
  */
 
-#include "log.h"
 #include "test_bench.h"
 
+#include <getopt.h>
+#include <regex>
+
+#include "log.h"
+
 /*
  * Implementation of test_option
  */
-bool test_option::full_log = false;
-std::string test_option::group = "";
-
-void test_option::show_full_log(bool show)
+bool test_option::verbose = false;
+bool test_option::shuffle = false;
+bool test_option::show_list = false;
+int test_option::repeat = 1;
+std::string test_option::filter = "";
+std::string test_option::output = "";
+int test_option::interval = -1;
+int test_option::latency = -1;
+int test_option::powersave = -1;
+
+bool test_option::set_options(int argc, char *argv[])
 {
-       full_log = show;
-}
-
-void test_option::set_group(const char *gname)
-{
-       group = gname;
-}
+       int c;
+
+       while (1) {
+               static struct option options[] = {
+                       {"list", no_argument, 0, 'l'},
+                       {"filter", required_argument, 0, 'f'},
+                       {"verbose", no_argument, 0, 'v'},
+                       {"shuffle", no_argument, 0, 's'},
+                       {"repeat", required_argument, 0, 'r'},
+                       {"output", required_argument, 0, 'o'},
+
+                       /* For manual test*/
+                       {"interval", required_argument, 0, 'i'},
+                       {"batch_latency", required_argument, 0, 'b'},
+                       {"powersave", required_argument, 0, 'p'},
+
+                       {"help", no_argument, 0, 'h'},
+                       {0, 0, 0, 0}
+               };
+
+               int option_index = 0;
+               c = getopt_long(argc, argv, "lfvsroibph:", options, &option_index);
+               if (c == -1)
+                       return true;
+
+               switch (c) {
+               case 0:
+                       break;
+               case 'l':
+                       _I("== Testcase List ==\n");
+                       test_bench::show_testcases();
+                       test_option::show_list = true;
+                       break;
+               case 'f':
+                       _I("Filter : %s\n", optarg);
+                       if (!optarg) break;
+                       test_option::filter = optarg;
+                       break;
+               case 'v':
+                       _I("Verbose is on\n");
+                       test_option::verbose = true;
+                       break;
+               case 's':
+                       _I("Shuffle is on(Default seed)\n");
+                       test_option::shuffle = true;
+                       break;
+               case 'r':
+                       _I("Repeat : %s\n", optarg);
+                       if (!optarg) break;
+                       test_option::repeat = atoi(optarg);
+                       break;
+               case 'o':
+                       /* [TODO] */
+                       _W("File output is not supported yet, use $sensorctl > out : %s\n", optarg);
+                       if (!optarg) break;
+                       test_option::output = optarg;
+                       break;
+               case 'i':
+                       _I("Interval : %s\n", optarg);
+                       if (!optarg) break;
+                       test_option::interval = atoi(optarg);
+                       break;
+               case 'b':
+                       _I("Batch latency : %s\n", optarg);
+                       if (!optarg) break;
+                       test_option::latency = atoi(optarg);
+                       break;
+               case 'p':
+                       _I("Power save : %s\n", optarg);
+                       if (!optarg) break;
+                       test_option::powersave = atoi(optarg);
+                       break;
+               case 'h':
+               case '?':
+               default:
+                       return false;
+               }
+       }
 
-void test_option::set_options(int argc, char *argv[])
-{
-       /* TODO: use getopt() */
-       if (argc > 3)
-               set_group(argv[3]);
-       if (argc > 4)
-               show_full_log(atoi(argv[4]));
+       return true;
 }
 
 /*
@@ -51,6 +127,7 @@ void test_option::set_options(int argc, char *argv[])
 test_case::test_case(const std::string &group, const std::string &name)
 : m_group(group)
 , m_name(name)
+, m_fullname(group + "." + m_name)
 , m_func(NULL)
 {
        test_bench::register_testcase(group, this);
@@ -58,25 +135,17 @@ test_case::test_case(const std::string &group, const std::string &name)
 
 void test_case::started(void)
 {
-       _I("[----------]\n");
        _I("[ RUN      ] ");
-       _N("%s.%s\n", m_group.c_str(), m_name.c_str());
-}
-
-void test_case::stopped(void)
-{
-       _I("[       OK ] ");
-       _N("%s.%s\n", m_group.c_str(), m_name.c_str());
-       _I("[----------]\n");
+       _N("%s\n", m_fullname.c_str());
 }
 
-void test_case::show(bool result)
+void test_case::stopped(bool result)
 {
        if (result)
-               _I("[  PASSED  ] ");
+               _I("[       OK ] ");
        else
                _E("[  FAILED  ] ");
-       _N("%s.%s\n", m_group.c_str(), m_name.c_str());
+       _N("%s\n", m_fullname.c_str());
 }
 
 void test_case::run_testcase(void)
@@ -85,8 +154,7 @@ void test_case::run_testcase(void)
 
        started();
        result = (this->*m_func)();
-       stopped();
-       show(result);
+       stopped(result);
 }
 
 void test_case::register_func(test_func func)
@@ -103,6 +171,11 @@ test_bench& test_bench::instance()
        return bench;
 }
 
+void test_bench::show_testcases(void)
+{
+       instance().show();
+}
+
 void test_bench::register_testcase(const std::string &group, test_case *testcase)
 {
        instance().add_testcase(group, testcase);
@@ -113,12 +186,15 @@ void test_bench::push_failure(const std::string &function, long line, const std:
        instance().add_failure(function, line, msg);
 }
 
-void test_bench::run_all_testcase(void)
+void test_bench::run_all_testcases(void)
 {
+       if (test_option::show_list)
+               return;
+
        instance().run();
 }
 
-void test_bench::stop_all_testcase(void)
+void test_bench::stop_all_testcases(void)
 {
        instance().stop();
 }
@@ -140,13 +216,36 @@ void test_bench::add_failure(const std::string &function, long line, const std::
 void test_bench::started(void)
 {
        _I("[==========] ");
-       _N("Running %d testcases\n", count(test_option::group));
+       _N("Running %d testcases\n", count());
 }
 
 void test_bench::stopped(void)
 {
        _I("[==========] ");
-       _N("%d testcases ran\n", count(test_option::group));
+       _N("%d testcases ran\n", count());
+}
+
+void test_bench::show(void)
+{
+       /*
+        * [group1]
+        *     [tc name1]
+        *     [tc name2]
+        * [group2]
+        *     [tc name1]
+        */
+
+       for (auto it = testcases.begin(); it != testcases.end();
+                       it = testcases.upper_bound(it->first)) {
+
+               auto range = testcases.equal_range(it->first);
+               _I("[%s]\n", it->first.c_str());
+
+               for (auto testcase = range.first; testcase != range.second; ++testcase)
+                       _N("    * %s\n", testcase->second->name().c_str());
+       }
+
+       _I("Testcase Count : %u\n", count());
 }
 
 void test_bench::show_failures(void)
@@ -154,7 +253,8 @@ void test_bench::show_failures(void)
        _N("================================\n");
 
        if (m_failure_count == 0) {
-               _N("there was no fail case\n");
+               _I("[  PASSED  ] ");
+               _N("%d tests\n", count() - m_failure_count);
                return;
        }
 
@@ -166,28 +266,44 @@ void test_bench::show_failures(void)
        }
 }
 
+bool test_bench::filter(const std::string &name)
+{
+       static std::regex filter(test_option::filter.c_str(), std::regex::optimize);
+       if (!std::regex_match(name, filter)) {
+               //_W("Not Matched : %s(%s)\n", name.c_str(), test_option::filter.c_str());
+               return false;
+       }
+
+       //_I("Matched : %s(%s)\n", name.c_str(), test_option::filter.c_str());
+       return true;
+}
+
 void test_bench::run(void)
 {
-       std::size_t found;
        m_failure_count = 0;
 
        started();
 
-       for (auto it = testcases.begin(); it != testcases.end(); ++it) {
-               if (m_stop)
-                       break;
+       /* For group */
+       for (auto it = testcases.begin(); it != testcases.end();
+                       it = testcases.upper_bound(it->first)) {
+               if (m_stop) break;
+               if (!filter(it->second->fullname())) continue;
 
-               found = it->first.find("skip");
+               auto range = testcases.equal_range(it->first);
 
-               if (test_option::group.empty() && found != std::string::npos)
-                       continue;
+               /* Time measurement for test group */
+               clock_t start = clock();
 
-               found = it->first.find(test_option::group);
+               _I("[----------] %d tests from %s\n", testcases.count(it->first), it->first.c_str());
+               for (auto testcase = range.first; testcase != range.second; ++testcase) {
+                       if (m_stop) break;
+                       testcase->second->run_testcase();
+               }
 
-               if (!test_option::group.empty() && found == std::string::npos)
-                       continue;
-
-               it->second->run_testcase();
+               _I("[----------] %d tests from %s (%.4f sec)\n",
+                       testcases.count(it->first), it->first.c_str(),
+                       (double)(clock() - start)/ CLOCKS_PER_SEC);
        }
 
        stopped();
@@ -199,23 +315,15 @@ void test_bench::stop(void)
        m_stop = true;
 }
 
-unsigned int test_bench::count(std::string &group)
-{
-       if (group.empty())
-               return testcases.size() - count_by_key("skip");
-
-       return count_by_key(group.c_str());
-}
-
-unsigned int test_bench::count_by_key(const char *key)
+unsigned int test_bench::count(void)
 {
        int count = 0;
 
        for (auto it = testcases.begin(); it != testcases.end(); ++it) {
-               std::size_t found = it->first.find(key);
+               if (!filter(it->second->fullname()))
+                       continue;
 
-               if (found != std::string::npos)
-                       count++;
+               count++;
        }
 
        return count;