[PATCH] libosmocore[master]: ctrl_test: expand to test message handling and detect mem leaks

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.org
Sat Dec 16 05:24:25 UTC 2017


Review 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>



More information about the gerrit-log mailing list