Tests about a simple python3 fastcgi runner using libfcgi and the Python-C API.
python
c
wsgi
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

check_logger.c 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. #include <stdlib.h>
  2. #include <check.h>
  3. #include <time.h>
  4. #include <stdio.h>
  5. #include "logger.h"
  6. pyfcgi_conf_logger_t *conf = &PyFCGI_conf.logs;
  7. char tmpdir[] = "/tmp/tmp_PyFCGI_checksXXXXXX";
  8. /*
  9. TC logger init
  10. */
  11. START_TEST(test_logger_init)
  12. {
  13. pyfcgi_logger_init();
  14. ck_assert_ptr_eq(conf->syslog_ident, NULL);
  15. ck_assert_ptr_eq(conf->ident, NULL);
  16. /*
  17. ck_assert_ptr_eq(conf->formats, NULL);
  18. ck_assert_ptr_eq(conf->loggers, NULL);
  19. */
  20. ck_assert_int_eq(conf->logger_sz, 0);
  21. ck_assert_int_eq(conf->format_sz, 0);
  22. ck_assert_int_eq(conf->flags, 0);
  23. }
  24. END_TEST
  25. START_TEST(test_logger_format_add)
  26. {
  27. int ret;
  28. size_t s;
  29. pyfcgi_logger_init();
  30. const char *fmt = "{datetime} {level} {ident}[{pid}] {msg}";
  31. const char *fmt2 = "{datetime} {level} {ident} {msg}";
  32. ret = pyfcgi_logger_format_add(fmt, &s);
  33. ck_assert_int_eq(ret, 0);
  34. ck_assert_int_eq(conf->format_sz, 1);
  35. ck_assert_int_eq(s, 0);
  36. ck_assert_str_eq(conf->formats[s].fmt, fmt);
  37. ret = pyfcgi_logger_format_add(fmt2, &s);
  38. ck_assert_int_eq(ret, 0);
  39. ck_assert_int_eq(conf->format_sz, 2);
  40. ck_assert_int_eq(s, 1);
  41. ck_assert_str_eq(conf->formats[s].fmt, fmt2);
  42. ret = pyfcgi_logger_format_add(fmt, &s);
  43. ck_assert_int_eq(ret, 0);
  44. ck_assert_int_eq(conf->format_sz, 2);
  45. ck_assert_int_eq(s, 0);
  46. ck_assert_str_eq(conf->formats[s].fmt, fmt);
  47. }
  48. END_TEST
  49. START_TEST(test_logger_add)
  50. {
  51. char tmplog[128];
  52. char logfmt[] = "{level} {ident} {pid} {msg}";
  53. char expected[] = " Alert 0 Hello world ! foobar 04\n";
  54. int ret;
  55. pyfcgi_conf_logger_t *conf;
  56. pyfcgi_logger_t *logger;
  57. pyfcgi_logger_format_t *fmt;
  58. char buf[128];
  59. size_t sz;
  60. memset(buf, 0, 128);
  61. pyfcgi_logger_init();
  62. conf = &PyFCGI_conf.logs;
  63. logger = &(conf->loggers[0]);
  64. snprintf(tmplog, 128, "%s/%s", tmpdir, "format_add.log");
  65. ret = pyfcgi_logger_add(tmplog, 0xFF, 0xFF, logfmt);
  66. ck_assert_int_eq(ret, 0);
  67. ck_assert_int_eq(conf->logger_sz, 1);
  68. ck_assert_str_eq(logger->filename, tmplog);
  69. fmt = &(conf->formats[logger->fmt_id]);
  70. ck_assert_str_eq(fmt->fmt, logfmt);
  71. pyfcgi_log(LOG_ALERT, "Hello world ! %s %02d", "foobar", 4);
  72. //pyfcgi_log(LOG_DEBUG, "Hello world 2 %s\n", tmplog);
  73. pyfcgi_logger_stop();
  74. ret = open(tmplog, O_RDONLY);
  75. sz = read(ret, buf, 128);
  76. ck_assert_str_eq(expected, buf);
  77. unlink(tmplog);
  78. }
  79. END_TEST
  80. /*
  81. TC logger default values
  82. */
  83. START_TEST(test_logger_parse_field_dtfmt_default)
  84. {
  85. int ret;
  86. char *ptr, *orig, *fmt;
  87. orig = "}";
  88. ptr = orig;
  89. fmt = NULL;
  90. ret = pyfcgi_logger_parse_field_dtfmt((const char**)&ptr, &fmt);
  91. ck_assert_int_eq(ret, 0);
  92. ck_assert_str_eq(fmt, PYFCGI_LOGGER_TIME_FMT_DEFAULT);
  93. ck_assert_ptr_eq(ptr, orig);
  94. free(fmt);
  95. }
  96. END_TEST
  97. START_TEST(test_logger_parse_field_sz_default)
  98. {
  99. int ret;
  100. size_t val;
  101. char *ptr, **orig;
  102. char *vals[] = {":%F}", ":}", "}", NULL};
  103. orig = vals;
  104. while(*orig)
  105. {
  106. ptr = *orig;
  107. ret = pyfcgi_logger_parse_field_sz((const char**)&ptr, &val);
  108. ck_assert_int_eq(ret, 0);
  109. ck_assert_int_eq(val, 0);
  110. ck_assert_ptr_eq(ptr, (*orig));
  111. orig++;
  112. }
  113. }
  114. END_TEST
  115. START_TEST(test_logger_parse_field_datetime_default)
  116. {
  117. int ret;
  118. char *ptr, **orig, err[PYFCGI_LOGGER_FMT_PARSE_ERRSZ];
  119. pyfcgi_logger_fmt_field_t field;
  120. char *vals[] = {"datetime}", "datetime::}", "datetime:}", NULL};
  121. memset(&field, 0, sizeof(pyfcgi_logger_fmt_field_t));
  122. orig = vals;
  123. while(*orig)
  124. {
  125. ptr = *orig;
  126. ret = pyfcgi_logger_parse_field((const char**)&ptr,
  127. (const char*)ptr, &field,
  128. err);
  129. if(ret)
  130. {
  131. dprintf(2, "ERROR : '%s'\n", err);
  132. }
  133. ck_assert_int_eq(ret, 0);
  134. ck_assert_int_eq(field.type, pyfcgi_logger_field_datetime);
  135. ck_assert_int_ne(field.known_length, 0);
  136. ck_assert_int_eq(field.len, PYFCGI_LOG_DTM_LEN);
  137. ck_assert_ptr_eq(field.val, strftime);
  138. ck_assert_str_eq(field.args.datetime.format,
  139. PYFCGI_LOGGER_TIME_FMT_DEFAULT);
  140. ck_assert_ptr_eq(field.buf_ptr, NULL);
  141. orig++;
  142. }
  143. }
  144. END_TEST
  145. START_TEST(test_logger_format_add_default)
  146. {
  147. int ret;
  148. size_t s;
  149. pyfcgi_logger_init();
  150. ret = pyfcgi_logger_format_add(NULL, &s);
  151. ck_assert_int_eq(ret, 0);
  152. ck_assert_int_eq(conf->format_sz, 1);
  153. ck_assert_int_eq(s, 0);
  154. ck_assert_str_eq(conf->formats[s].fmt, PYFCGI_LOGGER_FMT_DEFAULT);
  155. }
  156. END_TEST
  157. /*
  158. TC logger field parsing
  159. */
  160. START_TEST(test_logger_parse_field_sz)
  161. {
  162. int ret, *res;
  163. size_t val;
  164. char *ptr, **orig, **eptr;
  165. char *vals[] = {"42:%F}", "1337:}", "0}", ":}", NULL};
  166. int _res[] = {42,1337,0, 0};
  167. char *_eptr[] = {vals[0]+2, vals[1]+4, vals[2]+1, vals[3]};
  168. orig = vals;
  169. eptr = _eptr;
  170. res = _res;
  171. while(*orig)
  172. {
  173. ptr = *orig;
  174. ret = pyfcgi_logger_parse_field_sz((const char**)&ptr, &val);
  175. ck_assert_int_eq(val, *res);
  176. ck_assert_ptr_eq(ptr, *eptr);
  177. orig++;
  178. res++;
  179. eptr++;
  180. }
  181. }
  182. END_TEST
  183. START_TEST(test_logger_parse_field_dtfmt)
  184. {
  185. int ret;
  186. size_t len;
  187. char **val, **ptr, *fmt;
  188. char *_vals[] = {"%fdc}", "123}", "4}}foo}", NULL};
  189. val = _vals;
  190. while(*val)
  191. {
  192. ptr = val;
  193. len = strlen(*val);
  194. ret = pyfcgi_logger_parse_field_dtfmt((const char**)&ptr, &fmt);
  195. *val[len-1] = '\0'; //deleting leading '}' to get expected result
  196. ck_assert_int_eq(ret, 0);
  197. ck_assert_ptr_ne(fmt, *val);
  198. ck_assert_str_eq(fmt, *val);
  199. ck_assert_ptr_eq(ptr, *val+len-1);
  200. free(fmt);
  201. val++;
  202. }
  203. }
  204. END_TEST
  205. START_TEST(test_logger_parse_field_datetime)
  206. {
  207. int ret, *len;
  208. char *ptr, **orig, **fmt, err[PYFCGI_LOGGER_FMT_PARSE_ERRSZ];
  209. pyfcgi_logger_fmt_field_t field;
  210. char *vals[] = {"datetime:42}", "datetime::%s%F}",
  211. "datetime:42:COUCOU}",
  212. "dat:32:FOO}", "d::BAR}",
  213. "datetime}{level}", "datetime} {level}",
  214. "datetime}:{level}",
  215. NULL};
  216. int _len[] = {42, PYFCGI_LOG_DTM_LEN, 42, 32, PYFCGI_LOG_DTM_LEN,
  217. PYFCGI_LOG_DTM_LEN, PYFCGI_LOG_DTM_LEN, PYFCGI_LOG_DTM_LEN};
  218. char *_fmt[] = {PYFCGI_LOGGER_TIME_FMT_DEFAULT, "%s%F", "COUCOU", "FOO",
  219. "BAR", PYFCGI_LOGGER_TIME_FMT_DEFAULT,
  220. PYFCGI_LOGGER_TIME_FMT_DEFAULT,
  221. PYFCGI_LOGGER_TIME_FMT_DEFAULT};
  222. memset(&field, 0, sizeof(pyfcgi_logger_fmt_field_t));
  223. len = _len;
  224. fmt = _fmt;
  225. orig = vals;
  226. while(*orig)
  227. {
  228. ptr = *orig;
  229. ret = pyfcgi_logger_parse_field((const char**)&ptr,
  230. (const char*)ptr, &field,
  231. err);
  232. if(ret)
  233. {
  234. dprintf(2, "ERROR : '%s'\n", err);
  235. }
  236. ck_assert_int_eq(ret, 0);
  237. ck_assert_int_eq(field.type, pyfcgi_logger_field_datetime);
  238. ck_assert_int_ne(field.known_length, 0);
  239. ck_assert_int_eq(field.len, *len);
  240. ck_assert_ptr_eq(field.val, strftime);
  241. ck_assert_str_eq(field.args.datetime.format, *fmt);
  242. ck_assert_ptr_eq(field.buf_ptr, NULL);
  243. orig++;
  244. len++;
  245. fmt++;
  246. }
  247. }
  248. END_TEST
  249. START_TEST(test_logger_parse_field_level)
  250. {
  251. int ret;
  252. char **val, **ptr;
  253. char err[PYFCGI_LOGGER_FMT_PARSE_ERRSZ];
  254. char *vals[] = {"level}", "l}", "leve}", NULL};
  255. pyfcgi_logger_fmt_field_t field;
  256. val = vals;
  257. memset(&field, 0, sizeof(pyfcgi_logger_fmt_field_t));
  258. while(*val)
  259. {
  260. ptr = val;
  261. ret = pyfcgi_logger_parse_field((const char**)ptr,
  262. (const char*)*ptr, &field,
  263. err);
  264. if(ret)
  265. {
  266. dprintf(2, "ERROR : '%s'\n", err);
  267. }
  268. ck_assert_int_eq(ret, 0);
  269. ck_assert_int_eq(field.type, pyfcgi_logger_field_level);
  270. ck_assert_int_ne(field.known_length, 0);
  271. ck_assert_int_eq(field.len, PYFCGI_LOG_LVL_LEN);
  272. ck_assert_ptr_eq(field.val, pyfcgi_logger_value_level);
  273. val++;
  274. }
  275. }
  276. END_TEST
  277. START_TEST(test_logger_parse_field_facility)
  278. {
  279. int ret;
  280. char **val, **ptr;
  281. char err[PYFCGI_LOGGER_FMT_PARSE_ERRSZ];
  282. char *vals[] = {"facility}", "f}", "fac}", NULL};
  283. pyfcgi_logger_fmt_field_t field;
  284. val = vals;
  285. memset(&field, 0, sizeof(pyfcgi_logger_fmt_field_t));
  286. while(*val)
  287. {
  288. ptr = val;
  289. ret = pyfcgi_logger_parse_field((const char**)ptr,
  290. (const char*)*ptr, &field,
  291. err);
  292. if(ret)
  293. {
  294. dprintf(2, "ERROR : '%s'\n", err);
  295. }
  296. ck_assert_int_eq(ret, 0);
  297. ck_assert_int_eq(field.type, pyfcgi_logger_field_facility);
  298. ck_assert_int_ne(field.known_length, 0);
  299. ck_assert_int_eq(field.len, PYFCGI_LOG_TYP_LEN);
  300. ck_assert_ptr_eq(field.val, pyfcgi_logger_value_facility);
  301. val++;
  302. }
  303. }
  304. END_TEST
  305. START_TEST(test_logger_parse_field_pid)
  306. {
  307. int ret;
  308. char **val, **ptr;
  309. char err[PYFCGI_LOGGER_FMT_PARSE_ERRSZ];
  310. char *vals[] = {"pid}", "p}", "pi}", NULL};
  311. pyfcgi_logger_fmt_field_t field;
  312. val = vals;
  313. memset(&field, 0, sizeof(pyfcgi_logger_fmt_field_t));
  314. while(*val)
  315. {
  316. ptr = val;
  317. ret = pyfcgi_logger_parse_field((const char**)ptr,
  318. (const char*)*ptr, &field,
  319. err);
  320. if(ret)
  321. {
  322. dprintf(2, "ERROR : '%s'\n", err);
  323. }
  324. ck_assert_int_eq(ret, 0);
  325. ck_assert_int_eq(field.type, pyfcgi_logger_field_pid);
  326. ck_assert_int_ne(field.known_length, 0);
  327. ck_assert_int_eq(field.len, PYFCGI_LOG_PID_LEN-1);
  328. ck_assert_ptr_eq(field.val, (&PyFCGI_conf.context.pid));
  329. val++;
  330. }
  331. }
  332. END_TEST
  333. START_TEST(test_logger_parse_field_ident)
  334. {
  335. int ret;
  336. char **val, **ptr;
  337. char err[PYFCGI_LOGGER_FMT_PARSE_ERRSZ];
  338. char *vals[] = {"ident}", "i}", "id}", NULL};
  339. pyfcgi_logger_fmt_field_t field;
  340. val = vals;
  341. memset(&field, 0, sizeof(pyfcgi_logger_fmt_field_t));
  342. while(*val)
  343. {
  344. ptr = val;
  345. ret = pyfcgi_logger_parse_field((const char**)ptr,
  346. (const char*)*ptr, &field,
  347. err);
  348. if(ret)
  349. {
  350. dprintf(2, "ERROR : '%s'\n", err);
  351. }
  352. ck_assert_int_eq(ret, 0);
  353. ck_assert_int_eq(field.type, pyfcgi_logger_field_ident);
  354. ck_assert_int_ne(field.known_length, 0);
  355. ck_assert_int_eq(field.len, 0);
  356. ck_assert_ptr_eq(field.val, (&PyFCGI_conf.logs.ident));
  357. val++;
  358. }
  359. }
  360. END_TEST
  361. START_TEST(test_logger_parse_field_msg)
  362. {
  363. int ret;
  364. char **val, **ptr;
  365. char err[PYFCGI_LOGGER_FMT_PARSE_ERRSZ];
  366. pyfcgi_logger_fmt_field_t field;
  367. char *vals[] = {"msg}", "m}", "ms}", NULL};
  368. val = vals;
  369. memset(&field, 0, sizeof(pyfcgi_logger_fmt_field_t));
  370. while(*val)
  371. {
  372. ptr = val;
  373. ret = pyfcgi_logger_parse_field((const char**)ptr,
  374. (const char*)*ptr, &field,
  375. err);
  376. if(ret)
  377. {
  378. dprintf(2, "ERROR : '%s'\n", err);
  379. }
  380. ck_assert_int_eq(ret, 0);
  381. ck_assert_int_eq(field.type, pyfcgi_logger_field_msg);
  382. ck_assert_int_eq(field.known_length, 0);
  383. ck_assert_int_eq(field.len, 0);
  384. ck_assert_ptr_eq(field.val, NULL);
  385. val++;
  386. }
  387. }
  388. END_TEST
  389. START_TEST(test_logger_format_parse1)
  390. {
  391. int ret, i;
  392. size_t s;
  393. pyfcgi_logger_init();
  394. const char *fmt = "{datetime} {level} {ident}[{pid}] {msg}";
  395. pyfcgi_logger_field_type_e types[] = {
  396. pyfcgi_logger_field_datetime, pyfcgi_logger_field_const,
  397. pyfcgi_logger_field_level, pyfcgi_logger_field_const,
  398. pyfcgi_logger_field_ident, pyfcgi_logger_field_const,
  399. pyfcgi_logger_field_pid, pyfcgi_logger_field_const,
  400. pyfcgi_logger_field_msg};
  401. ret = pyfcgi_logger_format_add(fmt, &s);
  402. ck_assert_int_eq(ret, 0);
  403. ck_assert_int_eq(conf->format_sz, 1);
  404. ck_assert_int_eq(s, 0);
  405. ck_assert_str_eq(conf->formats[s].fmt, fmt);
  406. ck_assert_int_eq(conf->formats[s].nfield, 9);
  407. for(i=0; i<9; i++)
  408. {
  409. ck_assert_int_eq(conf->formats[s].fields[i].type, types[i]);
  410. }
  411. ck_assert_str_eq(conf->formats[s].fields[1].val, " ");
  412. ck_assert_str_eq(conf->formats[s].fields[3].val, " ");
  413. ck_assert_str_eq(conf->formats[s].fields[5].val, "[");
  414. ck_assert_str_eq(conf->formats[s].fields[7].val, "] ");
  415. ck_assert_str_eq(conf->formats[s].fields[0].args.datetime.format,
  416. PYFCGI_LOGGER_TIME_FMT_DEFAULT);
  417. }
  418. END_TEST
  419. /*
  420. TC logger format parsing error
  421. */
  422. START_TEST(test_logger_parse_field_sz_err)
  423. {
  424. int ret, *res;
  425. size_t val;
  426. char **ptr, **orig;
  427. char *vals[] = {"-42:%F}", "abc:}", "", "", NULL};
  428. orig = vals;
  429. while(*orig)
  430. {
  431. ptr = orig;
  432. ret = pyfcgi_logger_parse_field_sz((const char**)ptr, &val);
  433. ck_assert_int_eq(val, 0);
  434. ck_assert_int_ne(ret, 0);
  435. orig++;
  436. res++;
  437. }
  438. }
  439. END_TEST
  440. START_TEST(test_logger_parse_field_parse_err)
  441. {
  442. int ret;
  443. char **val, **ptr;
  444. char err[PYFCGI_LOGGER_FMT_PARSE_ERRSZ];
  445. char *vals[] = {"foobar}", "::}", "ident", "",
  446. "level", "pid", "42}", ":ident:", ":ident}", NULL};
  447. pyfcgi_logger_fmt_field_t field;
  448. val = vals;
  449. memset(&field, 0, sizeof(pyfcgi_logger_fmt_field_t));
  450. while(*val)
  451. {
  452. ptr = val;
  453. *err = '\0';
  454. ret = pyfcgi_logger_parse_field((const char**)ptr,
  455. (const char*)*ptr, &field,
  456. err);
  457. ck_assert_int_ne(ret, 0);
  458. ck_assert_int_ne(*err, '\0');
  459. ck_assert_int_eq(field.type, pyfcgi_logger_field_null);
  460. val++;
  461. }
  462. }
  463. END_TEST
  464. /* Suite, runner & main */
  465. Suite * logger_suite(void)
  466. {
  467. Suite *s;
  468. TCase *tc_init, *tc_field, *tc_field_default, *tc_parse_err;
  469. s = suite_create("Logger");
  470. tc_field_default = tcase_create("Logger format parsing default values");
  471. tcase_add_test(tc_field_default, test_logger_parse_field_dtfmt_default);
  472. tcase_add_test(tc_field_default, test_logger_parse_field_sz_default);
  473. tcase_add_test(tc_field_default, test_logger_parse_field_datetime_default);
  474. tcase_add_test(tc_field_default, test_logger_format_add_default);
  475. suite_add_tcase(s, tc_field_default);
  476. tc_field = tcase_create("Logger format parsing");
  477. tcase_add_test(tc_field, test_logger_parse_field_sz);
  478. tcase_add_test(tc_field, test_logger_parse_field_datetime);
  479. tcase_add_test(tc_field, test_logger_parse_field_level);
  480. tcase_add_test(tc_field, test_logger_parse_field_facility);
  481. tcase_add_test(tc_field, test_logger_parse_field_pid);
  482. tcase_add_test(tc_field, test_logger_parse_field_ident);
  483. tcase_add_test(tc_field, test_logger_parse_field_msg);
  484. tcase_add_test(tc_field, test_logger_format_parse1);
  485. suite_add_tcase(s, tc_field);
  486. tc_parse_err = tcase_create("Logger format parsing errors handling");
  487. tcase_add_test(tc_parse_err, test_logger_parse_field_sz_err);
  488. tcase_add_test(tc_parse_err, test_logger_parse_field_parse_err);
  489. suite_add_tcase(s, tc_parse_err);
  490. tc_init = tcase_create("Initialisation");
  491. tcase_add_test(tc_init, test_logger_init);
  492. tcase_add_test(tc_init, test_logger_format_add);
  493. tcase_add_test(tc_init, test_logger_add);
  494. suite_add_tcase(s, tc_init);
  495. return s;
  496. }
  497. int main(void)
  498. {
  499. int nfailed;
  500. Suite *s;
  501. SRunner *sr;
  502. mkdtemp(tmpdir);
  503. s = logger_suite();
  504. sr = srunner_create(s);
  505. //srunner_set_fork_status(sr, CK_NOFORK);
  506. //srunner_run_all(sr, CK_NORMAL);
  507. //srunner_run_all(sr, CK_ENV);
  508. srunner_run_all(sr, CK_VERBOSE);
  509. nfailed = srunner_ntests_failed(sr);
  510. srunner_free(sr);
  511. rmdir(tmpdir);
  512. return (!nfailed)?EXIT_SUCCESS:EXIT_FAILURE;
  513. }