This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Neels Hofmeyr gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/5432 ctrl_test: expand to test message handling and detect mem leaks Subsequent patches that tighten CTRL input validation will make the results more interesting. Change-Id: Idd4cc7d193db1a7d761f72ed33ed46eea450a78f --- M tests/ctrl/ctrl_test.c M tests/ctrl/ctrl_test.ok 2 files changed, 198 insertions(+), 57 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/32/5432/1 diff --git a/tests/ctrl/ctrl_test.c b/tests/ctrl/ctrl_test.c index 2bc3128..b0266fc 100644 --- a/tests/ctrl/ctrl_test.c +++ b/tests/ctrl/ctrl_test.c @@ -9,6 +9,8 @@ #include <osmocom/core/logging.h> #include <osmocom/core/msgb.h> #include <osmocom/core/application.h> +#include <osmocom/gsm/protocol/ipaccess.h> +#include <osmocom/ctrl/control_if.h> static void check_type(enum ctrl_type c) { @@ -24,18 +26,34 @@ struct msgb *msgb_from_string(const char *str) { - char *rc; + struct ipaccess_head *iph; + struct ipaccess_head_ext *ipx; + char *str_msg; size_t len = strlen(str) + 1; - /* ctrl_cmd_parse() appends a '\0' to the msgb, allow one more byte. */ - struct msgb *msg = msgb_alloc(len + 1, str); - msg->l2h = msg->head; - rc = (char*)msgb_put(msg, len); - OSMO_ASSERT(rc == (char*)msg->l2h); - strcpy(rc, str); + + struct msgb *msg = msgb_alloc(1024, str); + + iph = (void*)msgb_put(msg, sizeof(*iph)); + iph->proto = IPAC_PROTO_OSMO; + + ipx = (void*)msgb_put(msg, sizeof(*ipx)); + ipx->proto = IPAC_PROTO_EXT_CTRL; + + str_msg = (char*)msgb_put(msg, len); + msg->l2h = (void*)str_msg; + osmo_strlcpy(str_msg, str, len); + + iph->len = msgb_length(msg); return msg; } static void *ctx = NULL; + +struct one_test { + const char *cmd_str; + struct ctrl_cmd expect_parsed; + const char *reply_str; +}; void assert_same_str(const char *label, const char *expect, const char *got) { @@ -49,20 +67,22 @@ OSMO_ASSERT(expect == got); } -static void assert_parsing(const char *str, const struct ctrl_cmd *expect) +static void assert_test(struct ctrl_handle *ctrl, struct ctrl_connection *ccon, const struct one_test *t) { struct ctrl_cmd *cmd; - struct msgb *msg = msgb_from_string(str); + struct msgb *msg = msgb_from_string(t->cmd_str); + int ctx_size_was; - printf("test parsing: '%s'\n", osmo_escape_str(str, -1)); + printf("test: '%s'\n", osmo_escape_str(t->cmd_str, -1)); + printf("parsing:\n"); cmd = ctrl_cmd_parse(ctx, msg); OSMO_ASSERT(cmd); - OSMO_ASSERT(expect->type == cmd->type); + OSMO_ASSERT(t->expect_parsed.type == cmd->type); #define ASSERT_SAME_STR(field) \ - assert_same_str(#field, expect->field, cmd->field) + assert_same_str(#field, t->expect_parsed.field, cmd->field) ASSERT_SAME_STR(id); ASSERT_SAME_STR(variable); @@ -72,35 +92,68 @@ talloc_free(cmd); msgb_free(msg); + + printf("handling:\n"); + + ctx_size_was = talloc_total_size(ctx); + + msg = msgb_from_string(t->cmd_str); + ctrl_handle_msg(ctrl, ccon, msg); + + if (llist_empty(&ccon->write_queue.msg_queue)) { + if (t->reply_str) { + printf("Got no reply, but expected \"%s\"\n", osmo_escape_str(t->reply_str, -1)); + OSMO_ASSERT(!t->reply_str); + } + } else { + struct msgb *sent_msg = msgb_dequeue(&ccon->write_queue.msg_queue); + OSMO_ASSERT(sent_msg); + msgb_put_u8(sent_msg, 0); + + printf("replied: '%s'\n", osmo_escape_str((char*)msgb_l2(sent_msg), -1)); + OSMO_ASSERT(t->reply_str); + OSMO_ASSERT(!strcmp(t->reply_str, (char*)msgb_l2(sent_msg))) + msgb_free(sent_msg); + } + osmo_wqueue_clear(&ccon->write_queue); + + msgb_free(msg); + + if (talloc_total_size(ctx) != ctx_size_was) { + printf("mem leak!\n"); + talloc_report_full(ctx, stdout); + OSMO_ASSERT(false); + } + printf("ok\n"); } -struct one_parsing_test { - const char *cmd_str; - struct ctrl_cmd expect; -}; - -static const struct one_parsing_test test_parsing_list[] = { +static const struct one_test test_messages_list[] = { { "GET 1 variable", { .type = CTRL_TYPE_GET, .id = "1", .variable = "variable", - } + }, + "ERROR 1 Command not found", }, { "GET 1 variable\n", { .type = CTRL_TYPE_GET, .id = "1", .variable = "variable\n", /* current bug */ - } + }, + "ERROR 1 Command not found", + }, { "GET 1 var\ni\nable", { .type = CTRL_TYPE_GET, .id = "1", .variable = "var\ni\nable", /* current bug */ - } + }, + "ERROR 1 Command not found", + }, { "GET 1 variable value", { @@ -108,7 +161,9 @@ .id = "1", .variable = "variable", .value = NULL, - } + }, + "ERROR 1 Command not found", + }, { "GET 1 variable value\n", { @@ -116,7 +171,9 @@ .id = "1", .variable = "variable", .value = NULL, - } + }, + "ERROR 1 Command not found", + }, { "GET 1 variable multiple value tokens", { @@ -124,7 +181,9 @@ .id = "1", .variable = "variable", .value = NULL, - } + }, + "ERROR 1 Command not found", + }, { "GET 1 variable multiple value tokens\n", { @@ -132,7 +191,9 @@ .id = "1", .variable = "variable", .value = NULL, - } + }, + "ERROR 1 Command not found", + }, { "SET 1 variable value", { @@ -140,7 +201,9 @@ .id = "1", .variable = "variable", .value = "value", - } + }, + "ERROR 1 Command not found", + }, { "SET 1 variable value\n", { @@ -148,7 +211,9 @@ .id = "1", .variable = "variable", .value = "value", - } + }, + "ERROR 1 Command not found", + }, { "SET weird_id variable value", { @@ -156,7 +221,9 @@ .id = "weird_id", .variable = "variable", .value = "value", - } + }, + "ERROR weird_id Command not found", + }, { "SET weird_id variable value\n", { @@ -164,7 +231,9 @@ .id = "weird_id", .variable = "variable", .value = "value", - } + }, + "ERROR weird_id Command not found", + }, { "SET 1 variable multiple value tokens", { @@ -172,7 +241,9 @@ .id = "1", .variable = "variable", .value = "multiple value tokens", - } + }, + "ERROR 1 Command not found", + }, { "SET 1 variable multiple value tokens\n", { @@ -180,7 +251,9 @@ .id = "1", .variable = "variable", .value = "multiple value tokens", - } + }, + "ERROR 1 Command not found", + }, { "SET 1 variable value_with_trailing_spaces ", { @@ -188,7 +261,9 @@ .id = "1", .variable = "variable", .value = "value_with_trailing_spaces ", - } + }, + "ERROR 1 Command not found", + }, { "SET 1 variable value_with_trailing_spaces \n", { @@ -196,7 +271,9 @@ .id = "1", .variable = "variable", .value = "value_with_trailing_spaces ", - } + }, + "ERROR 1 Command not found", + }, { "SET \n special_char_id value", { @@ -204,7 +281,9 @@ .id = "\n", .variable = "special_char_id", .value = "value", - } + }, + "ERROR \n Command not found", + }, { "SET \t special_char_id value", { @@ -212,17 +291,28 @@ .id = "\t", .variable = "special_char_id", .value = "value", - } + }, + "ERROR \t Command not found", + }, }; -static void test_parsing() +static void test_messages() { + struct ctrl_handle *ctrl; + struct ctrl_connection *ccon; int i; - for (i = 0; i < ARRAY_SIZE(test_parsing_list); i++) - assert_parsing(test_parsing_list[i].cmd_str, - &test_parsing_list[i].expect); + ctrl = ctrl_handle_alloc2(ctx, NULL, NULL, 0); + ccon = talloc_zero(ctx, struct ctrl_connection); + + osmo_wqueue_init(&ccon->write_queue, 1); + + for (i = 0; i < ARRAY_SIZE(test_messages_list); i++) + assert_test(ctrl, ccon, &test_messages_list[i]); + + talloc_free(ccon); + talloc_free(ctrl); } static struct log_info_cat test_categories[] = { @@ -249,7 +339,7 @@ check_type(CTRL_TYPE_ERROR); check_type(64); - test_parsing(); + test_messages(); return 0; } diff --git a/tests/ctrl/ctrl_test.ok b/tests/ctrl/ctrl_test.ok index 5775eb2..edf97ea 100644 --- a/tests/ctrl/ctrl_test.ok +++ b/tests/ctrl/ctrl_test.ok @@ -7,105 +7,156 @@ ctrl type 5 is TRAP -> 5 OK ctrl type 6 is ERROR -> 6 OK ctrl type 64 is unknown 0x40 [PARSE FAILED] -test parsing: 'GET 1 variable' +test: 'GET 1 variable' +parsing: id = '1' variable = 'variable' value = '(null)' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'GET 1 variable\n' +test: 'GET 1 variable\n' +parsing: id = '1' variable = 'variable\n' value = '(null)' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'GET 1 var\ni\nable' +test: 'GET 1 var\ni\nable' +parsing: id = '1' variable = 'var\ni\nable' value = '(null)' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'GET 1 variable value' +test: 'GET 1 variable value' +parsing: id = '1' variable = 'variable' value = '(null)' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'GET 1 variable value\n' +test: 'GET 1 variable value\n' +parsing: id = '1' variable = 'variable' value = '(null)' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'GET 1 variable multiple value tokens' +test: 'GET 1 variable multiple value tokens' +parsing: id = '1' variable = 'variable' value = '(null)' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'GET 1 variable multiple value tokens\n' +test: 'GET 1 variable multiple value tokens\n' +parsing: id = '1' variable = 'variable' value = '(null)' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'SET 1 variable value' +test: 'SET 1 variable value' +parsing: id = '1' variable = 'variable' value = 'value' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'SET 1 variable value\n' +test: 'SET 1 variable value\n' +parsing: id = '1' variable = 'variable' value = 'value' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'SET weird_id variable value' +test: 'SET weird_id variable value' +parsing: id = 'weird_id' variable = 'variable' value = 'value' reply = '(null)' +handling: +replied: 'ERROR weird_id Command not found' ok -test parsing: 'SET weird_id variable value\n' +test: 'SET weird_id variable value\n' +parsing: id = 'weird_id' variable = 'variable' value = 'value' reply = '(null)' +handling: +replied: 'ERROR weird_id Command not found' ok -test parsing: 'SET 1 variable multiple value tokens' +test: 'SET 1 variable multiple value tokens' +parsing: id = '1' variable = 'variable' value = 'multiple value tokens' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'SET 1 variable multiple value tokens\n' +test: 'SET 1 variable multiple value tokens\n' +parsing: id = '1' variable = 'variable' value = 'multiple value tokens' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'SET 1 variable value_with_trailing_spaces ' +test: 'SET 1 variable value_with_trailing_spaces ' +parsing: id = '1' variable = 'variable' value = 'value_with_trailing_spaces ' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'SET 1 variable value_with_trailing_spaces \n' +test: 'SET 1 variable value_with_trailing_spaces \n' +parsing: id = '1' variable = 'variable' value = 'value_with_trailing_spaces ' reply = '(null)' +handling: +replied: 'ERROR 1 Command not found' ok -test parsing: 'SET \n special_char_id value' +test: 'SET \n special_char_id value' +parsing: id = '\n' variable = 'special_char_id' value = 'value' reply = '(null)' +handling: +replied: 'ERROR \n Command not found' ok -test parsing: 'SET \t special_char_id value' +test: 'SET \t special_char_id value' +parsing: id = '\t' variable = 'special_char_id' value = 'value' reply = '(null)' +handling: +replied: 'ERROR \t Command not found' ok -- To view, visit https://gerrit.osmocom.org/5432 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idd4cc7d193db1a7d761f72ed33ed46eea450a78f Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>