| #include <stdio.h> |
| #include <stdlib.h> |
| #include <stdint.h> |
| #include <string.h> |
| #include <stdbool.h> |
| |
| #include <osmocom/core/utils.h> |
| #include <osmocom/ctrl/control_cmd.h> |
| #include <osmocom/core/logging.h> |
| #include <osmocom/core/msgb.h> |
| #include <osmocom/core/application.h> |
| |
| static void check_type(enum ctrl_type c) |
| { |
| const char *t = get_value_string(ctrl_type_vals, c); |
| int v = get_string_value(ctrl_type_vals, t); |
| |
| printf("ctrl type %d is %s ", c, t); |
| if (v < 0) |
| printf("[PARSE FAILED]\n"); |
| else |
| printf("-> %d %s\n", v, c != v ? "FAIL" : "OK"); |
| } |
| |
| struct msgb *msgb_from_string(const char *str) |
| { |
| char *rc; |
| 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); |
| return msg; |
| } |
| |
| static void *ctx = NULL; |
| |
| void print_escaped(const char *str) |
| { |
| if (!str) { |
| printf("NULL"); |
| return; |
| } |
| |
| printf("'"); |
| for (;*str; str++) { |
| switch (*str) { |
| case '\n': |
| printf("\\n"); |
| break; |
| case '\r': |
| printf("\\r"); |
| break; |
| case '\t': |
| printf("\\t"); |
| break; |
| default: |
| printf("%c", *str); |
| break; |
| } |
| } |
| printf("'"); |
| } |
| |
| void assert_same_str(const char *label, const char *expect, const char *got) |
| { |
| if ((expect == got) || (expect && got && (strcmp(expect, got) == 0))) { |
| printf("%s = ", label); |
| print_escaped(got); |
| printf("\n"); |
| return; |
| } |
| |
| printf("MISMATCH for '%s':\ngot: ", label); print_escaped(got); |
| printf("\nexpected: "); print_escaped(expect); |
| printf("\n"); |
| OSMO_ASSERT(expect == got); |
| } |
| |
| static void assert_parsing(const char *str, const struct ctrl_cmd *expect) |
| { |
| struct ctrl_cmd *cmd; |
| struct msgb *msg = msgb_from_string(str); |
| |
| printf("test parsing: "); |
| print_escaped(str); |
| printf("\n"); |
| |
| cmd = ctrl_cmd_parse(ctx, msg); |
| OSMO_ASSERT(cmd); |
| |
| OSMO_ASSERT(expect->type == cmd->type); |
| |
| #define ASSERT_SAME_STR(field) \ |
| assert_same_str(#field, expect->field, cmd->field) |
| |
| ASSERT_SAME_STR(id); |
| ASSERT_SAME_STR(variable); |
| ASSERT_SAME_STR(value); |
| ASSERT_SAME_STR(reply); |
| |
| talloc_free(cmd); |
| msgb_free(msg); |
| |
| printf("ok\n"); |
| } |
| |
| struct one_parsing_test { |
| const char *cmd_str; |
| struct ctrl_cmd expect; |
| }; |
| |
| static const struct one_parsing_test test_parsing_list[] = { |
| { "GET 1 variable", |
| { |
| .type = CTRL_TYPE_GET, |
| .id = "1", |
| .variable = "variable", |
| } |
| }, |
| { "GET 1 variable\n", |
| { |
| .type = CTRL_TYPE_GET, |
| .id = "1", |
| .variable = "variable\n", /* current bug */ |
| } |
| }, |
| { "GET 1 var\ni\nable", |
| { |
| .type = CTRL_TYPE_GET, |
| .id = "1", |
| .variable = "var\ni\nable", /* current bug */ |
| } |
| }, |
| { "GET 1 variable value", |
| { |
| .type = CTRL_TYPE_GET, |
| .id = "1", |
| .variable = "variable", |
| .value = NULL, |
| } |
| }, |
| { "GET 1 variable value\n", |
| { |
| .type = CTRL_TYPE_GET, |
| .id = "1", |
| .variable = "variable", |
| .value = NULL, |
| } |
| }, |
| { "GET 1 variable multiple value tokens", |
| { |
| .type = CTRL_TYPE_GET, |
| .id = "1", |
| .variable = "variable", |
| .value = NULL, |
| } |
| }, |
| { "GET 1 variable multiple value tokens\n", |
| { |
| .type = CTRL_TYPE_GET, |
| .id = "1", |
| .variable = "variable", |
| .value = NULL, |
| } |
| }, |
| { "SET 1 variable value", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "1", |
| .variable = "variable", |
| .value = "value", |
| } |
| }, |
| { "SET 1 variable value\n", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "1", |
| .variable = "variable", |
| .value = "value", |
| } |
| }, |
| { "SET weird_id variable value", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "weird_id", |
| .variable = "variable", |
| .value = "value", |
| } |
| }, |
| { "SET weird_id variable value\n", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "weird_id", |
| .variable = "variable", |
| .value = "value", |
| } |
| }, |
| { "SET 1 variable multiple value tokens", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "1", |
| .variable = "variable", |
| .value = "multiple value tokens", |
| } |
| }, |
| { "SET 1 variable multiple value tokens\n", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "1", |
| .variable = "variable", |
| .value = "multiple value tokens", |
| } |
| }, |
| { "SET 1 variable value_with_trailing_spaces ", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "1", |
| .variable = "variable", |
| .value = "value_with_trailing_spaces ", |
| } |
| }, |
| { "SET 1 variable value_with_trailing_spaces \n", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "1", |
| .variable = "variable", |
| .value = "value_with_trailing_spaces ", |
| } |
| }, |
| { "SET \n special_char_id value", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "\n", |
| .variable = "special_char_id", |
| .value = "value", |
| } |
| }, |
| { "SET \t special_char_id value", |
| { |
| .type = CTRL_TYPE_SET, |
| .id = "\t", |
| .variable = "special_char_id", |
| .value = "value", |
| } |
| }, |
| }; |
| |
| static void test_parsing() |
| { |
| 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); |
| } |
| |
| static struct log_info_cat test_categories[] = { |
| }; |
| |
| static struct log_info info = { |
| .cat = test_categories, |
| .num_cat = ARRAY_SIZE(test_categories), |
| }; |
| |
| int main(int argc, char **argv) |
| { |
| ctx = talloc_named_const(NULL, 1, "ctrl_test"); |
| osmo_init_logging(&info); |
| |
| printf("Checking ctrl types...\n"); |
| |
| check_type(CTRL_TYPE_UNKNOWN); |
| check_type(CTRL_TYPE_GET); |
| check_type(CTRL_TYPE_SET); |
| check_type(CTRL_TYPE_GET_REPLY); |
| check_type(CTRL_TYPE_SET_REPLY); |
| check_type(CTRL_TYPE_TRAP); |
| check_type(CTRL_TYPE_ERROR); |
| check_type(64); |
| |
| test_parsing(); |
| |
| return 0; |
| } |