From 985094601315c45c2e0a2ac8292df4c2f646c698 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Mon, 9 Oct 2017 17:28:53 +0200 Subject: add initial db_test: creating and deleting subscribers Change-Id: I2a0d277f55162bf5ceb0fc7d50390f2994daed71 --- tests/Makefile.am | 1 + tests/db/Makefile.am | 53 ++++++++ tests/db/db_test.c | 346 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/db/db_test.err | 251 +++++++++++++++++++++++++++++++++++++ tests/db/db_test.ok | 2 + tests/testsuite.at | 8 ++ 6 files changed, 661 insertions(+) create mode 100644 tests/db/Makefile.am create mode 100644 tests/db/db_test.c create mode 100644 tests/db/db_test.err create mode 100644 tests/db/db_test.ok (limited to 'tests') diff --git a/tests/Makefile.am b/tests/Makefile.am index d979fb6..0b625f5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,7 @@ SUBDIRS = \ auc \ gsup_server \ + db \ $(NULL) # The `:;' works around a Bash 3.2 bug when the output is not writeable. diff --git a/tests/db/Makefile.am b/tests/db/Makefile.am new file mode 100644 index 0000000..a1f35a7 --- /dev/null +++ b/tests/db/Makefile.am @@ -0,0 +1,53 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/src \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(SQLITE3_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(NULL) + +EXTRA_DIST = \ + db_test.ok \ + db_test.err \ + $(NULL) + +check_PROGRAMS = db_test + +db_test_SOURCES = \ + db_test.c \ + $(NULL) + +db_test_LDADD = \ + $(top_srcdir)/src/db.c \ + $(top_srcdir)/src/db_hlr.c \ + $(top_srcdir)/src/db_auc.c \ + $(top_srcdir)/src/logging.c \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(SQLITE3_LIBS) \ + $(NULL) + +.PHONY: db_test.db update_exp manual manual-nonverbose manual-gdb +db_test.db: + rm -f db_test.db + sqlite3 $(builddir)/db_test.db < $(top_srcdir)/sql/hlr.sql + +update_exp: db_test.db + cd $(builddir); ./db_test >"$(srcdir)/db_test.ok" 2>"$(srcdir)/db_test.err" + +manual: db_test.db + cd $(builddir); ./db_test -v + +manual-nonverbose: db_test.db + cd $(builddir); ./db_test + +manual-gdb: db_test.db + cd $(builddir); gdb -ex run --args ./db_test -v diff --git a/tests/db/db_test.c b/tests/db/db_test.c new file mode 100644 index 0000000..9bd082e --- /dev/null +++ b/tests/db/db_test.c @@ -0,0 +1,346 @@ +/* (C) 2017 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Neels Hofmeyr + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "db.h" +#include "logging.h" + +#define comment_start() fprintf(stderr, "\n===== %s\n", __func__); +#define comment(fmt, args...) fprintf(stderr, "\n--- " fmt "\n\n", ## args); +#define comment_end() fprintf(stderr, "===== %s: SUCCESS\n\n", __func__); + +/* Perform a function call and verbosely assert that its return value is as expected. + * The return code is then available in g_rc. */ +#define ASSERT_RC(call, expect_rc) \ + do { \ + fprintf(stderr, #call " --> " #expect_rc "\n"); \ + g_rc = call; \ + if (g_rc != (expect_rc)) \ + fprintf(stderr, " MISMATCH: got rc = %d, expected: " \ + #expect_rc " = %d\n", g_rc, expect_rc); \ + OSMO_ASSERT(g_rc == (expect_rc)); \ + fprintf(stderr, "\n"); \ + } while (0) + +/* Do db_subscr_get_by_xxxx and verbosely assert that its return value is as expected. + * Print the subscriber struct to stderr to be validated by db_test.err. + * The result is then available in g_subscr. */ +#define ASSERT_SEL(by, val, expect_rc) \ + do { \ + int rc; \ + g_subscr = (struct hlr_subscriber){}; \ + fprintf(stderr, "db_subscr_get_by_" #by "(dbc, " #val ", &g_subscr) --> " \ + #expect_rc "\n"); \ + rc = db_subscr_get_by_##by(dbc, val, &g_subscr); \ + if (rc != (expect_rc)) \ + fprintf(stderr, " MISMATCH: got rc = %d, expected: " \ + #expect_rc " = %d\n", rc, expect_rc); \ + OSMO_ASSERT(rc == (expect_rc)); \ + if (!rc) \ + dump_subscr(&g_subscr); \ + fprintf(stderr, "\n"); \ + } while (0) + +static struct db_context *dbc = NULL; +static void *ctx = NULL; +static struct hlr_subscriber g_subscr; +static int g_rc; + +#define Pfv(name, fmt, val) \ + fprintf(stderr, " ." #name " = " fmt ",\n", val) +#define Pfo(name, fmt, obj) \ + Pfv(name, fmt, obj->name) + +/* Print a subscriber struct to stderr to be validated by db_test.err. */ +void dump_subscr(struct hlr_subscriber *subscr) +{ +#define Ps(name) \ + if (*subscr->name) \ + Pfo(name, "'%s'", subscr) +#define Pd(name) \ + Pfv(name, "%"PRId64, (int64_t)subscr->name) +#define Pd_nonzero(name) \ + if (subscr->name) \ + Pd(name) +#define Pb(if_val, name) \ + if (subscr->name == (if_val)) \ + Pfv(name, "%s", subscr->name ? "true" : "false") + + fprintf(stderr, "struct hlr_subscriber {\n"); + Pd(id); + Ps(imsi); + Ps(msisdn); + Ps(vlr_number); + Ps(sgsn_number); + Ps(sgsn_address); + Pd_nonzero(periodic_lu_timer); + Pd_nonzero(periodic_rau_tau_timer); + Pb(false, nam_cs); + Pb(false, nam_ps); + if (subscr->lmsi) + Pfo(lmsi, "0x%x", subscr); + Pb(true, ms_purged_cs); + Pb(true, ms_purged_ps); + fprintf(stderr, "}\n"); +#undef Ps +#undef Pd +#undef Pd_nonzero +#undef Pb +} + +void dump_aud(const char *label, struct osmo_sub_auth_data *aud) +{ + if (aud->type == OSMO_AUTH_TYPE_NONE) { + fprintf(stderr, "%s: none\n", label); + return; + } + + fprintf(stderr, "%s: struct osmo_sub_auth_data {\n", label); +#define Pf(name, fmt) \ + Pfo(name, fmt, aud) +#define Phex(name) \ + Pfv(name, "'%s'", osmo_hexdump_nospc(aud->name, sizeof(aud->name))) + + Pfv(type, "%s", osmo_sub_auth_type_name(aud->type)); + Pfv(algo, "%s", osmo_auth_alg_name(aud->algo)); + switch (aud->type) { + case OSMO_AUTH_TYPE_GSM: + Phex(u.gsm.ki); + break; + case OSMO_AUTH_TYPE_UMTS: + Phex(u.umts.opc); + Pf(u.umts.opc_is_op, "%u"); + Phex(u.umts.k); + Phex(u.umts.amf); + if (aud->u.umts.sqn) { + Pf(u.umts.sqn, "%"PRIu64); + Pf(u.umts.sqn, "0x%"PRIx64); + } + if (aud->u.umts.ind_bitlen) + Pf(u.umts.ind_bitlen, "%u"); + break; + default: + OSMO_ASSERT(false); + } + + fprintf(stderr, "}\n"); + +#undef Pf +#undef Phex +} + +static const char *imsi0 = "123456789000000"; +static const char *imsi1 = "123456789000001"; +static const char *imsi2 = "123456789000002"; +static const char *short_imsi = "123456"; +static const char *unknown_imsi = "999999999"; + +static void test_subscr_create_update_sel_delete() +{ + int64_t id0, id1, id2, id_short; + comment_start(); + + comment("Create with valid / invalid IMSI"); + + ASSERT_RC(db_subscr_create(dbc, imsi0), 0); + ASSERT_SEL(imsi, imsi0, 0); + id0 = g_subscr.id; + ASSERT_RC(db_subscr_create(dbc, imsi1), 0); + ASSERT_SEL(imsi, imsi1, 0); + id1 = g_subscr.id; + ASSERT_RC(db_subscr_create(dbc, imsi2), 0); + ASSERT_SEL(imsi, imsi2, 0); + id2 = g_subscr.id; + ASSERT_RC(db_subscr_create(dbc, imsi0), -EIO); + ASSERT_SEL(imsi, imsi0, 0); + ASSERT_RC(db_subscr_create(dbc, imsi1), -EIO); + ASSERT_RC(db_subscr_create(dbc, imsi1), -EIO); + ASSERT_SEL(imsi, imsi1, 0); + ASSERT_RC(db_subscr_create(dbc, imsi2), -EIO); + ASSERT_RC(db_subscr_create(dbc, imsi2), -EIO); + ASSERT_SEL(imsi, imsi2, 0); + + ASSERT_RC(db_subscr_create(dbc, "123456789 000003"), -EINVAL); + ASSERT_SEL(imsi, "123456789000003", -ENOEXEC); + + ASSERT_RC(db_subscr_create(dbc, "123456789000002123456"), -EINVAL); + ASSERT_SEL(imsi, "123456789000002123456", -ENOEXEC); + + ASSERT_RC(db_subscr_create(dbc, "foobar123"), -EINVAL); + ASSERT_SEL(imsi, "foobar123", -ENOEXEC); + + ASSERT_RC(db_subscr_create(dbc, "123"), -EINVAL); + ASSERT_SEL(imsi, "123", -ENOEXEC); + + ASSERT_RC(db_subscr_create(dbc, short_imsi), 0); + ASSERT_SEL(imsi, short_imsi, 0); + id_short = g_subscr.id; + + + comment("Set valid / invalid MSISDN"); + + ASSERT_SEL(imsi, imsi0, 0); + ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0, "54321"), 0); + ASSERT_SEL(imsi, imsi0, 0); + ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0, + "54321012345678912345678"), -EINVAL); + ASSERT_SEL(imsi, imsi0, 0); + ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0, + "543 21"), -EINVAL); + ASSERT_SEL(imsi, imsi0, 0); + ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0, + "foobar123"), -EINVAL); + ASSERT_SEL(imsi, imsi0, 0); + ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0, + "5"), 0); + ASSERT_SEL(imsi, imsi0, 0); + ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0, + "543210123456789"), 0); + ASSERT_SEL(imsi, imsi0, 0); + ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, imsi0, + "5432101234567891"), -EINVAL); + ASSERT_SEL(imsi, imsi0, 0); + + comment("Set MSISDN on non-existent / invalid IMSI"); + + ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, unknown_imsi, "99"), -ENOENT); + + ASSERT_RC(db_subscr_update_msisdn_by_imsi(dbc, "foobar", "99"), -ENOENT); + + comment("Delete non-existent / invalid IDs"); + + ASSERT_RC(db_subscr_delete_by_id(dbc, 999), -ENOENT); + ASSERT_RC(db_subscr_delete_by_id(dbc, -10), -ENOENT); + + comment("Delete subscribers"); + + ASSERT_SEL(imsi, imsi0, 0); + ASSERT_RC(db_subscr_delete_by_id(dbc, id0), 0); + ASSERT_SEL(imsi, imsi0, -ENOEXEC); + ASSERT_RC(db_subscr_delete_by_id(dbc, id0), -ENOENT); + + ASSERT_SEL(imsi, imsi1, 0); + ASSERT_RC(db_subscr_delete_by_id(dbc, id1), 0); + ASSERT_SEL(imsi, imsi1, -ENOEXEC); + + ASSERT_SEL(imsi, imsi2, 0); + ASSERT_RC(db_subscr_delete_by_id(dbc, id2), 0); + ASSERT_SEL(imsi, imsi2, -ENOEXEC); + + ASSERT_SEL(imsi, short_imsi, 0); + ASSERT_RC(db_subscr_delete_by_id(dbc, id_short), 0); + ASSERT_SEL(imsi, short_imsi, -ENOEXEC); + + comment_end(); +} + +static struct { + bool verbose; +} cmdline_opts = { + .verbose = false, +}; + +static void print_help(const char *program) +{ + printf("Usage:\n" + " %s [-v] [N [N...]]\n" + "Options:\n" + " -h --help show this text.\n" + " -v --verbose print source file and line numbers\n", + program + ); +} + +static void handle_options(int argc, char **argv) +{ + while (1) { + int option_index = 0, c; + static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"verbose", 1, 0, 'v'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "hv", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'h': + print_help(argv[0]); + exit(0); + case 'v': + cmdline_opts.verbose = true; + break; + default: + /* catch unknown options *as well as* missing arguments. */ + fprintf(stderr, "Error in command line options. Exiting.\n"); + exit(-1); + break; + } + } + + if (optind < argc) { + fprintf(stderr, "too many args\n"); + exit(-1); + } +} + +int main(int argc, char **argv) +{ + printf("db_test.c\n"); + + ctx = talloc_named_const(NULL, 1, "db_test"); + + handle_options(argc, argv); + + osmo_init_logging(&hlr_log_info); + log_set_print_filename(osmo_stderr_target, cmdline_opts.verbose); + log_set_print_timestamp(osmo_stderr_target, 0); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_category(osmo_stderr_target, 1); + + /* omit the SQLite version and compilation flags from test output */ + log_set_log_level(osmo_stderr_target, LOGL_ERROR); + dbc = db_open(ctx, "db_test.db"); + log_set_log_level(osmo_stderr_target, 0); + OSMO_ASSERT(dbc); + + test_subscr_create_update_sel_delete(); + + printf("Done\n"); + return 0; +} + +/* stubs */ +int auc_compute_vectors(struct osmo_auth_vector *vec, unsigned int num_vec, + struct osmo_sub_auth_data *aud2g, + struct osmo_sub_auth_data *aud3g, + const uint8_t *rand_auts, const uint8_t *auts) +{ OSMO_ASSERT(false); return -1; } diff --git a/tests/db/db_test.err b/tests/db/db_test.err new file mode 100644 index 0000000..ac0e2f1 --- /dev/null +++ b/tests/db/db_test.err @@ -0,0 +1,251 @@ + +===== test_subscr_create_update_sel_delete + +--- Create with valid / invalid IMSI + +db_subscr_create(dbc, imsi0) --> 0 + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', +} + +db_subscr_create(dbc, imsi1) --> 0 + +db_subscr_get_by_imsi(dbc, imsi1, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 2, + .imsi = '123456789000001', +} + +db_subscr_create(dbc, imsi2) --> 0 + +db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 3, + .imsi = '123456789000002', +} + +db_subscr_create(dbc, imsi0) --> -EIO +DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi +DDB Error in sqlite3_reset: 2067 +DAUC IMSI='123456789000000': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', +} + +db_subscr_create(dbc, imsi1) --> -EIO +DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi +DDB Error in sqlite3_reset: 2067 +DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi + +db_subscr_create(dbc, imsi1) --> -EIO +DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi +DDB Error in sqlite3_reset: 2067 +DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi + +db_subscr_get_by_imsi(dbc, imsi1, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 2, + .imsi = '123456789000001', +} + +db_subscr_create(dbc, imsi2) --> -EIO +DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi +DDB Error in sqlite3_reset: 2067 +DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi + +db_subscr_create(dbc, imsi2) --> -EIO +DDB (2067) abort at 18 in [INSERT INTO subscriber (imsi) VALUES ($imsi)]: UNIQUE constraint failed: subscriber.imsi +DDB Error in sqlite3_reset: 2067 +DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi + +db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 3, + .imsi = '123456789000002', +} + +db_subscr_create(dbc, "123456789 000003") --> -EINVAL +DAUC Cannot create subscriber: invalid IMSI: '123456789 000003' + +db_subscr_get_by_imsi(dbc, "123456789000003", &g_subscr) --> -ENOEXEC +DAUC IMSI='123456789000003': Error executing SQL: 101 + +db_subscr_create(dbc, "123456789000002123456") --> -EINVAL +DAUC Cannot create subscriber: invalid IMSI: '123456789000002123456' + +db_subscr_get_by_imsi(dbc, "123456789000002123456", &g_subscr) --> -ENOEXEC +DAUC IMSI='123456789000002123456': Error executing SQL: 101 + +db_subscr_create(dbc, "foobar123") --> -EINVAL +DAUC Cannot create subscriber: invalid IMSI: 'foobar123' + +db_subscr_get_by_imsi(dbc, "foobar123", &g_subscr) --> -ENOEXEC +DAUC IMSI='foobar123': Error executing SQL: 101 + +db_subscr_create(dbc, "123") --> -EINVAL +DAUC Cannot create subscriber: invalid IMSI: '123' + +db_subscr_get_by_imsi(dbc, "123", &g_subscr) --> -ENOEXEC +DAUC IMSI='123': Error executing SQL: 101 + +db_subscr_create(dbc, short_imsi) --> 0 + +db_subscr_get_by_imsi(dbc, short_imsi, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 4, + .imsi = '123456', +} + + +--- Set valid / invalid MSISDN + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', +} + +db_subscr_update_msisdn_by_imsi(dbc, imsi0, "54321") --> 0 + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', + .msisdn = '54321', +} + +db_subscr_update_msisdn_by_imsi(dbc, imsi0, "54321012345678912345678") --> -EINVAL +DAUC IMSI='123456789000000': Cannot update subscriber: invalid MSISDN: '54321012345678912345678' + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', + .msisdn = '54321', +} + +db_subscr_update_msisdn_by_imsi(dbc, imsi0, "543 21") --> -EINVAL +DAUC IMSI='123456789000000': Cannot update subscriber: invalid MSISDN: '543 21' + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', + .msisdn = '54321', +} + +db_subscr_update_msisdn_by_imsi(dbc, imsi0, "foobar123") --> -EINVAL +DAUC IMSI='123456789000000': Cannot update subscriber: invalid MSISDN: 'foobar123' + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', + .msisdn = '54321', +} + +db_subscr_update_msisdn_by_imsi(dbc, imsi0, "5") --> 0 + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', + .msisdn = '5', +} + +db_subscr_update_msisdn_by_imsi(dbc, imsi0, "543210123456789") --> 0 + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', + .msisdn = '543210123456789', +} + +db_subscr_update_msisdn_by_imsi(dbc, imsi0, "5432101234567891") --> -EINVAL +DAUC IMSI='123456789000000': Cannot update subscriber: invalid MSISDN: '5432101234567891' + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', + .msisdn = '543210123456789', +} + + +--- Set MSISDN on non-existent / invalid IMSI + +db_subscr_update_msisdn_by_imsi(dbc, unknown_imsi, "99") --> -ENOENT +DAUC Cannot update MSISDN: no such subscriber: IMSI='999999999' + +db_subscr_update_msisdn_by_imsi(dbc, "foobar", "99") --> -ENOENT +DAUC Cannot update MSISDN: no such subscriber: IMSI='foobar' + + +--- Delete non-existent / invalid IDs + +db_subscr_delete_by_id(dbc, 999) --> -ENOENT +DAUC Cannot delete: no such subscriber: ID=999 + +db_subscr_delete_by_id(dbc, -10) --> -ENOENT +DAUC Cannot delete: no such subscriber: ID=-10 + + +--- Delete subscribers + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', + .msisdn = '543210123456789', +} + +db_subscr_delete_by_id(dbc, id0) --> 0 + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> -ENOEXEC +DAUC IMSI='123456789000000': Error executing SQL: 101 + +db_subscr_delete_by_id(dbc, id0) --> -ENOENT +DAUC Cannot delete: no such subscriber: ID=1 + +db_subscr_get_by_imsi(dbc, imsi1, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 2, + .imsi = '123456789000001', +} + +db_subscr_delete_by_id(dbc, id1) --> 0 + +db_subscr_get_by_imsi(dbc, imsi1, &g_subscr) --> -ENOEXEC +DAUC IMSI='123456789000001': Error executing SQL: 101 + +db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 3, + .imsi = '123456789000002', +} + +db_subscr_delete_by_id(dbc, id2) --> 0 + +db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> -ENOEXEC +DAUC IMSI='123456789000002': Error executing SQL: 101 + +db_subscr_get_by_imsi(dbc, short_imsi, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 4, + .imsi = '123456', +} + +db_subscr_delete_by_id(dbc, id_short) --> 0 + +db_subscr_get_by_imsi(dbc, short_imsi, &g_subscr) --> -ENOEXEC +DAUC IMSI='123456': Error executing SQL: 101 + +===== test_subscr_create_update_sel_delete: SUCCESS + diff --git a/tests/db/db_test.ok b/tests/db/db_test.ok new file mode 100644 index 0000000..26cefd1 --- /dev/null +++ b/tests/db/db_test.ok @@ -0,0 +1,2 @@ +db_test.c +Done diff --git a/tests/testsuite.at b/tests/testsuite.at index a969082..74179e7 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -21,3 +21,11 @@ cat $abs_srcdir/gsup_server/gsup_server_test.ok > expout cat $abs_srcdir/gsup_server/gsup_server_test.err > experr AT_CHECK([$abs_top_builddir/tests/gsup_server/gsup_server_test], [], [expout], [experr]) AT_CLEANUP + +AT_SETUP([db]) +AT_KEYWORDS([db]) +cat $abs_srcdir/db/db_test.ok > expout +cat $abs_srcdir/db/db_test.err > experr +sqlite3 db_test.db < $abs_top_srcdir/sql/hlr.sql +AT_CHECK([$abs_top_builddir/tests/db/db_test], [], [expout], [experr]) +AT_CLEANUP -- cgit v1.2.3