unit_test.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. /** @file unit_test.h
  3. * @brief Includes unit tests for the Logs Management project
  4. */
  5. #include "unit_test.h"
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #ifndef __USE_XOPEN_EXTENDED
  9. #define __USE_XOPEN_EXTENDED
  10. #endif
  11. #include <ftw.h>
  12. #include <unistd.h>
  13. #include "../circular_buffer.h"
  14. #include "../helper.h"
  15. #include "../logsmanag_config.h"
  16. #include "../parser.h"
  17. #include "../query.h"
  18. #include "../db_api.h"
  19. static int old_stdout = STDOUT_FILENO;
  20. static int old_stderr = STDERR_FILENO;
  21. #define SUPRESS_STDX(stream_no) \
  22. { \
  23. if(stream_no == STDOUT_FILENO) \
  24. old_stdout = dup(old_stdout); \
  25. else \
  26. old_stderr = dup(old_stderr); \
  27. if(!freopen("/dev/null", "w", stream_no == STDOUT_FILENO ? stdout : stderr)) \
  28. exit(-1); \
  29. }
  30. #define UNSUPRESS_STDX(stream_no) \
  31. { \
  32. fclose(stream_no == STDOUT_FILENO ? stdout : stderr); \
  33. if(stream_no == STDOUT_FILENO) \
  34. stdout = fdopen(old_stdout, "w"); \
  35. else \
  36. stderr = fdopen(old_stderr, "w"); \
  37. }
  38. #define SUPRESS_STDOUT() SUPRESS_STDX(STDOUT_FILENO)
  39. #define SUPRESS_STDERR() SUPRESS_STDX(STDERR_FILENO)
  40. #define UNSUPRESS_STDOUT() UNSUPRESS_STDX(STDOUT_FILENO)
  41. #define UNSUPRESS_STDERR() UNSUPRESS_STDX(STDERR_FILENO)
  42. #define LOG_RECORDS_PARTIAL "\
  43. 127.0.0.1 - - [30/Jun/2022:16:43:51 +0300] \"GET / HTTP/1.0\" 200 11192 \"-\" \"ApacheBench/2.3\"\n\
  44. 192.168.2.1 - - [30/Jun/2022:16:43:51 +0300] \"PUT / HTTP/1.0\" 400 11192 \"-\" \"ApacheBench/2.3\"\n\
  45. 255.91.204.202 - mann1475 [30/Jun/2023:21:05:09 +0000] \"POST /vertical/turn-key/engineer/e-enable HTTP/1.0\" 401 11411\n\
  46. 91.126.60.234 - ritchie4302 [30/Jun/2023:21:05:09 +0000] \"PATCH /empower/interfaces/deploy HTTP/2.0\" 404 29063\n\
  47. 120.134.242.160 - runte5364 [30/Jun/2023:21:05:09 +0000] \"GET /visualize/enterprise/optimize/embrace HTTP/1.0\" 400 10637\n\
  48. 61.134.57.25 - - [30/Jun/2023:21:05:09 +0000] \"HEAD /metrics/optimize/bandwidth HTTP/1.1\" 200 26713\n\
  49. 18.90.118.50 - - [30/Jun/2023:21:05:09 +0000] \"PATCH /methodologies/extend HTTP/2.0\" 205 15708\n\
  50. 21.174.251.223 - zulauf8852 [30/Jun/2023:21:05:09 +0000] \"POST /proactive HTTP/2.0\" 100 9456\n\
  51. 20.217.190.46 - - [30/Jun/2023:21:05:09 +0000] \"GET /mesh/frictionless HTTP/1.1\" 301 3153\n\
  52. 130.43.250.80 - hintz5738 [30/Jun/2023:21:05:09 +0000] \"PATCH /e-markets/supply-chains/mindshare HTTP/2.0\" 401 13039\n\
  53. 222.36.95.121 - pouros3514 [30/Jun/2023:21:05:09 +0000] \"DELETE /e-commerce/scale/customized/best-of-breed HTTP/1.0\" 406 8304\n\
  54. 133.117.9.29 - hoeger7673 [30/Jun/2023:21:05:09 +0000] \"PUT /extensible/maximize/visualize/bricks-and-clicks HTTP/1.0\" 403 17067\n\
  55. 65.145.39.136 - heathcote3368 [30/Jun/2023:21:05:09 +0000] \"DELETE /technologies/iterate/viral HTTP/1.1\" 501 29982\n\
  56. 153.132.199.122 - murray8217 [30/Jun/2023:21:05:09 +0000] \"PUT /orchestrate/visionary/visualize HTTP/1.1\" 500 12705\n\
  57. 140.149.178.196 - hickle8613 [30/Jun/2023:21:05:09 +0000] \"PATCH /drive/front-end/infomediaries/maximize HTTP/1.1\" 406 20179\n\
  58. 237.31.189.207 - - [30/Jun/2023:21:05:09 +0000] \"GET /bleeding-edge/recontextualize HTTP/1.1\" 406 24815\n\
  59. 210.217.232.107 - - [30/Jun/2023:21:05:09 +0000] \"POST /redefine/next-generation/relationships/intuitive HTTP/2.0\" 205 14028\n\
  60. 121.2.189.119 - marvin5528 [30/Jun/2023:21:05:09 +0000] \"PUT /sexy/innovative HTTP/2.0\" 204 10689\n\
  61. 120.13.121.164 - jakubowski1027 [30/Jun/2023:21:05:09 +0000] \"PUT /sexy/initiatives/morph/eyeballs HTTP/1.0\" 502 22287\n\
  62. 28.229.107.175 - wilderman8830 [30/Jun/2023:21:05:09 +0000] \"PATCH /visionary/best-of-breed HTTP/1.1\" 503 6010\n\
  63. 210.147.186.50 - - [30/Jun/2023:21:05:09 +0000] \"PUT /paradigms HTTP/2.0\" 501 18054\n\
  64. 185.157.236.127 - - [30/Jun/2023:21:05:09 +0000] \"GET /maximize HTTP/1.0\" 400 13650\n\
  65. 236.90.19.165 - - [30/Jun/2023:21:23:34 +0000] \"GET /next-generation/user-centric/24%2f365 HTTP/1.0\" 400 5212\n\
  66. 233.182.111.100 - torphy3512 [30/Jun/2023:21:23:34 +0000] \"PUT /seamless/incentivize HTTP/1.0\" 304 27750\n\
  67. 80.185.129.193 - - [30/Jun/2023:21:23:34 +0000] \"HEAD /strategic HTTP/1.1\" 502 6146\n\
  68. 182.145.92.52 - - [30/Jun/2023:21:23:34 +0000] \"PUT /dot-com/grow/networks HTTP/1.0\" 301 1763\n\
  69. 46.14.122.16 - - [30/Jun/2023:21:23:34 +0000] \"HEAD /deliverables HTTP/1.0\" 301 7608\n\
  70. 162.111.143.158 - bruen3883 [30/Jun/2023:21:23:34 +0000] \"POST /extensible HTTP/2.0\" 403 22752\n\
  71. 201.13.111.255 - hilpert8768 [30/Jun/2023:21:23:34 +0000] \"PATCH /applications/engage/frictionless/content HTTP/1.0\" 406 24866\n\
  72. 76.90.243.15 - - [30/Jun/2023:21:23:34 +0000] \"PATCH /24%2f7/seamless/target/enable HTTP/1.1\" 503 8176\n\
  73. 187.79.114.48 - - [30/Jun/2023:21:23:34 +0000] \"GET /synergistic HTTP/1.0\" 503 14251\n\
  74. 59.52.178.62 - kirlin3704 [30/Jun/2023:21:23:34 +0000] \"POST /web-readiness/grow/evolve HTTP/1.0\" 501 13305\n\
  75. 27.46.78.167 - - [30/Jun/2023:21:23:34 +0000] \"PATCH /interfaces/schemas HTTP/2.0\" 100 4860\n\
  76. 191.9.15.43 - goodwin7310 [30/Jun/2023:21:23:34 +0000] \"POST /engage/innovate/web-readiness/roi HTTP/2.0\" 404 4225\n\
  77. 195.153.126.148 - klein8350 [30/Jun/2023:21:23:34 +0000] \"DELETE /killer/synthesize HTTP/1.0\" 204 15134\n\
  78. 162.207.64.184 - mayert4426 [30/Jun/2023:21:23:34 +0000] \"HEAD /intuitive/vertical/incentivize HTTP/1.0\" 204 23666\n\
  79. 185.96.7.205 - - [30/Jun/2023:21:23:34 +0000] \"DELETE /communities/deliver/user-centric HTTP/1.0\" 416 18210\n\
  80. 187.180.105.55 - - [30/Jun/2023:21:23:34 +0000] \"POST /customized HTTP/2.0\" 200 1396\n\
  81. 216.82.243.54 - kunze7200 [30/Jun/2023:21:23:34 +0000] \"PUT /e-tailers/evolve/leverage/engage HTTP/2.0\" 504 1665\n\
  82. 170.128.69.228 - - [30/Jun/2023:21:23:34 +0000] \"DELETE /matrix/open-source/proactive HTTP/1.0\" 301 18326\n\
  83. 253.200.84.66 - steuber5220 [30/Jun/2023:21:23:34 +0000] \"POST /benchmark/experiences HTTP/1.1\" 504 18944\n\
  84. 28.240.40.161 - - [30/Jun/2023:21:23:34 +0000] \"PATCH /initiatives HTTP/1.0\" 500 6500\n\
  85. 134.163.236.75 - - [30/Jun/2023:21:23:34 +0000] \"HEAD /platforms/recontextualize HTTP/1.0\" 203 22188\n\
  86. 241.64.230.66 - - [30/Jun/2023:21:23:34 +0000] \"GET /cutting-edge/methodologies/b2c/cross-media HTTP/1.1\" 403 20698\n\
  87. 210.216.183.157 - okuneva6218 [30/Jun/2023:21:23:34 +0000] \"POST /generate/incentivize HTTP/2.0\" 403 25900\n\
  88. 164.219.134.242 - - [30/Jun/2023:21:23:34 +0000] \"HEAD /efficient/killer/whiteboard HTTP/2.0\" 501 22081\n\
  89. 173.156.54.99 - harvey6165 [30/Jun/2023:21:23:34 +0000] \"HEAD /dynamic/cutting-edge/sexy/user-centric HTTP/2.0\" 200 2995\n\
  90. 215.242.74.14 - - [30/Jun/2023:21:23:34 +0000] \"PUT /roi HTTP/1.0\" 204 9674\n\
  91. 133.77.49.187 - lockman3141 [30/Jun/2023:21:23:34 +0000] \"PUT /mindshare/transition HTTP/2.0\" 503 2726\n\
  92. 159.77.190.255 - - [30/Jun/2023:21:23:34 +0000] \"DELETE /world-class/bricks-and-clicks HTTP/1.1\" 501 21712\n\
  93. 65.6.237.113 - - [30/Jun/2023:21:23:34 +0000] \"PATCH /e-enable HTTP/2.0\" 405 11865\n\
  94. 194.76.211.16 - champlin6280 [30/Jun/2023:21:23:34 +0000] \"PUT /applications/redefine/eyeballs/mindshare HTTP/1.0\" 302 27679\n\
  95. 96.206.219.202 - - [30/Jun/2023:21:23:34 +0000] \"PUT /solutions/mindshare/vortals/transition HTTP/1.0\" 403 7385\n\
  96. 255.80.116.201 - hintz8162 [30/Jun/2023:21:23:34 +0000] \"POST /frictionless/e-commerce HTTP/1.0\" 302 9235\n\
  97. 89.66.165.183 - smith2655 [30/Jun/2023:21:23:34 +0000] \"HEAD /markets/synergize HTTP/2.0\" 501 28055\n\
  98. 39.210.168.14 - - [30/Jun/2023:21:23:34 +0000] \"GET /integrate/killer/end-to-end/infrastructures HTTP/1.0\" 302 11311\n\
  99. 173.99.112.210 - - [30/Jun/2023:21:23:34 +0000] \"GET /interfaces HTTP/2.0\" 503 1471\n\
  100. 108.4.157.6 - morissette1161 [30/Jun/2023:21:23:34 +0000] \"POST /mesh/convergence HTTP/1.1\" 403 18708\n\
  101. 174.160.107.162 - - [30/Jun/2023:21:23:34 +0000] \"POST /vortals/monetize/utilize/synergistic HTTP/1.1\" 302 13252\n\
  102. 188.8.105.56 - beatty6880 [30/Jun/2023:21:23:34 +0000] \"POST /web+services/innovate/generate/leverage HTTP/1.1\" 301 29856\n\
  103. 115.179.64.255 - - [30/Jun/2023:21:23:34 +0000] \"PATCH /transform/transparent/b2c/holistic HTTP/1.1\" 406 10208\n\
  104. 48.104.215.32 - - [30/Jun/2023:21:23:34 +0000] \"DELETE /drive/clicks-and-mortar HTTP/1.0\" 501 13752\n\
  105. 75.212.115.12 - pfannerstill5140 [30/Jun/2023:21:23:34 +0000] \"PATCH /leading-edge/mesh/methodologies HTTP/1.0\" 503 4946\n\
  106. 52.75.2.117 - osinski2030 [30/Jun/2023:21:23:34 +0000] \"PUT /incentivize/recontextualize HTTP/1.1\" 301 8785\n"
  107. #define LOG_RECORD_WITHOUT_NEW_LINE \
  108. "82.39.169.93 - streich5722 [30/Jun/2023:21:23:34 +0000] \"GET /action-items/leading-edge/reinvent/maximize HTTP/1.1\" 500 1228"
  109. #define LOG_RECORDS_WITHOUT_TERMINATING_NEW_LINE \
  110. LOG_RECORDS_PARTIAL \
  111. LOG_RECORD_WITHOUT_NEW_LINE
  112. #define LOG_RECORD_WITH_NEW_LINE \
  113. "131.128.33.109 - turcotte6735 [30/Jun/2023:21:23:34 +0000] \"PUT /distributed/strategize HTTP/1.1\" 401 16471\n"
  114. #define LOG_RECORDS_WITH_TERMINATING_NEW_LINE \
  115. LOG_RECORDS_PARTIAL \
  116. LOG_RECORD_WITH_NEW_LINE
  117. static int test_compression_decompression() {
  118. int errors = 0;
  119. fprintf(stderr, "%s():\n", __FUNCTION__);
  120. Circ_buff_item_t item;
  121. item.text_size = sizeof(LOG_RECORDS_WITH_TERMINATING_NEW_LINE);
  122. fprintf(stderr, "Testing LZ4_compressBound()...\n");
  123. size_t required_compressed_space = LZ4_compressBound(item.text_size);
  124. if(!required_compressed_space){
  125. fprintf(stderr, "- Error while using LZ4_compressBound()\n");
  126. return ++errors;
  127. }
  128. item.data_max_size = item.text_size + required_compressed_space;
  129. item.data = mallocz(item.data_max_size);
  130. memcpy(item.data, LOG_RECORDS_WITH_TERMINATING_NEW_LINE, sizeof(LOG_RECORDS_WITH_TERMINATING_NEW_LINE));
  131. fprintf(stderr, "Testing LZ4_compress_fast()...\n");
  132. item.text_compressed = item.data + item.text_size;
  133. item.text_compressed_size = LZ4_compress_fast( item.data, item.text_compressed,
  134. item.text_size, required_compressed_space, 1);
  135. if(!item.text_compressed_size){
  136. fprintf(stderr, "- Error while using LZ4_compress_fast()\n");
  137. return ++errors;
  138. }
  139. char *decompressed_text = mallocz(item.text_size);
  140. if(LZ4_decompress_safe( item.text_compressed,
  141. decompressed_text,
  142. item.text_compressed_size,
  143. item.text_size) < 0){
  144. fprintf(stderr, "- Error in decompress_text()\n");
  145. return ++errors;
  146. }
  147. if(memcmp(item.data, decompressed_text, item.text_size)){
  148. fprintf(stderr, "- Error, original and decompressed data not the same\n");
  149. ++errors;
  150. }
  151. freez(decompressed_text);
  152. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  153. return errors;
  154. }
  155. static int test_read_last_line() {
  156. int errors = 0;
  157. fprintf(stderr, "%s():\n", __FUNCTION__);
  158. #if defined(_WIN32) || defined(_WIN64)
  159. char tmpname[MAX_PATH] = "/tmp/tmp.XXXXXX";
  160. #else
  161. char tmpname[] = "/tmp/tmp.XXXXXX";
  162. #endif
  163. (void) umask(0022);
  164. int fd = mkstemp(tmpname);
  165. if (fd == -1){
  166. fprintf(stderr, "mkstemp() Failed with error %s\n", strerror(errno));
  167. exit(EXIT_FAILURE);
  168. }
  169. FILE *tmpfp = fdopen(fd, "r+");
  170. if (tmpfp == NULL) {
  171. close(fd);
  172. unlink(tmpname);
  173. exit(EXIT_FAILURE);
  174. }
  175. if(fprintf(tmpfp, "%s", LOG_RECORDS_WITHOUT_TERMINATING_NEW_LINE) <= 0){
  176. close(fd);
  177. unlink(tmpname);
  178. exit(EXIT_FAILURE);
  179. }
  180. fflush(tmpfp);
  181. fprintf(stderr, "Testing read of LOG_RECORD_WITHOUT_NEW_LINE...\n");
  182. errors += strcmp(LOG_RECORD_WITHOUT_NEW_LINE, read_last_line(tmpname, 0)) ? 1 : 0;
  183. if(fprintf(tmpfp, "\n%s", LOG_RECORD_WITH_NEW_LINE) <= 0){
  184. close(fd);
  185. unlink(tmpname);
  186. exit(EXIT_FAILURE);
  187. }
  188. fflush(tmpfp);
  189. fprintf(stderr, "Testing read of LOG_RECORD_WITH_NEW_LINE...\n");
  190. errors += strcmp(LOG_RECORD_WITH_NEW_LINE, read_last_line(tmpname, 0)) ? 1 : 0;
  191. unlink(tmpname);
  192. close(fd);
  193. fclose(tmpfp);
  194. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  195. return errors;
  196. }
  197. const char * const parse_configs_to_test[] = {
  198. /* [1] Apache csvCombined 1 */
  199. "127.0.0.1 - - [15/Oct/2020:04:43:51 -0700] \"GET / HTTP/1.0\" 200 11228 \"-\" \"ApacheBench/2.3\"",
  200. /* [2] Apache csvCombined 2 - extra white space */
  201. "::1 - - [01/Sep/2022:19:04:42 +0100] \"GET / HTTP/1.1\" 200 3477 \"-\" \"Mozilla/5.0 (Windows NT 10.0; \
  202. Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0\"",
  203. /* [3] Apache csvCombined 3 - with new line */
  204. "209.202.252.202 - rosenbaum7551 [20/Jun/2023:14:42:27 +0000] \"PUT /harness/networks/initiatives/engineer HTTP/2.0\"\
  205. 403 42410 \"https://www.senioriterate.name/streamline/exploit\" \"Opera/10.54 (Macintosh; Intel Mac OS X 10_7_6;\
  206. en-US) Presto/2.12.334 Version/10.00\"\n",
  207. /* [4] Apache csvCombined 4 - invalid request field */
  208. "::1 - - [13/Jul/2023:21:00:56 +0100] \"-\" 408 - \"-\" \"-\"",
  209. /* [5] Apache csvVhostCombined */
  210. "XPS-wsl.localdomain:80 ::1 - - [30/Jun/2022:20:59:29 +0300] \"GET / HTTP/1.1\" 200 3477 \"-\" \"Mozilla\
  211. /5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36\
  212. Edg/103.0.1264.37\"",
  213. /* [6] Apache csvCommon 1 */
  214. "127.0.0.1 - - [30/Jun/2022:16:43:51 +0300] \"GET / HTTP/1.0\" 200 11228",
  215. /* [7] Apache csvCommon 2 - with carriage return */
  216. "180.89.137.89 - barrows1527 [05/Jun/2023:17:46:08 +0000]\
  217. \"DELETE /b2c/viral/innovative/reintermediate HTTP/1.0\" 416 99\r",
  218. /* [8] Apache csvCommon 3 - with new line */
  219. "212.113.230.101 - - [20/Jun/2023:14:29:49 +0000] \"PATCH /strategic HTTP/1.1\" 404 1217\n",
  220. /* [9] Apache csvVhostCommon 1 */
  221. "XPS-wsl.localdomain:80 127.0.0.1 - - [30/Jun/2022:16:43:51 +0300] \"GET / HTTP/1.0\" 200 11228",
  222. /* [10] Apache csvVhostCommon 2 - with new line and extra white space */
  223. "XPS-wsl.localdomain:80 2001:0db8:85a3:0000:0000:8a2e:0370:7334 - - [30/Jun/2022:16:43:51 +0300] \"GET /\
  224. HTTP/1.0\" 200 11228\n",
  225. /* [11] Nginx csvCombined */
  226. "47.29.201.179 - - [28/Feb/2019:13:17:10 +0000] \"GET /?p=1 HTTP/2.0\" 200 5316 \"https://dot.com/?p=1\"\
  227. \"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36\"",
  228. };
  229. const web_log_line_field_t parse_config_expected[][15] = {
  230. /* [1] */ {REQ_CLIENT , CUSTOM , CUSTOM, TIME , TIME, REQ , RESP_CODE, RESP_SIZE, CUSTOM , CUSTOM , -1, -1, -1, -1, -1}, /* Apache csvCombined 1 */
  231. /* [2] */ {REQ_CLIENT , CUSTOM , CUSTOM, TIME , TIME, REQ , RESP_CODE, RESP_SIZE, CUSTOM , CUSTOM , -1, -1, -1, -1, -1}, /* Apache csvCombined 2 */
  232. /* [3] */ {REQ_CLIENT , CUSTOM , CUSTOM, TIME , TIME, REQ , RESP_CODE, RESP_SIZE, CUSTOM , CUSTOM , -1, -1, -1, -1, -1}, /* Apache csvCombined 3 */
  233. /* [4] */ {REQ_CLIENT , CUSTOM , CUSTOM, TIME , TIME, REQ , RESP_CODE, RESP_SIZE, CUSTOM , CUSTOM , -1, -1, -1, -1, -1}, /* Apache csvCombined 4 */
  234. /* [5] */ {VHOST_WITH_PORT, REQ_CLIENT, CUSTOM, CUSTOM, TIME, TIME, REQ , RESP_CODE, RESP_SIZE, CUSTOM , CUSTOM, -1, -1, -1, -1}, /* Apache csvVhostCombined */
  235. /* [6] */ {REQ_CLIENT , CUSTOM , CUSTOM, TIME , TIME, REQ , RESP_CODE, RESP_SIZE, -1 , -1 , -1, -1, -1, -1, -1}, /* Apache csvCommon 1 */
  236. /* [7] */ {REQ_CLIENT , CUSTOM , CUSTOM, TIME , TIME, REQ , RESP_CODE, RESP_SIZE, -1 , -1 , -1, -1, -1, -1, -1}, /* Apache csvCommon 2 */
  237. /* [8] */ {REQ_CLIENT , CUSTOM , CUSTOM, TIME , TIME, REQ , RESP_CODE, RESP_SIZE, -1 , -1 , -1, -1, -1, -1, -1}, /* Apache csvCommon 3 */
  238. /* [9] */ {VHOST_WITH_PORT, REQ_CLIENT, CUSTOM, CUSTOM, TIME, TIME, REQ , RESP_CODE, RESP_SIZE, -1 , -1, -1, -1, -1, -1}, /* Apache csvVhostCommon 1 */
  239. /* [10] */ {VHOST_WITH_PORT, REQ_CLIENT, CUSTOM, CUSTOM, TIME, TIME, REQ , RESP_CODE, RESP_SIZE, -1 , -1, -1, -1, -1, -1}, /* Apache csvVhostCommon 2 */
  240. /* [11] */ {REQ_CLIENT , CUSTOM , CUSTOM, TIME , TIME, REQ, RESP_CODE, RESP_SIZE, CUSTOM , CUSTOM , -1, -1, -1, -1, -1}, /* Nginx csvCombined */
  241. };
  242. static const char parse_config_delim = ' ';
  243. static int *parse_config_expected_num_fields = NULL;
  244. static void setup_parse_config_expected_num_fields() {
  245. fprintf(stderr, "%s():\n", __FUNCTION__);
  246. for(int i = 0; i < (int) (sizeof(parse_configs_to_test) / sizeof(parse_configs_to_test[0])); i++){
  247. parse_config_expected_num_fields = reallocz(parse_config_expected_num_fields, (i + 1) * sizeof(int));
  248. parse_config_expected_num_fields[i] = 0;
  249. for(int j = 0; (int) parse_config_expected[i][j] != -1; j++){
  250. parse_config_expected_num_fields[i]++;
  251. }
  252. }
  253. fprintf(stderr, "OK\n");
  254. }
  255. static int test_count_fields() {
  256. int errors = 0;
  257. fprintf(stderr, "%s():\n", __FUNCTION__);
  258. for(int i = 0; i < (int) (sizeof(parse_configs_to_test) / sizeof(parse_configs_to_test[0])); i++){
  259. if(count_fields(parse_configs_to_test[i], parse_config_delim) != parse_config_expected_num_fields[i]){
  260. fprintf(stderr, "- Error (count_fields() result incorrect) for:\n%s", parse_configs_to_test[i]);
  261. ++errors;
  262. }
  263. }
  264. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  265. return errors;
  266. }
  267. static int test_auto_detect_web_log_parser_config() {
  268. int errors = 0;
  269. fprintf(stderr, "%s():\n", __FUNCTION__);
  270. for(int i = 0; i < (int) (sizeof(parse_configs_to_test) / sizeof(parse_configs_to_test[0])); i++){
  271. size_t line_sz = strlen(parse_configs_to_test[i]) + 1;
  272. char *line = strdupz(parse_configs_to_test[i]);
  273. if(line[line_sz - 2] != '\n' && line[line_sz - 2] != '\r'){
  274. line = reallocz(line, ++line_sz); // +1 to add '\n' char
  275. line[line_sz - 1] = '\0';
  276. line[line_sz - 2] = '\n';
  277. }
  278. Web_log_parser_config_t *wblp_conf = auto_detect_web_log_parser_config(line, parse_config_delim);
  279. if(!wblp_conf){
  280. fprintf(stderr, "- Error (NULL wblp_conf) for:\n%s", line);
  281. ++errors;
  282. } else if(wblp_conf->num_fields != parse_config_expected_num_fields[i]){
  283. fprintf(stderr, "- Error (number of fields mismatch) for:\n%s", line);
  284. fprintf(stderr, "Expected %d fields but auto-detected %d\n", parse_config_expected_num_fields[i], wblp_conf->num_fields);
  285. ++errors;
  286. } else {
  287. for(int j = 0; (int) parse_config_expected[i][j] != -1; j++){
  288. if(wblp_conf->fields[j] != parse_config_expected[i][j]){
  289. fprintf(stderr, "- Error (field type mismatch) for:\n%s", line);
  290. ++errors;
  291. break;
  292. }
  293. }
  294. }
  295. freez(line);
  296. if(wblp_conf) freez(wblp_conf->fields);
  297. freez(wblp_conf);
  298. }
  299. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  300. return errors;
  301. }
  302. Log_line_parsed_t log_line_parsed_expected[] = {
  303. /* --------------------------------------
  304. char vhost[VHOST_MAX_LEN];
  305. int port;
  306. char req_scheme[REQ_SCHEME_MAX_LEN];
  307. char req_client[REQ_CLIENT_MAX_LEN];
  308. char req_method[REQ_METHOD_MAX_LEN];
  309. char req_URL[REQ_URL_MAX_LEN];
  310. char req_proto[REQ_PROTO_MAX_LEN];
  311. int req_size;
  312. int req_proc_time;
  313. int resp_code;
  314. int resp_size;
  315. int ups_resp_time;
  316. char ssl_proto[SSL_PROTO_MAX_LEN];
  317. char ssl_cipher[SSL_CIPHER_SUITE_MAX_LEN];
  318. int64_t timestamp;
  319. int parsing_errors;
  320. ------------------------------------------ */
  321. /* [1] */ {"", 0, "", "127.0.0.1", "GET", "/", "1.0", 0, 0, 200, 11228, 0, "", "", 1602762231, 0},
  322. /* [2] */ {"", 0, "", "::1", "GET", "/", "1.1", 0, 0, 200, 3477 , 0, "", "", 1662055482, 0},
  323. /* [3] */ {"", 0, "", "209.202.252.202", "PUT", "/harness/networks/initiatives/engineer", "2.0", 0, 0, 403, 42410, 0, "", "", 1687272147, 0},
  324. /* [4] */ {"", 0, "", "::1", "-", "", "", 0, 0, 408, 0, 0, "", "", 1689278456, 0},
  325. /* [5] */ {"XPS-wsl.localdomain", 80, "", "::1", "GET", "/", "1.1", 0, 0, 200, 3477 , 0, "", "", 1656611969, 0},
  326. /* [6] */ {"", 0, "", "127.0.0.1", "GET", "/", "1.0", 0, 0, 200, 11228, 0, "", "", 1656596631, 0},
  327. /* [7] */ {"", 0, "", "180.89.137.89", "DELETE", "/b2c/viral/innovative/reintermediate", "1.0", 0, 0, 416, 99 , 0, "", "", 1685987168, 0},
  328. /* [8] */ {"", 0, "", "212.113.230.101", "PATCH", "/strategic", "1.1", 0, 0, 404, 1217 , 0, "", "", 1687271389, 0},
  329. /* [9] */ {"XPS-wsl.localdomain", 80, "", "127.0.0.1", "GET", "/", "1.0", 0, 0, 200, 11228, 0, "", "", 1656596631, 0},
  330. /* [10] */ {"XPS-wsl.localdomain", 80, "", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "GET", "/", "1.0", 0, 0, 200, 11228, 0, "", "", 1656596631, 0},
  331. /* [11] */ {"", 0, "", "47.29.201.179", "GET", "/?p=1", "2.0", 0, 0, 200, 5316 , 0, "", "", 1551359830, 0}
  332. };
  333. static int test_parse_web_log_line(){
  334. int errors = 0;
  335. fprintf(stderr, "%s():\n", __FUNCTION__);
  336. Web_log_parser_config_t *wblp_conf = callocz(1, sizeof(Web_log_parser_config_t));
  337. wblp_conf->delimiter = parse_config_delim;
  338. wblp_conf->verify_parsed_logs = 1;
  339. for(int i = 0; i < (int) (sizeof(parse_configs_to_test) / sizeof(parse_configs_to_test[0])); i++){
  340. wblp_conf->num_fields = parse_config_expected_num_fields[i];
  341. wblp_conf->fields = (web_log_line_field_t *) parse_config_expected[i];
  342. Log_line_parsed_t log_line_parsed = (Log_line_parsed_t) {0};
  343. parse_web_log_line( wblp_conf,
  344. (char *) parse_configs_to_test[i],
  345. strlen(parse_configs_to_test[i]),
  346. &log_line_parsed);
  347. if(strcmp(log_line_parsed_expected[i].vhost, log_line_parsed.vhost))
  348. fprintf(stderr, "- Error (parsed vhost:%s != expected vhost:%s) for:\n%s",
  349. log_line_parsed.vhost, log_line_parsed_expected[i].vhost, parse_configs_to_test[i]), ++errors;
  350. if(log_line_parsed_expected[i].port != log_line_parsed.port)
  351. fprintf(stderr, "- Error (parsed port:%d != expected port:%d) for:\n%s",
  352. log_line_parsed.port, log_line_parsed_expected[i].port, parse_configs_to_test[i]), ++errors;
  353. if(strcmp(log_line_parsed_expected[i].req_scheme, log_line_parsed.req_scheme))
  354. fprintf(stderr, "- Error (parsed req_scheme:%s != expected req_scheme:%s) for:\n%s",
  355. log_line_parsed.req_scheme, log_line_parsed_expected[i].req_scheme, parse_configs_to_test[i]), ++errors;
  356. if(strcmp(log_line_parsed_expected[i].req_client, log_line_parsed.req_client))
  357. fprintf(stderr, "- Error (parsed req_client:%s != expected req_client:%s) for:\n%s",
  358. log_line_parsed.req_client, log_line_parsed_expected[i].req_client, parse_configs_to_test[i]), ++errors;
  359. if(strcmp(log_line_parsed_expected[i].req_method, log_line_parsed.req_method))
  360. fprintf(stderr, "- Error (parsed req_method:%s != expected req_method:%s) for:\n%s",
  361. log_line_parsed.req_method, log_line_parsed_expected[i].req_method, parse_configs_to_test[i]), ++errors;
  362. if(strcmp(log_line_parsed_expected[i].req_URL, log_line_parsed.req_URL))
  363. fprintf(stderr, "- Error (parsed req_URL:%s != expected req_URL:%s) for:\n%s",
  364. log_line_parsed.req_URL, log_line_parsed_expected[i].req_URL, parse_configs_to_test[i]), ++errors;
  365. if(strcmp(log_line_parsed_expected[i].req_proto, log_line_parsed.req_proto))
  366. fprintf(stderr, "- Error (parsed req_proto:%s != expected req_proto:%s) for:\n%s",
  367. log_line_parsed.req_proto, log_line_parsed_expected[i].req_proto, parse_configs_to_test[i]), ++errors;
  368. if(log_line_parsed_expected[i].req_size != log_line_parsed.req_size)
  369. fprintf(stderr, "- Error (parsed req_size:%d != expected req_size:%d) for:\n%s",
  370. log_line_parsed.req_size, log_line_parsed_expected[i].req_size, parse_configs_to_test[i]), ++errors;
  371. if(log_line_parsed_expected[i].req_proc_time != log_line_parsed.req_proc_time)
  372. fprintf(stderr, "- Error (parsed req_proc_time:%d != expected req_proc_time:%d) for:\n%s",
  373. log_line_parsed.req_proc_time, log_line_parsed_expected[i].req_proc_time, parse_configs_to_test[i]), ++errors;
  374. if(log_line_parsed_expected[i].resp_code != log_line_parsed.resp_code)
  375. fprintf(stderr, "- Error (parsed resp_code:%d != expected resp_code:%d) for:\n%s",
  376. log_line_parsed.resp_code, log_line_parsed_expected[i].resp_code, parse_configs_to_test[i]), ++errors;
  377. if(log_line_parsed_expected[i].resp_size != log_line_parsed.resp_size)
  378. fprintf(stderr, "- Error (parsed resp_size:%d != expected resp_size:%d) for:\n%s",
  379. log_line_parsed.resp_size, log_line_parsed_expected[i].resp_size, parse_configs_to_test[i]), ++errors;
  380. if(log_line_parsed_expected[i].ups_resp_time != log_line_parsed.ups_resp_time)
  381. fprintf(stderr, "- Error (parsed ups_resp_time:%d != expected ups_resp_time:%d) for:\n%s",
  382. log_line_parsed.ups_resp_time, log_line_parsed_expected[i].ups_resp_time, parse_configs_to_test[i]), ++errors;
  383. if(strcmp(log_line_parsed_expected[i].ssl_proto, log_line_parsed.ssl_proto))
  384. fprintf(stderr, "- Error (parsed ssl_proto:%s != expected ssl_proto:%s) for:\n%s",
  385. log_line_parsed.ssl_proto, log_line_parsed_expected[i].ssl_proto, parse_configs_to_test[i]), ++errors;
  386. if(strcmp(log_line_parsed_expected[i].ssl_cipher, log_line_parsed.ssl_cipher))
  387. fprintf(stderr, "- Error (parsed ssl_cipher:%s != expected ssl_cipher:%s) for:\n%s",
  388. log_line_parsed.ssl_cipher, log_line_parsed_expected[i].ssl_cipher, parse_configs_to_test[i]), ++errors;
  389. if(log_line_parsed_expected[i].timestamp != log_line_parsed.timestamp)
  390. fprintf(stderr, "- Error (parsed timestamp:%" PRId64 " != expected timestamp:%" PRId64 ") for:\n%s",
  391. log_line_parsed.timestamp, log_line_parsed_expected[i].timestamp, parse_configs_to_test[i]), ++errors;
  392. }
  393. freez(wblp_conf);
  394. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  395. return errors ;
  396. }
  397. const char * const unsanitised_strings[] = { "[test]", "^test$", "{test}",
  398. "(test)", "\\test\\", "test*+.?|", "test&£@"};
  399. const char * const expected_sanitised_strings[] = { "\\[test\\]", "\\^test\\$", "\\{test\\}",
  400. "\\(test\\)", "\\\\test\\\\", "test\\*\\+\\.\\?\\|", "test&£@"};
  401. static int test_sanitise_string(){
  402. int errors = 0;
  403. fprintf(stderr, "%s():\n", __FUNCTION__);
  404. for(int i = 0; i < (int) (sizeof(unsanitised_strings) / sizeof(unsanitised_strings[0])); i++){
  405. char *sanitised = sanitise_string((char *) unsanitised_strings[i]);
  406. if(strcmp(expected_sanitised_strings[i], sanitised)){
  407. fprintf(stderr, "- Error during sanitise_string() for:%s\n", unsanitised_strings[i]);
  408. ++errors;
  409. };
  410. freez(sanitised);
  411. }
  412. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  413. return errors;
  414. }
  415. char * const regex_src[] = {
  416. "2022-11-07T11:28:27.427519600Z container create e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (image=hello-world, name=xenodochial_lumiere)\n\
  417. 2022-11-07T11:28:27.932624500Z container start e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (image=hello-world, name=xenodochial_lumiere)\n\
  418. 2022-11-07T11:28:27.971060500Z container die e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (exitCode=0, image=hello-world, name=xenodochial_lumiere)",
  419. "2022-11-07T11:28:27.427519600Z container create e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (image=hello-world, name=xenodochial_lumiere)\n\
  420. 2022-11-07T11:28:27.932624500Z container start e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (image=hello-world, name=xenodochial_lumiere)\n\
  421. 2022-11-07T11:28:27.971060500Z container die e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (exitCode=0, image=hello-world, name=xenodochial_lumiere)",
  422. "2022-11-07T11:28:27.427519600Z container create e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (image=hello-world, name=xenodochial_lumiere)\n\
  423. 2022-11-07T11:28:27.932624500Z container start e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (image=hello-world, name=xenodochial_lumiere)\n\
  424. 2022-11-07T11:28:27.971060500Z container die e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (exitCode=0, image=hello-world, name=xenodochial_lumiere)",
  425. "2022-11-07T20:06:36.919980700Z container create bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234 (image=hello-world, name=distracted_sinoussi)\n\
  426. 2022-11-07T20:06:36.927728700Z container attach bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234 (image=hello-world, name=distracted_sinoussi)\n\
  427. 2022-11-07T20:06:36.958906200Z network connect 178a1988c4173559c721d5e24970eef32aaca41e0e363ff9792c731f917683ed (container=bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234, name=bridge, type=bridge)\n\
  428. 2022-11-07T20:06:37.564947300Z container start bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234 (image=hello-world, name=distracted_sinoussi)\n\
  429. 2022-11-07T20:06:37.596428500Z container die bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234 (exitCode=0, image=hello-world, name=distracted_sinoussi)\n\
  430. 2022-11-07T20:06:38.134325100Z network disconnect 178a1988c4173559c721d5e24970eef32aaca41e0e363ff9792c731f917683ed (container=bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234, name=bridge, type=bridge)",
  431. "Nov 7 21:54:24 X-PC sudo: john : TTY=pts/7 ; PWD=/home/john ; USER=root ; COMMAND=/usr/bin/docker run hello-world\n\
  432. Nov 7 21:54:24 X-PC sudo: pam_unix(sudo:session): session opened for user root by john(uid=0)\n\
  433. Nov 7 21:54:25 X-PC sudo: pam_unix(sudo:session): session closed for user root\n\
  434. Nov 7 21:54:24 X-PC sudo: john : TTY=pts/7 ; PWD=/home/john ; USER=root ; COMMAND=/usr/bin/docker run hello-world\n"
  435. };
  436. const char * const regex_keyword[] = {
  437. "start",
  438. "CONTAINER",
  439. "CONTAINER",
  440. NULL,
  441. NULL
  442. };
  443. const char * const regex_pat_str[] = {
  444. NULL,
  445. NULL,
  446. NULL,
  447. ".*\\bcontainer\\b.*\\bhello-world\\b.*",
  448. ".*\\bsudo\\b.*\\bCOMMAND=/usr/bin/docker run\\b.*"
  449. };
  450. const int regex_ignore_case[] = {
  451. 1,
  452. 1,
  453. 0,
  454. 1,
  455. 1
  456. };
  457. const int regex_exp_matches[] = {
  458. 1,
  459. 3,
  460. 0,
  461. 4,
  462. 2
  463. };
  464. const char * const regex_exp_dst[] = {
  465. "2022-11-07T11:28:27.932624500Z container start e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (image=hello-world, name=xenodochial_lumiere)\n",
  466. "2022-11-07T11:28:27.427519600Z container create e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (image=hello-world, name=xenodochial_lumiere)\n\
  467. 2022-11-07T11:28:27.932624500Z container start e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (image=hello-world, name=xenodochial_lumiere)\n\
  468. 2022-11-07T11:28:27.971060500Z container die e0c3c6120c29beb393e4b92773c9aa60006747bddabd352b77bf0b4ad23747a7 (exitCode=0, image=hello-world, name=xenodochial_lumiere)",
  469. "",
  470. "2022-11-07T20:06:36.919980700Z container create bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234 (image=hello-world, name=distracted_sinoussi)\n\
  471. 2022-11-07T20:06:36.927728700Z container attach bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234 (image=hello-world, name=distracted_sinoussi)\n\
  472. 2022-11-07T20:06:37.564947300Z container start bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234 (image=hello-world, name=distracted_sinoussi)\n\
  473. 2022-11-07T20:06:37.596428500Z container die bd8d4a3338c3e9ab4ca555c6d869dc980f04f10ebdcd9284321c0afecbec1234 (exitCode=0, image=hello-world, name=distracted_sinoussi)",
  474. "Nov 7 21:54:24 X-PC sudo: john : TTY=pts/7 ; PWD=/home/john ; USER=root ; COMMAND=/usr/bin/docker run hello-world\n\
  475. Nov 7 21:54:24 X-PC sudo: john : TTY=pts/7 ; PWD=/home/john ; USER=root ; COMMAND=/usr/bin/docker run hello-world\n"
  476. };
  477. static int test_search_keyword(){
  478. int errors = 0;
  479. fprintf(stderr, "%s():\n", __FUNCTION__);
  480. for(int i = 0; i < (int) (sizeof(regex_src) / sizeof(regex_src[0])); i++){
  481. regex_t *regex_c = regex_pat_str[i] ? mallocz(sizeof(regex_t)) : NULL;
  482. if(regex_c && regcomp( regex_c, regex_pat_str[i],
  483. regex_ignore_case[i] ? REG_EXTENDED | REG_NEWLINE | REG_ICASE : REG_EXTENDED | REG_NEWLINE))
  484. fatal("Could not compile regular expression:%s", regex_pat_str[i]);
  485. size_t regex_src_sz = strlen(regex_src[i]) + 1;
  486. char *res = callocz(1 , regex_src_sz);
  487. size_t res_sz;
  488. int matches = search_keyword( regex_src[i], regex_src_sz,
  489. res, &res_sz,
  490. regex_keyword[i], regex_c,
  491. regex_ignore_case[i]);
  492. // fprintf(stderr, "\nMatches:%d\nResults:\n%.*s\n", matches, (int) res_sz, res);
  493. if(regex_exp_matches[i] != matches){
  494. fprintf(stderr, "- Error in matches returned from search_keyword() for: regex_src[%d]\n", i);
  495. ++errors;
  496. };
  497. if(strncmp(regex_exp_dst[i], res, res_sz - 1)){
  498. fprintf(stderr, "- Error in strncmp() of results from search_keyword() for: regex_src[%d]\n", i);
  499. ++errors;
  500. }
  501. if(regex_c) freez(regex_c);
  502. freez(res);
  503. }
  504. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  505. return errors;
  506. }
  507. static Flb_socket_config_t *p_forward_in_config = NULL;
  508. static flb_srvc_config_t flb_srvc_config = {
  509. .flush = FLB_FLUSH_DEFAULT,
  510. .http_listen = FLB_HTTP_LISTEN_DEFAULT,
  511. .http_port = FLB_HTTP_PORT_DEFAULT,
  512. .http_server = FLB_HTTP_SERVER_DEFAULT,
  513. .log_path = "NULL",
  514. .log_level = FLB_LOG_LEVEL_DEFAULT,
  515. .coro_stack_size = FLB_CORO_STACK_SIZE_DEFAULT
  516. };
  517. static flb_srvc_config_t *p_flb_srvc_config = NULL;
  518. static int test_logsmanag_config_funcs(){
  519. int errors = 0, rc;
  520. fprintf(stderr, "%s():\n", __FUNCTION__);
  521. fprintf(stderr, "Testing get_X_dir() functions...\n");
  522. if(NULL == get_user_config_dir()){
  523. fprintf(stderr, "- Error, get_user_config_dir() returns NULL.\n");
  524. ++errors;
  525. }
  526. if(NULL == get_stock_config_dir()){
  527. fprintf(stderr, "- Error, get_stock_config_dir() returns NULL.\n");
  528. ++errors;
  529. }
  530. if(NULL == get_log_dir()){
  531. fprintf(stderr, "- Error, get_log_dir() returns NULL.\n");
  532. ++errors;
  533. }
  534. if(NULL == get_cache_dir()){
  535. fprintf(stderr, "- Error, get_cache_dir() returns NULL.\n");
  536. ++errors;
  537. }
  538. fprintf(stderr, "Testing logs_manag_config_load() when p_flb_srvc_config is NULL...\n");
  539. SUPRESS_STDERR();
  540. rc = logs_manag_config_load(p_flb_srvc_config, &p_forward_in_config, 1);
  541. UNSUPRESS_STDERR();
  542. if(LOGS_MANAG_CONFIG_LOAD_ERROR_P_FLB_SRVC_NULL != rc){
  543. fprintf(stderr, "- Error, logs_manag_config_load() returns %d.\n", rc);
  544. ++errors;
  545. }
  546. p_flb_srvc_config = &flb_srvc_config;
  547. fprintf(stderr, "Testing logs_manag_config_load() can load stock config...\n");
  548. SUPRESS_STDERR();
  549. rc = logs_manag_config_load(&flb_srvc_config, &p_forward_in_config, 1);
  550. UNSUPRESS_STDERR();
  551. if( LOGS_MANAG_CONFIG_LOAD_ERROR_OK != rc){
  552. fprintf(stderr, "- Error, logs_manag_config_load() returns %d.\n", rc);
  553. ++errors;
  554. }
  555. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  556. return errors;
  557. }
  558. uv_loop_t *main_loop;
  559. static void setup_p_file_infos_arr_and_main_loop() {
  560. fprintf(stderr, "%s():\n", __FUNCTION__);
  561. p_file_infos_arr = callocz(1, sizeof(struct File_infos_arr));
  562. main_loop = mallocz(sizeof(uv_loop_t));
  563. if(uv_loop_init(main_loop))
  564. exit(EXIT_FAILURE);
  565. fprintf(stderr, "OK\n");
  566. }
  567. static int test_flb_init(){
  568. int errors = 0, rc;
  569. fprintf(stderr, "%s():\n", __FUNCTION__);
  570. fprintf(stderr, "Testing flb_init() with wrong stock_config_dir...\n");
  571. SUPRESS_STDERR();
  572. rc = flb_init(flb_srvc_config, "/tmp", "example_prefix_");
  573. UNSUPRESS_STDERR();
  574. if(!rc){
  575. fprintf(stderr, "- Error, flb_init() should fail but it returns %d.\n", rc);
  576. ++errors;
  577. }
  578. fprintf(stderr, "Testing flb_init() with correct stock_config_dir...\n");
  579. rc = flb_init(flb_srvc_config, get_stock_config_dir(), "example_prefix_");
  580. if(rc){
  581. fprintf(stderr, "- Error, flb_init() should fail but it returns %d.\n", rc);
  582. ++errors;
  583. }
  584. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  585. return errors;
  586. }
  587. static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf){
  588. UNUSED(sb);
  589. UNUSED(typeflag);
  590. UNUSED(ftwbuf);
  591. return remove(fpath);
  592. }
  593. static int test_db_init(){
  594. int errors = 0;
  595. fprintf(stderr, "%s():\n", __FUNCTION__);
  596. extern netdata_mutex_t stdout_mut;
  597. SUPRESS_STDOUT();
  598. SUPRESS_STDERR();
  599. config_file_load(main_loop, p_forward_in_config, &flb_srvc_config, &stdout_mut);
  600. UNSUPRESS_STDOUT();
  601. UNSUPRESS_STDERR();
  602. fprintf(stderr, "Testing db_init() with main_db_dir == NULL...\n");
  603. SUPRESS_STDERR();
  604. db_set_main_dir(NULL);
  605. int rc = db_init();
  606. UNSUPRESS_STDERR();
  607. if(!rc){
  608. fprintf(stderr, "- Error, db_init() returns %d even though db_set_main_dir(NULL); was called.\n", rc);
  609. ++errors;
  610. }
  611. char tmpdir[] = "/tmp/tmpdir.XXXXXX";
  612. char *main_db_dir = mkdtemp (tmpdir);
  613. fprintf(stderr, "Testing db_init() with main_db_dir == %s...\n", main_db_dir);
  614. SUPRESS_STDERR();
  615. db_set_main_dir(main_db_dir);
  616. rc = db_init();
  617. UNSUPRESS_STDERR();
  618. if(rc){
  619. fprintf(stderr, "- Error, db_init() returns %d.\n", rc);
  620. ++errors;
  621. }
  622. fprintf(stderr, "Cleaning up %s...\n", main_db_dir);
  623. if(nftw(main_db_dir, unlink_cb, 64, FTW_DEPTH | FTW_PHYS) == -1){
  624. fprintf(stderr, "Error while remove path:%s. Will exit...\n", strerror(errno));
  625. exit(EXIT_FAILURE);
  626. }
  627. fprintf(stderr, "%s\n", errors ? "FAIL" : "OK");
  628. return errors;
  629. }
  630. int logs_management_unittest(void){
  631. int errors = 0;
  632. fprintf(stderr, "\n\n======================================================\n");
  633. fprintf(stderr, " ** Starting logs management tests **\n");
  634. fprintf(stderr, "======================================================\n");
  635. fprintf(stderr, "------------------------------------------------------\n");
  636. errors += test_compression_decompression();
  637. fprintf(stderr, "------------------------------------------------------\n");
  638. errors += test_read_last_line();
  639. fprintf(stderr, "------------------------------------------------------\n");
  640. setup_parse_config_expected_num_fields();
  641. fprintf(stderr, "------------------------------------------------------\n");
  642. errors += test_count_fields();
  643. fprintf(stderr, "------------------------------------------------------\n");
  644. errors += test_auto_detect_web_log_parser_config();
  645. fprintf(stderr, "------------------------------------------------------\n");
  646. errors += test_parse_web_log_line();
  647. fprintf(stderr, "------------------------------------------------------\n");
  648. errors += test_sanitise_string();
  649. fprintf(stderr, "------------------------------------------------------\n");
  650. errors += test_search_keyword();
  651. fprintf(stderr, "------------------------------------------------------\n");
  652. errors += test_logsmanag_config_funcs();
  653. fprintf(stderr, "------------------------------------------------------\n");
  654. setup_p_file_infos_arr_and_main_loop();
  655. fprintf(stderr, "------------------------------------------------------\n");
  656. errors += test_flb_init();
  657. fprintf(stderr, "------------------------------------------------------\n");
  658. errors += test_db_init();
  659. fprintf(stderr, "------------------------------------------------------\n");
  660. fprintf(stderr, "[%s] Total errors: %d\n", errors ? "FAILED" : "SUCCEEDED", errors);
  661. fprintf(stderr, "======================================================\n");
  662. fprintf(stderr, " ** Finished logs management tests **\n");
  663. fprintf(stderr, "======================================================\n");
  664. fflush(stderr);
  665. return errors;
  666. }