[MERGED] osmo-hlr[master]: add initial db_test: creating and deleting subscribers

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Wed Oct 11 22:02:37 UTC 2017


Neels Hofmeyr has submitted this change and it was merged.

Change subject: add initial db_test: creating and deleting subscribers
......................................................................


add initial db_test: creating and deleting subscribers

Change-Id: I2a0d277f55162bf5ceb0fc7d50390f2994daed71
---
M configure.ac
M tests/Makefile.am
A tests/db/Makefile.am
A tests/db/db_test.c
A tests/db/db_test.err
A tests/db/db_test.ok
M tests/testsuite.at
7 files changed, 662 insertions(+), 0 deletions(-)

Approvals:
  Neels Hofmeyr: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/configure.ac b/configure.ac
index 167d7f3..1db32d4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,4 +70,5 @@
 	tests/auc/Makefile
 	tests/auc/gen_ts_55_205_test_sets/Makefile
 	tests/gsup_server/Makefile
+	tests/db/Makefile
 	)
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 <info at sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr at sysmocom.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <getopt.h>
+#include <inttypes.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/logging.h>
+
+#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.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

-- 
To view, visit https://gerrit.osmocom.org/4178
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I2a0d277f55162bf5ceb0fc7d50390f2994daed71
Gerrit-PatchSet: 3
Gerrit-Project: osmo-hlr
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>


More information about the gerrit-log mailing list