From c0d02cc16341198ac8c3b4813f1403a856ac047e Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Mon, 14 Dec 2020 02:36:53 +0100 Subject: utils: add osmo-ns-dummy A dummy client to do integration tests of the ns2 layer. It drop all unit data. But allows vty tests. Change-Id: I127c178426bc1a3da8de251740eda93853030d6d --- tests/Makefile.am | 9 ++ tests/gb/gprs_ns2_vty.vty | 33 ++++++ utils/Makefile.am | 21 +++- utils/osmo-ns-dummy.c | 274 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 tests/gb/gprs_ns2_vty.vty create mode 100644 utils/osmo-ns-dummy.c diff --git a/tests/Makefile.am b/tests/Makefile.am index cb683f79..33b42df4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -320,6 +320,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ gsm0808/gsm0808_test.ok gb/bssgp_fc_tests.err \ gb/bssgp_fc_tests.ok gb/bssgp_fc_tests.sh \ gb/gprs_bssgp_test.ok gb/gprs_ns_test.ok gea/gea_test.ok \ + gb/gprs_ns2_vty.vty \ gprs/gprs_test.ok kasumi/kasumi_test.ok \ msgfile/msgfile_test.ok msgfile/msgconfig.cfg \ logging/logging_test.ok logging/logging_test.err \ @@ -430,6 +431,13 @@ endif # pass -u to osmo_verify_transcript_vty.py by doing: # make vty-test U=-u +vty-test-ns2: + $(MAKE) -C $(top_builddir)/utils osmo-ns-dummy + osmo_verify_transcript_vty.py -v \ + -p 42042 \ + -r "$(top_builddir)/utils/osmo-ns-dummy -p 42042" \ + $(U) $(srcdir)/gb/gprs_ns2*.vty + vty-test-logging: osmo_verify_transcript_vty.py -v \ -p 42042 \ @@ -461,6 +469,7 @@ vty-test: $(MAKE) vty-test-logging $(MAKE) vty-test-vty $(MAKE) vty-test-tdef + $(MAKE) vty-test-ns2 ctrl-test: echo "No CTRL tests exist currently" diff --git a/tests/gb/gprs_ns2_vty.vty b/tests/gb/gprs_ns2_vty.vty new file mode 100644 index 00000000..397ec26d --- /dev/null +++ b/tests/gb/gprs_ns2_vty.vty @@ -0,0 +1,33 @@ +OsmoNSdummy> list +... + show ns binds [stats] + show ns entities [stats] + show ns persistent + show ns (nsei|nsvc) <0-65535> [stats] +... + logging filter nse nsei <0-65535> + logging filter nsvc nsvci <0-65535> +... +OsmoNSdummy> enable +OsmoNSdummy# configure terminal +OsmoNSdummy(config)# list +... + ns +... +OsmoNSdummy(config)# ns +OsmoNSdummy(config-ns)# list +... + timer (tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov|tsns-size-retries|tsns-config-retries) <0-65535> + nse <0-65535> + no nse <0-65535> + bind (fr|udp) ID + no bind ID +... +OsmoNSdummy(config-ns)# bind udp abc +OsmoNSdummy(config-ns-bind)# fr eta0 frnet +fr can be only used with frame relay bind +OsmoNSdummy(config-ns-bind)# listen 127.0.0.14 42999 +OsmoNSdummy(config-ns-bind)# end +OsmoNSdummy# show ns +UDP bind: 127.0.0.14:42999 DSCP: 0 + 0 NS-VC: diff --git a/utils/Makefile.am b/utils/Makefile.am index 653b7190..4fac477d 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -1,11 +1,14 @@ -if ENABLE_UTILITIES + +bin_PROGRAMS = +noinst_PROGRAMS = AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include $(TALLOC_CFLAGS) AM_CFLAGS = -Wall $(PTHREAD_CFLAGS) LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la $(PTHREAD_LIBS) +if ENABLE_UTILITIES EXTRA_DIST = conv_gen.py conv_codes_gsm.py -bin_PROGRAMS = osmo-arfcn osmo-auc-gen osmo-config-merge +bin_PROGRAMS += osmo-arfcn osmo-auc-gen osmo-config-merge osmo_arfcn_SOURCES = osmo-arfcn.c @@ -16,9 +19,21 @@ osmo_config_merge_LDADD = $(LDADD) $(TALLOC_LIBS) osmo_config_merge_CFLAGS = $(TALLOC_CFLAGS) if ENABLE_PCSC -noinst_PROGRAMS = osmo-sim-test +noinst_PROGRAMS += osmo-sim-test osmo_sim_test_SOURCES = osmo-sim-test.c osmo_sim_test_LDADD = $(LDADD) $(top_builddir)/src/sim/libosmosim.la $(PCSC_LIBS) osmo_sim_test_CFLAGS = $(PCSC_CFLAGS) endif endif + +if ENABLE_EXT_TESTS +if ENABLE_GB +noinst_PROGRAMS += osmo-ns-dummy +osmo_ns_dummy_SOURCES = osmo-ns-dummy.c +osmo_ns_dummy_LDADD = $(LDADD) $(TALLOC_LIBS) \ + $(top_builddir)/src/gb/libosmogb.la \ + $(top_builddir)/src/vty/libosmovty.la \ + $(top_builddir)/src/gsm/libosmogsm.la +osmo_ns_dummy_CFLAGS = $(TALLOC_CFLAGS) +endif +endif diff --git a/utils/osmo-ns-dummy.c b/utils/osmo-ns-dummy.c new file mode 100644 index 00000000..6790b4c3 --- /dev/null +++ b/utils/osmo-ns-dummy.c @@ -0,0 +1,274 @@ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" + +void *tall_nsdummy_ctx = NULL; +static struct log_info log_info = {}; +static bool quit = false; +static bool config_given = false; +static bool daemonize = false; +static int vty_port = 0; +static char *config_file = NULL; + +static const char vty_copyright[] = + "Copyright (C) 2020 by by sysmocom - s.f.m.c. GmbH\r\n" + "Author: Alexander Couzens \r\n" + "License GNU GPL version 2 or later\r\n" + "This is free software: you are free to change and redistribute it.\r\n" + "There is NO WARRANTY, to the extent permitted by law.\r\n"; + +static struct vty_app_info vty_info = { + .name = "OsmoNSdummy", + .version = PACKAGE_VERSION, + .copyright = vty_copyright, +}; + +static void print_help() +{ + printf( "Some useful options:\n" + " -h --help This text\n" + " -c --config-file Specify the filename of the config file\n" + " -V --version Print version\n" + " -D --daemonize Fork the process into a background daemon\n" + " -p --vty-port PORT Set the vty port to listen on.\n" + "\nVTY reference generation:\n" + " --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n" + " --vty-ref-xml Generate the VTY reference XML output and exit.\n" + ); +} + +static void handle_long_options(const char *prog_name, const int long_option) +{ + static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT; + + switch (long_option) { + case 1: + vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg); + if (vty_ref_mode < 0) { + fprintf(stderr, "%s: Unknown VTY reference generation " + "mode '%s'\n", prog_name, optarg); + exit(2); + } + break; + case 2: + fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n", + get_value_string(vty_ref_gen_mode_names, vty_ref_mode), + get_value_string(vty_ref_gen_mode_desc, vty_ref_mode)); + vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode); + exit(0); + default: + fprintf(stderr, "%s: error parsing cmdline options\n", prog_name); + exit(2); + } +} + +static void handle_options(int argc, char **argv) +{ + while (1) { + int option_idx = 0, c; + static int long_option = 0; + static const struct option long_options[] = { + { "help", 0, 0, 'h' }, + { "config-file", 1, 0, 'c' }, + { "version", 0, 0, 'V' }, + { "daemonize", 0, 0, 'D' }, + { "vty-port", 1, 0, 'p' }, + { "vty-ref-mode", 1, &long_option, 1 }, + { "vty-ref-xml", 0, &long_option, 2 }, + { 0, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "hc:p:VD", + long_options, &option_idx); + if (c == -1) + break; + + switch (c) { + case 'h': + print_help(); + exit(0); + break; + case 0: + handle_long_options(argv[0], long_option); + break; + case 'c': + if (config_file) + free(config_file); + config_file = optarg; + config_given = true; + break; + case 'p': + vty_port = atoi(optarg); + if (vty_port < 0 || vty_port > 65535) { + fprintf(stderr, "Invalid port %d given!\n", vty_port); + exit(1); + } + break; + case 'V': + print_version(1); + exit(0); + break; + case 'D': + daemonize = true; + break; + default: + fprintf(stderr, "Unknown option '%c'\n", c); + exit(0); + break; + } + } + + if (!config_file) + config_file = "osmo-ns-dummy.cfg"; + if (!vty_port) { + fprintf(stderr, "A vty port need to be specified (-p)\n"); + exit(1); + } +} + +void sighandler(int sigset) +{ + if (sigset == SIGPIPE) + return; + + fprintf(stderr, "Signal %d received.\n", sigset); + + switch (sigset) { + case SIGINT: + case SIGTERM: + /* If another signal is received afterwards, the program + * is terminated without finishing shutdown process. + */ + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + signal(SIGABRT, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + signal(SIGUSR2, SIG_DFL); + + quit = 1; + break; + case SIGABRT: + /* in case of abort, we want to obtain a talloc report and + * then run default SIGABRT handler, who will generate coredump + * and abort the process. abort() should do this for us after we + * return, but program wouldn't exit if an external SIGABRT is + * received. + */ + talloc_report_full(tall_nsdummy_ctx, stderr); + signal(SIGABRT, SIG_DFL); + raise(SIGABRT); + break; + case SIGUSR1: + case SIGUSR2: + talloc_report_full(tall_nsdummy_ctx, stderr); + break; + } +} + +/* called by the ns layer */ +int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + return 0; +} + +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + return 0; +} + + +int main (int argc, char *argv[]) +{ + void *ctx = tall_nsdummy_ctx = talloc_named_const(NULL, 0, "osmo-ns-dummy"); + struct gprs_ns2_inst *nsi; + int rc = 0; + + osmo_init_logging2(ctx, &log_info); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_filename(osmo_stderr_target, 0); + log_set_print_filename(osmo_stderr_target, 0); + log_set_log_level(osmo_stderr_target, LOGL_INFO); + msgb_talloc_ctx_init(ctx, 0); + osmo_stats_init(ctx); + rate_ctr_init(ctx); + + vty_info.tall_ctx = ctx; + vty_init(&vty_info); + logging_vty_add_cmds(); + osmo_stats_vty_add_cmds(); + osmo_talloc_vty_add_cmds(); + + handle_options(argc, argv); + + nsi = gprs_ns2_instantiate(ctx, gprs_ns_prim_cb, NULL); + if (!nsi) { + LOGP(DLNS, LOGL_ERROR, "Failed to create NS instance\n"); + exit(1); + } + + gprs_ns2_vty2_init(nsi); + rc = vty_read_config_file(config_file, NULL); + if (rc < 0 && config_given) { + fprintf(stderr, "Failed to parse the config file: '%s'\n", + config_file); + exit(1); + } + if (rc < 0) + fprintf(stderr, "No config file: '%s' Using default config.\n", + config_file); + + rc = telnet_init_dynif(ctx, NULL, vty_get_bind_addr(), + vty_port); + if (rc < 0) { + fprintf(stderr, "Error initializing telnet\n"); + exit(1); + } + + signal(SIGINT, sighandler); + signal(SIGTERM, sighandler); + signal(SIGPIPE, sighandler); + signal(SIGABRT, sighandler); + signal(SIGUSR1, sighandler); + signal(SIGUSR2, sighandler); + osmo_init_ignore_signals(); + + if (daemonize) { + rc = osmo_daemonize(); + if (rc < 0) { + perror("Error during daemonize"); + exit(1); + } + } + + while (!quit) { + osmo_select_main(0); + } + + telnet_exit(); + gprs_ns2_free(nsi); + + talloc_report_full(tall_nsdummy_ctx, stderr); + talloc_free(tall_nsdummy_ctx); + + return 0; +} -- cgit v1.2.3