libpurple/tests/sqlite3/test_sqlite3.c

changeset 41804
36c3c3cd2402
child 42182
3fc2d2b7b7a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/tests/sqlite3/test_sqlite3.c	Mon Oct 10 00:38:48 2022 -0500
@@ -0,0 +1,476 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+
+#include <sqlite3.h>
+
+#include <purple.h>
+
+/******************************************************************************
+ * get schema version tests
+ *****************************************************************************/
+static void
+test_sqlite3_get_schema_version_null(void) {
+	if(g_test_subprocess()) {
+		GError *error = NULL;
+		int version = 0;
+
+		version = purple_sqlite3_get_schema_version(NULL, &error);
+		g_assert_error(error, PURPLE_SQLITE3_DOMAIN, 0);
+		g_assert_cmpint(version, ==, -1);
+	}
+
+	g_test_trap_subprocess(NULL, 0, 0);
+	g_test_trap_assert_failed();
+	g_test_trap_assert_stderr("*assertion*!= NULL*");
+}
+
+static void
+test_sqlite3_get_schema_version_new(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	int rc = 0;
+	int version = 0;
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 0);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+/******************************************************************************
+ * string migration tests
+ *****************************************************************************/
+static void
+test_sqlite3_string_migrations_null(void) {
+	if(g_test_subprocess()) {
+		GError *error = NULL;
+		sqlite3 *db = NULL;
+		gboolean res = FALSE;
+		int rc = 0;
+
+		rc = sqlite3_open(":memory:", &db);
+		g_assert_nonnull(db);
+		g_assert_cmpint(rc, ==, SQLITE_OK);
+
+		res = purple_sqlite3_run_migrations_from_strings(db, NULL, &error);
+		g_assert_no_error(error);
+		g_assert_false(res);
+	}
+
+	g_test_trap_subprocess(NULL, 0, 0);
+	g_test_trap_assert_failed();
+	g_test_trap_assert_stderr("*migrations != NULL*");
+}
+
+static void
+test_sqlite3_string_migrations_null_terminator(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	gboolean res = FALSE;
+	int rc = 0;
+	int version = -1;
+	const char *migrations[] = {NULL};
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	res = purple_sqlite3_run_migrations_from_strings(db, migrations, &error);
+	g_assert_no_error(error);
+	g_assert_true(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 0);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+static void
+test_sqlite3_string_migrations_multiple(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	gboolean res = FALSE;
+	int rc = 0;
+	int version = -1;
+	const char *migrations[] = {
+		"CREATE TABLE foo(a TEXT); CREATE TABLE bar(b TEXT);",
+		"CREATE TABLE baz(c TEXT);",
+		NULL
+	};
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	res = purple_sqlite3_run_migrations_from_strings(db, migrations, &error);
+	g_assert_no_error(error);
+	g_assert_true(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 2);
+
+	/* Run the migrations again and make sure we remain at schema version 2. */
+	res = purple_sqlite3_run_migrations_from_strings(db, migrations, &error);
+	g_assert_no_error(error);
+	g_assert_true(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 2);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+static void
+test_sqlite3_string_migrations_syntax_error(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	gboolean res = FALSE;
+	int rc = 0;
+	int version = -1;
+	const char *migrations[] = {
+		"CREATE TABLE broke(a TEXT",
+		NULL
+	};
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	res = purple_sqlite3_run_migrations_from_strings(db, migrations, &error);
+	g_assert_error(error, PURPLE_SQLITE3_DOMAIN, 0);
+	g_clear_error(&error);
+	g_assert_false(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 0);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+static void
+test_sqlite3_string_migrations_older(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	gboolean res = FALSE;
+	int rc = 0;
+	int version = -1;
+	const char *migrations1[] = {
+		"CREATE TABLE foo(a TEXT); CREATE TABLE bar(b TEXT);",
+		"CREATE TABLE baz(c TEXT);",
+		NULL
+	};
+	const char *migrations2[] = {
+		"CREATE TABLE foo(a TEXT); CREATE TABLE bar(b TEXT);",
+		NULL
+	};
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	res = purple_sqlite3_run_migrations_from_strings(db, migrations1, &error);
+	g_assert_no_error(error);
+	g_assert_true(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 2);
+
+	/* Run the older migrations now and verify we get a failure. */
+	res = purple_sqlite3_run_migrations_from_strings(db, migrations2, &error);
+	g_assert_error(error, PURPLE_SQLITE3_DOMAIN, 0);
+	g_clear_error(&error);
+	g_assert_false(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 2);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+/******************************************************************************
+ * resource migration tests
+ *****************************************************************************/
+static void
+test_sqlite3_resource_migrations_null_path(void) {
+	if(g_test_subprocess()) {
+		GError *error = NULL;
+		sqlite3 *db = NULL;
+		gboolean res = FALSE;
+		int rc = 0;
+
+		rc = sqlite3_open(":memory:", &db);
+		g_assert_nonnull(db);
+		g_assert_cmpint(rc, ==, SQLITE_OK);
+
+		res = purple_sqlite3_run_migrations_from_resources(db, NULL, NULL,
+		                                                   &error);
+		g_assert_no_error(error);
+		g_assert_false(res);
+
+		rc = sqlite3_close(db);
+		g_assert_cmpint(rc, ==, SQLITE_OK);
+	}
+
+	g_test_trap_subprocess(NULL, 0, 0);
+	g_test_trap_assert_failed();
+	g_test_trap_assert_stderr("*path != NULL*");
+}
+
+static void
+test_sqlite3_resource_migrations_null_migrations(void) {
+	if(g_test_subprocess()) {
+		GError *error = NULL;
+		sqlite3 *db = NULL;
+		gboolean res = FALSE;
+		const char *path = "/im/libpidgin/purple/tests/sqlite3/";
+		int rc = 0;
+
+		rc = sqlite3_open(":memory:", &db);
+		g_assert_nonnull(db);
+		g_assert_cmpint(rc, ==, SQLITE_OK);
+
+		res = purple_sqlite3_run_migrations_from_resources(db, path, NULL,
+		                                                   &error);
+		g_assert_no_error(error);
+		g_assert_false(res);
+
+		rc = sqlite3_close(db);
+		g_assert_cmpint(rc, ==, SQLITE_OK);
+	}
+
+	g_test_trap_subprocess(NULL, 0, 0);
+	g_test_trap_assert_failed();
+	g_test_trap_assert_stderr("*migrations != NULL*");
+}
+
+static void
+test_sqlite3_resource_migrations_null_terminator(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	gboolean res = FALSE;
+	int rc = 0;
+	int version = -1;
+	const char *migrations[] = {NULL};
+	const char *path = "/im/pidgin/libpurple/tests/sqlite3/";
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	res = purple_sqlite3_run_migrations_from_resources(db, path, migrations,
+	                                                   &error);
+	g_assert_no_error(error);
+	g_assert_true(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 0);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+static void
+test_sqlite3_resource_migrations_multiple(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	gboolean res = FALSE;
+	int rc = 0;
+	int version = -1;
+	const char *migrations[] = {"initial.sql", "secondary.sql", NULL};
+	const char *path = "/im/pidgin/libpurple/tests/sqlite3/";
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	res = purple_sqlite3_run_migrations_from_resources(db, path, migrations,
+	                                                   &error);
+	g_assert_no_error(error);
+	g_assert_true(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 2);
+
+	/* Run the migrations again and make sure we remain at schema version 2. */
+	res = purple_sqlite3_run_migrations_from_strings(db, migrations, &error);
+	g_assert_no_error(error);
+	g_assert_true(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 2);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+static void
+test_sqlite3_resource_migrations_missing(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	gboolean res = FALSE;
+	int rc = 0;
+	int version = -1;
+	const char *migrations[] = {"initial.sql", "imaginary.sql", NULL};
+	const char *path = "/im/pidgin/libpurple/tests/sqlite3/";
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	res = purple_sqlite3_run_migrations_from_resources(db, path, migrations,
+	                                                   &error);
+	g_assert_error(error, G_RESOURCE_ERROR, 0);
+	g_clear_error(&error);
+	g_assert_false(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 1);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+static void
+test_sqlite3_resource_migrations_syntax_error(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	gboolean res = FALSE;
+	int rc = 0;
+	int version = -1;
+	const char *migrations[] = {"malformed.sql", NULL};
+	const char *path = "/im/pidgin/libpurple/tests/sqlite3/";
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	res = purple_sqlite3_run_migrations_from_resources(db, path, migrations,
+	                                                   &error);
+	g_assert_error(error, PURPLE_SQLITE3_DOMAIN, 0);
+	g_clear_error(&error);
+	g_assert_false(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 0);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+static void
+test_sqlite3_resource_migrations_older(void) {
+	GError *error = NULL;
+	sqlite3 *db = NULL;
+	gboolean res = FALSE;
+	int rc = 0;
+	int version = -1;
+	const char *migrations1[] = {"initial.sql", "secondary.sql", NULL};
+	const char *migrations2[] = {"initial.sql", NULL};
+	const char *path = "/im/pidgin/libpurple/tests/sqlite3/";
+
+	rc = sqlite3_open(":memory:", &db);
+	g_assert_nonnull(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+
+	res = purple_sqlite3_run_migrations_from_resources(db, path, migrations1,
+	                                                   &error);
+	g_assert_no_error(error);
+	g_assert_true(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 2);
+
+	/* Run the older migrations now and verify we get a failure. */
+	res = purple_sqlite3_run_migrations_from_resources(db, path, migrations2,
+	                                                   &error);
+	g_assert_error(error, PURPLE_SQLITE3_DOMAIN, 0);
+	g_clear_error(&error);
+	g_assert_false(res);
+
+	version = purple_sqlite3_get_schema_version(db, &error);
+	g_assert_no_error(error);
+	g_assert_cmpint(version, ==, 2);
+
+	rc = sqlite3_close(db);
+	g_assert_cmpint(rc, ==, SQLITE_OK);
+}
+
+/******************************************************************************
+ * Main
+ *****************************************************************************/
+int
+main(int argc, char *argv[]) {
+	g_test_init(&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
+
+	g_test_add_func("/sqlite3/schema_version/null",
+	                test_sqlite3_get_schema_version_null);
+	g_test_add_func("/sqlite3/schema_version/new",
+	                test_sqlite3_get_schema_version_new);
+
+	g_test_add_func("/sqlite3/string_migrations/null",
+	                test_sqlite3_string_migrations_null);
+	g_test_add_func("/sqlite3/string_migrations/null-terminator",
+	                test_sqlite3_string_migrations_null_terminator);
+	g_test_add_func("/sqlite3/string_migrations/multiple",
+	                test_sqlite3_string_migrations_multiple);
+	g_test_add_func("/sqlite3/string_migrations/syntax-error",
+	                test_sqlite3_string_migrations_syntax_error);
+	g_test_add_func("/sqlite3/string_migrations/older",
+	                test_sqlite3_string_migrations_older);
+
+	g_test_add_func("/sqlite3/resource_migrations/null-path",
+	                test_sqlite3_resource_migrations_null_path);
+	g_test_add_func("/sqlite3/resource_migrations/null-migrations",
+	                test_sqlite3_resource_migrations_null_migrations);
+	g_test_add_func("/sqlite3/resource_migrations/null-terminator",
+	                test_sqlite3_resource_migrations_null_terminator);
+	g_test_add_func("/sqlite3/resource_migrations/multiple",
+	                test_sqlite3_resource_migrations_multiple);
+	g_test_add_func("/sqlite3/resource_migrations/missing",
+	                test_sqlite3_resource_migrations_missing);
+	g_test_add_func("/sqlite3/resource_migrations/syntax-error",
+	                test_sqlite3_resource_migrations_syntax_error);
+	g_test_add_func("/sqlite3/resource_migrations/older",
+	                test_sqlite3_resource_migrations_older);
+
+	return g_test_run();
+}

mercurial