loadtests.cc 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #include <string>
  2. #include <iostream>
  3. #include <sstream>
  4. #include <cassert>
  5. #include <cstdlib>
  6. #include <cstring>
  7. #include "service.h"
  8. #include "proc-service.h"
  9. //#include "load-service.h"
  10. std::string test_service_dir;
  11. void init_test_service_dir()
  12. {
  13. test_service_dir = "./test-services";
  14. }
  15. void test_basic()
  16. {
  17. dirload_service_set sset(test_service_dir.c_str());
  18. auto t1 = sset.load_service("t1");
  19. assert(t1->get_name() == "t1");
  20. }
  21. void test_env_subst()
  22. {
  23. dirload_service_set sset(test_service_dir.c_str());
  24. setenv("ONEVAR", "a", true);
  25. setenv("TWOVAR", "hellohello", true);
  26. // leave THREEVAR undefined
  27. auto t2 = static_cast<base_process_service *>(sset.load_service("t2"));
  28. auto exec_parts = t2->get_exec_arg_parts();
  29. assert(strcmp("echo", exec_parts[0]) == 0);
  30. assert(strcmp("a", exec_parts[1]) == 0);
  31. assert(strcmp("hellohello", exec_parts[2]) == 0);
  32. assert(strcmp("", exec_parts[3]) == 0);
  33. }
  34. void test_env_subst2()
  35. {
  36. auto resolve_env_var = [](const std::string &name){
  37. if (name == "ONE_VAR") return "a";
  38. if (name == "TWOVAR") return "hellohello";
  39. return "";
  40. };
  41. std::string line = "test x$ONE_VAR~ y$TWOVAR$$ONE_VAR";
  42. std::list<std::pair<unsigned,unsigned>> offsets;
  43. std::string::iterator li = line.begin();
  44. std::string::iterator le = line.end();
  45. dinit_load::read_setting_value(1 /* line_num */, li, le, &offsets);
  46. dinit_load::cmdline_var_subst("command", line, offsets, resolve_env_var);
  47. assert(line == "test xa~ yhellohello$ONE_VAR");
  48. assert(offsets.size() == 3);
  49. assert((*std::next(offsets.begin(), 0) == std::pair<unsigned,unsigned>{0, 4}));
  50. assert((*std::next(offsets.begin(), 1) == std::pair<unsigned,unsigned>{5, 8}));
  51. assert((*std::next(offsets.begin(), 2) == std::pair<unsigned,unsigned>{9, 28}));
  52. }
  53. void test_nonexistent()
  54. {
  55. bool got_service_not_found = false;
  56. dirload_service_set sset(test_service_dir.c_str());
  57. try {
  58. sset.load_service("does-not-exist");
  59. }
  60. catch (service_not_found &) {
  61. got_service_not_found = true;
  62. }
  63. assert(got_service_not_found);
  64. }
  65. // test_prelim_dep: A preliminary (unresolved) service dependency
  66. class test_prelim_dep
  67. {
  68. public:
  69. std::string name;
  70. dependency_type dep_type;
  71. test_prelim_dep(const std::string &name_p, dependency_type dep_type_p)
  72. : name(name_p), dep_type(dep_type_p) { }
  73. test_prelim_dep(std::string &&name_p, dependency_type dep_type_p)
  74. : name(std::move(name_p)), dep_type(dep_type_p) { }
  75. };
  76. void test_settings()
  77. {
  78. using string = std::string;
  79. using string_iterator = std::string::iterator;
  80. using prelim_dep = test_prelim_dep;
  81. dinit_load::service_settings_wrapper<prelim_dep> settings;
  82. std::stringstream ss;
  83. ss << "type = process\n"
  84. "command = /something/test\n"
  85. "depends-on = abc\n"
  86. "rlimit-nofile = 50:100\n"
  87. "rlimit-core = 60:\n"
  88. "rlimit-data = -:-";
  89. try {
  90. process_service_file("test-service", ss,
  91. [&](string &line, unsigned line_num, string &setting, string_iterator &i, string_iterator &end) -> void {
  92. auto process_dep_dir_n = [&](std::list<prelim_dep> &deplist, const std::string &waitsford,
  93. dependency_type dep_type) -> void {
  94. //process_dep_dir(name.c_str(), service_filename, deplist, waitsford, dep_type);
  95. };
  96. auto load_service_n = [&](const string &dep_name) -> const string & {
  97. return dep_name;
  98. };
  99. try {
  100. process_service_line(settings, "test-service", line, line_num, setting, i, end, load_service_n, process_dep_dir_n);
  101. }
  102. catch (service_description_exc &exc) {
  103. //report_service_description_exc(exc);
  104. }
  105. });
  106. }
  107. catch (std::system_error &sys_err)
  108. {
  109. //report_error(sys_err, name);
  110. throw service_description_exc("", "error while reading service description.", "unknown");
  111. }
  112. assert(settings.service_type == service_type_t::PROCESS);
  113. assert(settings.command == "/something/test");
  114. assert(settings.rlimits.size() == 3);
  115. assert(settings.rlimits[0].resource_id == RLIMIT_NOFILE);
  116. assert(settings.rlimits[0].soft_set && settings.rlimits[0].hard_set);
  117. assert(settings.rlimits[0].limits.rlim_cur == 50);
  118. assert(settings.rlimits[0].limits.rlim_max == 100);
  119. assert(settings.rlimits[1].resource_id == RLIMIT_CORE);
  120. assert(settings.rlimits[1].soft_set && !settings.rlimits[1].hard_set);
  121. assert(settings.rlimits[1].limits.rlim_cur == 60);
  122. assert(settings.rlimits[2].resource_id == RLIMIT_DATA);
  123. assert(settings.rlimits[2].soft_set && settings.rlimits[2].hard_set);
  124. assert(settings.rlimits[2].limits.rlim_cur == RLIM_INFINITY);
  125. assert(settings.rlimits[2].limits.rlim_max == RLIM_INFINITY);
  126. assert(settings.depends.size() == 1);
  127. assert(settings.depends.front().dep_type == dependency_type::REGULAR);
  128. assert(settings.depends.front().name == "abc");
  129. }
  130. void test_path_env_subst()
  131. {
  132. using string = std::string;
  133. using string_iterator = std::string::iterator;
  134. using prelim_dep = test_prelim_dep;
  135. dinit_load::service_settings_wrapper<prelim_dep> settings;
  136. std::stringstream ss;
  137. ss << "type = process\n"
  138. "command = /something/test\n"
  139. "logfile = /some/$username/dir\n";
  140. try {
  141. process_service_file("test-service", ss,
  142. [&](string &line, unsigned line_num, string &setting, string_iterator &i, string_iterator &end) -> void {
  143. auto process_dep_dir_n = [&](std::list<prelim_dep> &deplist, const std::string &waitsford,
  144. dependency_type dep_type) -> void {
  145. //process_dep_dir(name.c_str(), service_filename, deplist, waitsford, dep_type);
  146. };
  147. auto load_service_n = [&](const string &dep_name) -> const string & {
  148. return dep_name;
  149. };
  150. try {
  151. process_service_line(settings, "test-service", line, line_num, setting, i, end, load_service_n, process_dep_dir_n);
  152. }
  153. catch (service_description_exc &exc) {
  154. //report_service_description_exc(exc);
  155. }
  156. });
  157. }
  158. catch (std::system_error &sys_err)
  159. {
  160. throw service_description_exc("", "error while reading service description.", "unknown");
  161. }
  162. auto report_error = [](const char *msg) {};
  163. auto resolve_var = [](const std::string &name) {
  164. if (name == "username") return "testsuccess";
  165. return "";
  166. };
  167. settings.finalise(report_error, report_error /* lint */, resolve_var);
  168. assert(settings.service_type == service_type_t::PROCESS);
  169. assert(settings.command == "/something/test");
  170. assert(settings.logfile == "/some/testsuccess/dir");
  171. }
  172. #define RUN_TEST(name, spacing) \
  173. std::cout << #name "..." spacing << std::flush; \
  174. name(); \
  175. std::cout << "PASSED" << std::endl;
  176. int main(int argc, char **argv)
  177. {
  178. init_test_service_dir();
  179. RUN_TEST(test_basic, " ");
  180. RUN_TEST(test_env_subst, " ");
  181. RUN_TEST(test_env_subst2, " ");
  182. RUN_TEST(test_nonexistent, " ");
  183. RUN_TEST(test_settings, " ");
  184. RUN_TEST(test_path_env_subst, " ");
  185. return 0;
  186. }