/** * collectd - src/logparser_test.c * * Copyright(c) 2018 Intel Corporation. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Marcin Mozejko * Adrian Boczkowski **/ #include "logparser.c" #include "testing.h" DEF_TEST(init) { logparser_ctx.parsers_len = 3; logparser_ctx.parsers = calloc(3, sizeof(log_parser_t)); logparser_ctx.parsers[0].filename = "test_filename0"; logparser_ctx.parsers[0].patterns_len = 3; logparser_ctx.parsers[0].patterns = calloc(3, sizeof(message_pattern_t)); logparser_ctx.parsers[0].patterns[0].regex = "test_regex00"; logparser_ctx.parsers[0].patterns[0].excluderegex = "exclude_regex00"; logparser_ctx.parsers[0].patterns[0].is_mandatory = true; logparser_ctx.parsers[0].patterns[0].submatch_idx = 1; logparser_ctx.parsers[0].patterns[0].name = "test_name00"; logparser_ctx.parsers[0].patterns[1].regex = "test_regex01"; logparser_ctx.parsers[0].patterns[1].excluderegex = "exclude_regex01"; logparser_ctx.parsers[0].patterns[1].is_mandatory = true; logparser_ctx.parsers[0].patterns[1].submatch_idx = 1; logparser_ctx.parsers[0].patterns[1].name = "test_name01"; logparser_ctx.parsers[0].patterns[2].regex = "test_regex02"; logparser_ctx.parsers[0].patterns[2].excluderegex = "exclude_regex02"; logparser_ctx.parsers[0].patterns[2].is_mandatory = true; logparser_ctx.parsers[0].patterns[2].submatch_idx = 1; logparser_ctx.parsers[0].patterns[2].name = "test_name02"; logparser_ctx.parsers[1].filename = "test_filename1"; logparser_ctx.parsers[1].patterns_len = 3; logparser_ctx.parsers[1].patterns = calloc(3, sizeof(message_pattern_t)); logparser_ctx.parsers[1].patterns[0].regex = "test_regex10"; logparser_ctx.parsers[1].patterns[0].excluderegex = "exclude_regex10"; logparser_ctx.parsers[1].patterns[0].is_mandatory = true; logparser_ctx.parsers[1].patterns[0].submatch_idx = 1; logparser_ctx.parsers[1].patterns[0].name = "test_name10"; logparser_ctx.parsers[1].patterns[1].regex = "test_regex11"; logparser_ctx.parsers[1].patterns[1].excluderegex = "exclude_regex11"; logparser_ctx.parsers[1].patterns[1].is_mandatory = true; logparser_ctx.parsers[1].patterns[1].submatch_idx = 1; logparser_ctx.parsers[1].patterns[1].name = "test_name11"; logparser_ctx.parsers[1].patterns[2].regex = "test_regex12"; logparser_ctx.parsers[1].patterns[2].excluderegex = "exclude_regex12"; logparser_ctx.parsers[1].patterns[2].is_mandatory = true; logparser_ctx.parsers[1].patterns[2].submatch_idx = 1; logparser_ctx.parsers[1].patterns[2].name = "test_name12"; logparser_ctx.parsers[2].filename = "test_filename2"; logparser_ctx.parsers[2].patterns_len = 3; logparser_ctx.parsers[2].patterns = calloc(3, sizeof(message_pattern_t)); logparser_ctx.parsers[2].patterns[0].regex = "test_regex20"; logparser_ctx.parsers[2].patterns[0].excluderegex = "exclude_regex20"; logparser_ctx.parsers[2].patterns[0].is_mandatory = true; logparser_ctx.parsers[2].patterns[0].submatch_idx = 1; logparser_ctx.parsers[2].patterns[0].name = "test_name20"; logparser_ctx.parsers[2].patterns[1].regex = "test_regex21"; logparser_ctx.parsers[2].patterns[1].excluderegex = "exclude_regex21"; logparser_ctx.parsers[2].patterns[1].is_mandatory = true; logparser_ctx.parsers[2].patterns[1].submatch_idx = 1; logparser_ctx.parsers[2].patterns[1].name = "test_name21"; logparser_ctx.parsers[2].patterns[2].regex = "test_regex22"; logparser_ctx.parsers[2].patterns[2].excluderegex = "exclude_regex22"; logparser_ctx.parsers[2].patterns[2].is_mandatory = true; logparser_ctx.parsers[2].patterns[2].submatch_idx = 1; logparser_ctx.parsers[2].patterns[2].name = "test_name22"; int ret = logparser_init(); sfree(logparser_ctx.parsers[0].patterns); sfree(logparser_ctx.parsers[1].patterns); sfree(logparser_ctx.parsers[2].patterns); message_parser_cleanup(logparser_ctx.parsers[0].job); message_parser_cleanup(logparser_ctx.parsers[1].job); message_parser_cleanup(logparser_ctx.parsers[2].job); sfree(logparser_ctx.parsers); logparser_ctx.parsers_len = 0; EXPECT_EQ_INT(0, ret); return 0; } DEF_TEST(free_user_data) { message_item_user_data_t *user_data = calloc(1, sizeof(*user_data)); user_data->infos_len = 4; user_data->infos[0].type = MSG_ITEM_SEVERITY; user_data->infos[0].val.severity = NOTIF_OKAY; user_data->infos[1].type = MSG_ITEM_PLUGIN_INST; user_data->infos[1].val.str_override = strdup("test_plugin_inst"); user_data->infos[2].type = MSG_ITEM_TYPE; user_data->infos[2].val.str_override = strdup("test_type"); user_data->infos[3].type = MSG_ITEM_TYPE_INST; user_data->infos[3].val.str_override = strdup("test_type_inst"); logparser_free_user_data(user_data); return 0; } DEF_TEST(config_logfile) { oconfig_item_t *logfile_ci = calloc(1, sizeof(*logfile_ci)); assert(logfile_ci != NULL); logfile_ci->key = "Logfile"; logfile_ci->values_num = 1; logfile_ci->values = calloc(logfile_ci->values_num, sizeof(*logfile_ci->values)); assert(logfile_ci->values != NULL); logfile_ci->values->type = OCONFIG_TYPE_STRING; logfile_ci->values->value.string = "/path/to/a/file"; logfile_ci->children_num = 2; logfile_ci->children = calloc(logfile_ci->children_num, sizeof(*logfile_ci->children)); assert(logfile_ci->children != NULL); oconfig_item_t *first_full_read_ci = &logfile_ci->children[0]; first_full_read_ci->key = "FirstFullRead"; first_full_read_ci->values_num = 1; first_full_read_ci->values = calloc(first_full_read_ci->values_num, sizeof(*first_full_read_ci->values)); assert(first_full_read_ci->values != NULL); first_full_read_ci->values->type = OCONFIG_TYPE_BOOLEAN; first_full_read_ci->values->value.boolean = true; oconfig_item_t *msg_ci = &logfile_ci->children[1]; msg_ci->key = "Message"; msg_ci->values_num = 1; msg_ci->values = calloc(msg_ci->values_num, sizeof(*msg_ci->values)); assert(msg_ci->values != NULL); msg_ci->values->type = OCONFIG_TYPE_STRING; msg_ci->values->value.string = "msg-name"; msg_ci->children_num = 6; msg_ci->children = calloc(msg_ci->children_num, sizeof(*msg_ci->children)); assert(msg_ci->children != NULL); oconfig_item_t *def_plugin_inst_ci = &msg_ci->children[0]; def_plugin_inst_ci->key = "DefaultPluginInstance"; def_plugin_inst_ci->values_num = 1; def_plugin_inst_ci->values = calloc(def_plugin_inst_ci->values_num, sizeof(*def_plugin_inst_ci->values)); assert(def_plugin_inst_ci->values != NULL); def_plugin_inst_ci->values->type = OCONFIG_TYPE_STRING; def_plugin_inst_ci->values->value.string = "test_default_plugin_instance_1"; oconfig_item_t *def_type_ci = &msg_ci->children[1]; def_type_ci->key = "DefaultType"; def_type_ci->values_num = 1; def_type_ci->values = calloc(def_type_ci->values_num, sizeof(*def_type_ci->values)); assert(def_type_ci->values != NULL); def_type_ci->values->type = OCONFIG_TYPE_STRING; def_type_ci->values->value.string = "test_default_type_1"; oconfig_item_t *def_type_inst_ci = &msg_ci->children[2]; def_type_inst_ci->key = "DefaultTypeInstance"; def_type_inst_ci->values_num = 1; def_type_inst_ci->values = calloc(def_type_inst_ci->values_num, sizeof(*def_type_inst_ci->values)); assert(def_type_inst_ci->values != NULL); def_type_inst_ci->values->type = OCONFIG_TYPE_STRING; def_type_inst_ci->values->value.string = "test_default_type_instance_1"; oconfig_item_t *def_severity_ci = &msg_ci->children[3]; def_severity_ci->key = "DefaultSeverity"; def_severity_ci->values_num = 1; def_severity_ci->values = calloc(def_severity_ci->values_num, sizeof(*def_severity_ci->values)); assert(def_severity_ci->values != NULL); def_severity_ci->values->type = OCONFIG_TYPE_STRING; def_severity_ci->values->value.string = "OK"; oconfig_item_t *match1_ci = &msg_ci->children[4]; assert(match1_ci != NULL); match1_ci->key = "Match"; match1_ci->values_num = 1; match1_ci->values = calloc(match1_ci->values_num, sizeof(*match1_ci->values)); assert(match1_ci->values != NULL); match1_ci->values->type = OCONFIG_TYPE_STRING; match1_ci->values->value.string = "test_match_1"; match1_ci->children_num = 6; match1_ci->children = calloc(match1_ci->children_num, sizeof(*match1_ci->children)); assert(match1_ci->children != NULL); oconfig_item_t *regex1_ci = &match1_ci->children[0]; regex1_ci->key = "Regex"; regex1_ci->values_num = 1; regex1_ci->values = calloc(regex1_ci->values_num, sizeof(*regex1_ci->values)); assert(regex1_ci->values != NULL); regex1_ci->values->type = OCONFIG_TYPE_STRING; regex1_ci->values->value.string = "test_regex_1"; oconfig_item_t *submatch_idx1_ci = &match1_ci->children[1]; submatch_idx1_ci->key = "SubmatchIdx"; submatch_idx1_ci->values_num = 1; submatch_idx1_ci->values = calloc(submatch_idx1_ci->values_num, sizeof(*submatch_idx1_ci->values)); assert(submatch_idx1_ci->values != NULL); submatch_idx1_ci->values->type = OCONFIG_TYPE_NUMBER; submatch_idx1_ci->values->value.number = 15; oconfig_item_t *is_mandatory1_ci = &match1_ci->children[2]; is_mandatory1_ci->key = "IsMandatory"; is_mandatory1_ci->values_num = 1; is_mandatory1_ci->values = calloc(is_mandatory1_ci->values_num, sizeof(*is_mandatory1_ci->values)); assert(is_mandatory1_ci->values != NULL); is_mandatory1_ci->values->type = OCONFIG_TYPE_BOOLEAN; is_mandatory1_ci->values->value.boolean = false; oconfig_item_t *severity1_ci = &match1_ci->children[3]; severity1_ci->key = "Severity"; severity1_ci->values_num = 1; severity1_ci->values = calloc(severity1_ci->values_num, sizeof(*severity1_ci->values)); assert(severity1_ci->values != NULL); severity1_ci->values->type = OCONFIG_TYPE_STRING; severity1_ci->values->value.string = "failure"; oconfig_item_t *type_inst1_ci = &match1_ci->children[4]; type_inst1_ci->key = "TypeInstance"; type_inst1_ci->values_num = 1; type_inst1_ci->values = calloc(type_inst1_ci->values_num, sizeof(*type_inst1_ci->values)); assert(type_inst1_ci->values != NULL); type_inst1_ci->values->type = OCONFIG_TYPE_STRING; type_inst1_ci->values->value.string = "test_type_instance_1"; oconfig_item_t *plugin_inst1_ci = &match1_ci->children[5]; plugin_inst1_ci->key = "PluginInstance"; plugin_inst1_ci->values_num = 1; plugin_inst1_ci->values = calloc(plugin_inst1_ci->values_num, sizeof(*plugin_inst1_ci->values)); assert(plugin_inst1_ci->values != NULL); plugin_inst1_ci->values->type = OCONFIG_TYPE_STRING; plugin_inst1_ci->values->value.string = "test_plugin_instance_1"; oconfig_item_t *match2_ci = &msg_ci->children[5]; assert(match2_ci != NULL); match2_ci->key = "Match"; match2_ci->values_num = 1; match2_ci->values = calloc(match2_ci->values_num, sizeof(*match2_ci->values)); assert(match2_ci->values != NULL); match2_ci->values->type = OCONFIG_TYPE_STRING; match2_ci->values->value.string = "test_match_2"; match2_ci->children_num = 6; match2_ci->children = calloc(match2_ci->children_num, sizeof(*match2_ci->children)); assert(match2_ci->children != NULL); oconfig_item_t *regex2_ci = &match2_ci->children[0]; regex2_ci->key = "Regex"; regex2_ci->values_num = 1; regex2_ci->values = calloc(regex2_ci->values_num, sizeof(*regex2_ci->values)); assert(regex2_ci->values != NULL); regex2_ci->values->type = OCONFIG_TYPE_STRING; regex2_ci->values->value.string = "test_regex_2"; oconfig_item_t *submatch_idx2_ci = &match2_ci->children[1]; submatch_idx2_ci->key = "SubmatchIdx"; submatch_idx2_ci->values_num = 1; submatch_idx2_ci->values = calloc(submatch_idx2_ci->values_num, sizeof(*submatch_idx2_ci->values)); assert(submatch_idx2_ci->values != NULL); submatch_idx2_ci->values->type = OCONFIG_TYPE_NUMBER; submatch_idx2_ci->values->value.number = 8; oconfig_item_t *is_mandatory2_ci = &match2_ci->children[2]; is_mandatory2_ci->key = "IsMandatory"; is_mandatory2_ci->values_num = 1; is_mandatory2_ci->values = calloc(is_mandatory2_ci->values_num, sizeof(*is_mandatory2_ci->values)); assert(is_mandatory2_ci->values != NULL); is_mandatory2_ci->values->type = OCONFIG_TYPE_BOOLEAN; is_mandatory2_ci->values->value.boolean = true; oconfig_item_t *severity2_ci = &match2_ci->children[3]; severity2_ci->key = "Severity"; severity2_ci->values_num = 1; severity2_ci->values = calloc(severity2_ci->values_num, sizeof(*severity2_ci->values)); assert(severity2_ci->values != NULL); severity2_ci->values->type = OCONFIG_TYPE_STRING; severity2_ci->values->value.string = "warning"; oconfig_item_t *type_inst2_ci = &match2_ci->children[4]; type_inst2_ci->key = "TypeInstance"; type_inst2_ci->values_num = 1; type_inst2_ci->values = calloc(type_inst2_ci->values_num, sizeof(*type_inst2_ci->values)); assert(type_inst2_ci->values != NULL); type_inst2_ci->values->type = OCONFIG_TYPE_STRING; type_inst2_ci->values->value.string = "test_type_instance_2"; oconfig_item_t *plugin_inst2_ci = &match2_ci->children[5]; plugin_inst2_ci->key = "PluginInstance"; plugin_inst2_ci->values_num = 1; plugin_inst2_ci->values = calloc(plugin_inst2_ci->values_num, sizeof(*plugin_inst2_ci->values)); assert(plugin_inst2_ci->values != NULL); plugin_inst2_ci->values->type = OCONFIG_TYPE_STRING; plugin_inst2_ci->values->value.string = "test_plugin_instance_2"; int ret = logparser_config_logfile(logfile_ci); EXPECT_EQ_INT(0, ret); EXPECT_EQ_INT(1, logparser_ctx.parsers_len); log_parser_t *parser = &logparser_ctx.parsers[0]; EXPECT_EQ_INT(1, parser->first_read); EXPECT_EQ_STR("/path/to/a/file", parser->filename); EXPECT_EQ_STR("test_default_plugin_instance_1", parser->def_plugin_inst); EXPECT_EQ_INT(NOTIF_OKAY, parser->def_severity); EXPECT_EQ_STR("test_default_type_1", parser->def_type); EXPECT_EQ_STR("test_default_type_instance_1", parser->def_type_inst); EXPECT_EQ_INT(2, parser->patterns_len); message_pattern_t *pattern = &logparser_ctx.parsers[0].patterns[0]; EXPECT_EQ_STR("test_regex_1", pattern->regex); EXPECT_EQ_INT(0, pattern->is_mandatory); EXPECT_EQ_INT(15, pattern->submatch_idx); EXPECT_EQ_STR("test_match_1", pattern->name); message_item_user_data_t *user_data = pattern->user_data; EXPECT_EQ_INT(3, user_data->infos_len); for (size_t i = 0; i < user_data->infos_len; ++i) { switch (user_data->infos[i].type) { case MSG_ITEM_PLUGIN_INST: EXPECT_EQ_STR("test_plugin_instance_1", user_data->infos[i].val.str_override); break; case MSG_ITEM_TYPE_INST: EXPECT_EQ_STR("test_type_instance_1", user_data->infos[i].val.str_override); break; case MSG_ITEM_SEVERITY: EXPECT_EQ_INT(NOTIF_FAILURE, user_data->infos[i].val.severity); break; default: OK1(false, "Unknown message item"); } } pattern = &logparser_ctx.parsers[0].patterns[1]; EXPECT_EQ_STR("test_regex_2", pattern->regex); EXPECT_EQ_INT(1, pattern->is_mandatory); EXPECT_EQ_INT(8, pattern->submatch_idx); EXPECT_EQ_STR("test_match_2", pattern->name); user_data = pattern->user_data; EXPECT_EQ_INT(3, user_data->infos_len); for (size_t i = 0; i < user_data->infos_len; ++i) { switch (user_data->infos[i].type) { case MSG_ITEM_PLUGIN_INST: EXPECT_EQ_STR("test_plugin_instance_2", user_data->infos[i].val.str_override); break; case MSG_ITEM_TYPE_INST: EXPECT_EQ_STR("test_type_instance_2", user_data->infos[i].val.str_override); break; case MSG_ITEM_SEVERITY: EXPECT_EQ_INT(NOTIF_WARNING, user_data->infos[i].val.severity); break; default: OK1(false, "Unknown message item"); } } sfree(regex1_ci->values); sfree(submatch_idx1_ci->values); sfree(is_mandatory1_ci->values); sfree(severity1_ci->values); sfree(type_inst1_ci->values); sfree(plugin_inst1_ci->values); sfree(regex2_ci->values); sfree(submatch_idx2_ci->values); sfree(is_mandatory2_ci->values); sfree(severity2_ci->values); sfree(type_inst2_ci->values); sfree(plugin_inst2_ci->values); sfree(match2_ci->children); sfree(match2_ci->values); sfree(match1_ci->children); sfree(match1_ci->values); sfree(def_plugin_inst_ci->values); sfree(def_type_ci->values); sfree(def_type_inst_ci->values); sfree(def_severity_ci->values); sfree(msg_ci->children); sfree(msg_ci->values); sfree(first_full_read_ci->values); sfree(logfile_ci->children); sfree(logfile_ci->values); sfree(logfile_ci); logparser_shutdown(); return 0; } int main(void) { RUN_TEST(init); RUN_TEST(free_user_data); RUN_TEST(config_logfile); END_TEST; }