#include static void db_test_fatal(const char *fmt, ...); #define db_fatal db_test_fatal static void db_log_(struct log *log UNUSED, enum log_level level UNUSED, bool call_notifier UNUSED, const char *fmt UNUSED, ...) { } #define log_ db_log_ #include "wallet/db.c" #include "test_utils.h" #include #include #include #include /* AUTOGENERATED MOCKS START */ /* Generated stub for bigsize_get */ size_t bigsize_get(const u8 *p UNNEEDED, size_t max UNNEEDED, bigsize_t *val UNNEEDED) { fprintf(stderr, "bigsize_get called!\n"); abort(); } /* Generated stub for bigsize_put */ size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN] UNNEEDED, bigsize_t v UNNEEDED) { fprintf(stderr, "bigsize_put called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ static char *db_err; static void db_test_fatal(const char *fmt, ...) { va_list ap; /* Fail hard if we're complaining about not being in transaction */ assert(!strstarts(fmt, "No longer in transaction")); va_start(ap, fmt); db_err = tal_vfmt(NULL, fmt, ap); va_end(ap); } void plugin_hook_db_sync(struct db *db UNNEEDED, const char **changes UNNEEDED, const char *final UNNEEDED) { } static struct db *create_test_db(void) { struct db *db; char filename[] = "/tmp/ldb-XXXXXX"; int fd = mkstemp(filename); if (fd == -1) return NULL; close(fd); db = db_open(NULL, filename); return db; } static bool test_empty_db_migrate(struct lightningd *ld) { struct db *db = create_test_db(); CHECK(db); db_begin_transaction(db); CHECK(db_get_version(db) == -1); db_commit_transaction(db); db_migrate(ld, db, NULL); db_begin_transaction(db); CHECK(db_get_version(db) == ARRAY_SIZE(dbmigrations) - 1); db_commit_transaction(db); tal_free(db); return true; } static bool test_primitives(void) { struct db *db = create_test_db(); db_begin_transaction(db); CHECK(db->in_transaction); db_commit_transaction(db); CHECK(!db->in_transaction); db_begin_transaction(db); db_commit_transaction(db); db_begin_transaction(db); db_exec(__func__, db, "SELECT name FROM sqlite_master WHERE type='table';"); CHECK_MSG(!db_err, "Simple correct SQL command"); db_exec(__func__, db, "not a valid SQL statement"); CHECK_MSG(db_err, "Failing SQL command"); db_err = tal_free(db_err); db_commit_transaction(db); CHECK(!db->in_transaction); tal_free(db); return true; } static bool test_vars(struct lightningd *ld) { struct db *db = create_test_db(); char *varname = "testvar"; CHECK(db); db_migrate(ld, db, NULL); db_begin_transaction(db); /* Check default behavior */ CHECK(db_get_intvar(db, varname, 42) == 42); /* Check setting and getting */ db_set_intvar(db, varname, 1); CHECK(db_get_intvar(db, varname, 42) == 1); /* Check updating */ db_set_intvar(db, varname, 2); CHECK(db_get_intvar(db, varname, 42) == 2); db_commit_transaction(db); tal_free(db); return true; } int main(void) { setup_locale(); bool ok = true; /* Dummy for migration hooks */ struct lightningd *ld = tal(NULL, struct lightningd); ld->config = test_config; ok &= test_empty_db_migrate(ld); ok &= test_vars(ld); ok &= test_primitives(); tal_free(ld); return !ok; }