END_TEST START_TEST (db_exec_prepared_stmt_test) { int res; array_header *results; const char *table_path, *schema_name, *stmt, *errstr = NULL; results = proxy_db_exec_prepared_stmt(NULL, NULL, NULL); fail_unless(results == NULL, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); results = proxy_db_exec_prepared_stmt(p, NULL, NULL); fail_unless(results == NULL, "Failed to handle null statement"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); stmt = "SELECT COUNT(*) FROM foo;"; results = proxy_db_exec_prepared_stmt(p, stmt, &errstr); fail_unless(results == NULL, "Failed to handle unprepared statement"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); (void) unlink(db_test_table); table_path = db_test_table; schema_name = "proxy_test"; res = proxy_db_open(p, table_path, schema_name); fail_unless(res == 0, "Failed to open table '%s', schema '%s': %s", table_path, schema_name, strerror(errno)); results = proxy_db_exec_prepared_stmt(p, stmt, &errstr); fail_unless(results == NULL, "Failed to handle unprepared statement"); fail_unless(errno == ENOENT, "Expected ENOENT (%d), got '%s' (%d)", ENOENT, strerror(errno), errno); res = create_table(p, schema_name, "foo"); fail_unless(res == 0, "Failed to create table 'foo': %s", strerror(errno)); res = proxy_db_prepare_stmt(p, stmt); fail_unless(res == 0, "Failed to prepare statement '%s': %s", stmt, strerror(errno)); results = proxy_db_exec_prepared_stmt(p, stmt, &errstr); fail_unless(results != NULL, "Failed to execute prepared statement '%s': %s (%s)", stmt, errstr, strerror(errno)); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close database: %s", strerror(errno)); (void) unlink(db_test_table); }
END_TEST START_TEST (db_finish_stmt_test) { int res; const char *table_path, *schema_name, *stmt; res = proxy_db_finish_stmt(NULL, NULL); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); res = proxy_db_finish_stmt(p, NULL); fail_unless(res < 0, "Failed to handle null statement"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); stmt = "SELECT COUNT(*) FROM foo"; res = proxy_db_finish_stmt(p, stmt); fail_unless(res < 0, "Failed to handle unprepared statement"); fail_unless(errno == ENOENT, "Expected ENOENT (%d), got '%s' (%d)", ENOENT, strerror(errno), errno); (void) unlink(db_test_table); table_path = db_test_table; schema_name = "proxy_test"; res = proxy_db_open(p, table_path, schema_name); fail_unless(res == 0, "Failed to open table '%s', schema '%s': %s", table_path, schema_name, strerror(errno)); res = create_table(p, schema_name, "foo"); fail_unless(res == 0, "Failed to create table 'foo': %s", strerror(errno)); res = proxy_db_prepare_stmt(p, stmt); fail_unless(res == 0, "Failed to prepare statement '%s': %s", stmt, strerror(errno)); res = proxy_db_finish_stmt(p, stmt); fail_unless(res == 0, "Failed to finish statement '%s': %s", stmt, strerror(errno)); res = proxy_db_finish_stmt(p, stmt); fail_unless(res < 0, "Failed to handle unprepared statement"); fail_unless(errno == ENOENT, "Expected ENOENT (%d), got '%s' (%d)", ENOENT, strerror(errno), errno); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close database: %s", strerror(errno)); (void) unlink(db_test_table); }
END_TEST START_TEST (db_reindex_test) { int res; const char *table_path, *schema_name, *index_name, *errstr = NULL; res = proxy_db_reindex(NULL, NULL, NULL); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); res = proxy_db_reindex(p, NULL, NULL); fail_unless(res < 0, "Failed to handle null index name"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); index_name = "test_idx"; res = proxy_db_reindex(p, index_name, NULL); fail_unless(res < 0, "Failed to handle invalid index name"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); (void) unlink(db_test_table); table_path = db_test_table; schema_name = "proxy_test"; res = proxy_db_open(p, table_path, schema_name); fail_unless(res == 0, "Failed to open table '%s', schema '%s': %s", table_path, schema_name, strerror(errno)); res = proxy_db_reindex(p, index_name, &errstr); fail_unless(res < 0, "Failed to handle invalid index"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); fail_unless(errstr != NULL, "Failed to provide error string"); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close database: %s", strerror(errno)); (void) unlink(db_test_table); }
END_TEST START_TEST (db_exec_stmt_test) { int res; const char *table_path, *schema_name, *stmt, *errstr; res = proxy_db_exec_stmt(NULL, NULL, NULL); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); res = proxy_db_exec_stmt(p, NULL, NULL); fail_unless(res < 0, "Failed to handle null statement"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); stmt = "SELECT COUNT(*) FROM foo;"; errstr = NULL; res = proxy_db_exec_stmt(p, stmt, &errstr); fail_unless(res < 0, "Failed to handle missing database handle"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); (void) unlink(db_test_table); table_path = db_test_table; schema_name = "proxy_test"; res = proxy_db_open(p, table_path, schema_name); fail_unless(res == 0, "Failed to open table '%s', schema '%s': %s", table_path, schema_name, strerror(errno)); res = proxy_db_exec_stmt(p, stmt, &errstr); fail_unless(res < 0, "Failed to execute statement '%s'", stmt); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close database: %s", strerror(errno)); (void) unlink(db_test_table); }
END_TEST START_TEST (tls_sess_init_test) { #ifdef PR_USE_OPENSSL int res, flags = PROXY_DB_OPEN_FL_SKIP_VACUUM; res = proxy_tls_sess_init(NULL, flags); fail_unless(res < 0, "Failed to handle null pool"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); mark_point(); res = proxy_tls_sess_init(p, flags); fail_unless(res < 0, "Failed to handle invalid SSL_CTX"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); mark_point(); res = proxy_tls_init(p, test_dir, flags); fail_unless(res == 0, "Failed to init TLS API resources: %s", strerror(errno)); (void) proxy_db_close(p, NULL); mark_point(); res = proxy_tls_sess_init(p, flags); fail_unless(res == 0, "Failed to init TLS API session resources: %s", strerror(errno)); mark_point(); res = proxy_tls_sess_free(p); fail_unless(res == 0, "Failed to release TLS API session resources: %s", strerror(errno)); mark_point(); res = proxy_tls_free(p); fail_unless(res == 0, "Failed to release TLS API resources: %s", strerror(errno)); #endif /* PR_USE_OPENSSL */ }
END_TEST START_TEST (db_open_test) { int res; const char *table_path, *schema_name; res = proxy_db_open(NULL, NULL, NULL); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)", strerror(errno), errno); res = proxy_db_open(p, NULL, NULL); fail_unless(res < 0, "Failed to handle null table path"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)", strerror(errno), errno); (void) unlink(db_test_table); table_path = db_test_table; res = proxy_db_open(p, table_path, NULL); fail_unless(res < 0, "Failed to handle null schema name"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)", strerror(errno), errno); schema_name = "proxy_test"; res = proxy_db_open(p, "/foo/bar/baz/quxx/quzz.db", schema_name); fail_unless(res < 0, "Failed to handle null schema name"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); res = proxy_db_open(p, table_path, schema_name); fail_unless(res == 0, "Failed to open table '%s', schema '%s': %s", table_path, schema_name, strerror(errno)); res = proxy_db_close(p, schema_name); fail_unless(res == 0, "Failed to detach schema '%s': %s", schema_name, strerror(errno)); res = proxy_db_close(p, schema_name); fail_unless(res < 0, "Unexpectedly detached schema '%s'", schema_name); fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM, strerror(errno), errno); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close table '%s': %s", table_path, strerror(errno)); res = proxy_db_open(p, table_path, schema_name); fail_unless(res == 0, "Failed to open table '%s', schema '%s': %s", table_path, schema_name); res = proxy_db_open(p, table_path, schema_name); fail_unless(res < 0, "Re-opened table '%s', schema '%s' unexpectedly", table_path, schema_name); fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM, strerror(errno), errno); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close table '%s': %s", table_path, strerror(errno)); (void) unlink(db_test_table); }
END_TEST START_TEST (db_bind_stmt_test) { int res; const char *table_path, *schema_name, *stmt; int idx, int_val; long long_val; char *text_val; res = proxy_db_bind_stmt(NULL, NULL, -1, -1, NULL); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); res = proxy_db_bind_stmt(p, NULL, -1, -1, NULL); fail_unless(res < 0, "Failed to handle null statement"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); stmt = "SELECT COUNT(*) FROM table"; idx = -1; res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, NULL); fail_unless(res < 0, "Failed to handle invalid index %d", idx); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); idx = 1; res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, NULL); fail_unless(res < 0, "Failed to handle unprepared statement"); fail_unless(errno == ENOENT, "Expected ENOENT (%d), got '%s' (%d)", ENOENT, strerror(errno), errno); (void) unlink(db_test_table); table_path = db_test_table; schema_name = "proxy_test"; res = proxy_db_open(p, table_path, schema_name); fail_unless(res == 0, "Failed to open table '%s', schema '%s': %s", table_path, schema_name, strerror(errno)); res = create_table(p, schema_name, "foo"); fail_unless(res == 0, "Failed to create table 'foo': %s", strerror(errno)); stmt = "SELECT COUNT(*) FROM foo;"; res = proxy_db_prepare_stmt(p, stmt); fail_unless(res == 0, "Failed to prepare statement '%s': %s", stmt, strerror(errno)); res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, NULL); fail_unless(res < 0, "Failed to handle missing INT value"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); int_val = 7; res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, &int_val); fail_unless(res < 0, "Failed to handle invalid index value"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_LONG, NULL); fail_unless(res < 0, "Failed to handle missing LONG value"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); long_val = 7; res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_LONG, &long_val); fail_unless(res < 0, "Failed to handle invalid index value"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_TEXT, NULL); fail_unless(res < 0, "Failed to handle missing TEXT value"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL, strerror(errno), errno); text_val = "testing"; res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_TEXT, text_val); fail_unless(res < 0, "Failed to handle invalid index value"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_NULL, NULL); fail_unless(res < 0, "Failed to handle invalid NULL value"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); stmt = "SELECT COUNT(*) FROM foo WHERE id = ?;"; res = proxy_db_prepare_stmt(p, stmt); fail_unless(res == 0, "Failed to prepare statement '%s': %s", stmt, strerror(errno)); int_val = 7; res = proxy_db_bind_stmt(p, stmt, idx, PROXY_DB_BIND_TYPE_INT, &int_val); fail_unless(res == 0, "Failed to bind INT value: %s", strerror(errno)); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close database: %s", strerror(errno)); (void) unlink(db_test_table); }
END_TEST START_TEST (db_open_with_version_test) { int res, flags = 0; const char *table_path, *schema_name; unsigned int schema_version; res = proxy_db_open_with_version(NULL, NULL, NULL, 0, 0); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)", strerror(errno), errno); (void) unlink(db_test_table); table_path = db_test_table; schema_name = "proxy_test"; schema_version = 0; if (getenv("TRAVIS_CI") != NULL) { /* Disable the integrity checks, vacuuming for these tests. */ flags |= PROXY_DB_OPEN_FL_SKIP_VACUUM; } mark_point(); res = proxy_db_open_with_version(p, table_path, schema_name, schema_version, flags); fail_unless(res == 0, "Failed to open table '%s', schema '%s', version %u: %s", table_path, schema_name, schema_version, strerror(errno)); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close database: %s", strerror(errno)); mark_point(); schema_version = 76; flags |= PROXY_DB_OPEN_FL_ERROR_ON_SCHEMA_VERSION_SKEW; res = proxy_db_open_with_version(p, table_path, schema_name, schema_version, flags); fail_unless(res < 0, "Opened table with version skew unexpectedly"); fail_unless(errno == EPERM, "Expected EPERM (%d), got '%s' (%d)", EPERM, strerror(errno), errno); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close database: %s", strerror(errno)); mark_point(); flags &= ~PROXY_DB_OPEN_FL_ERROR_ON_SCHEMA_VERSION_SKEW; res = proxy_db_open_with_version(p, table_path, schema_name, schema_version, flags); fail_unless(res == 0, "Failed to open table '%s', schema '%s', version %u: %s", table_path, schema_name, schema_version, strerror(errno)); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close database: %s", strerror(errno)); mark_point(); schema_version = 76; res = proxy_db_open_with_version(p, table_path, schema_name, schema_version, flags); fail_unless(res == 0, "Failed to open table '%s', schema '%s', version %u: %s", table_path, schema_name, schema_version, strerror(errno)); res = proxy_db_close(p, schema_name); fail_unless(res == 0, "Failed to detach schema '%s': %s", schema_name, strerror(errno)); mark_point(); schema_version = 99; res = proxy_db_open_with_version(p, table_path, schema_name, schema_version, flags); fail_unless(res == 0, "Failed to open table '%s', schema '%s', version %u: %s", table_path, schema_name, schema_version, strerror(errno)); res = proxy_db_close(p, NULL); fail_unless(res == 0, "Failed to close database: %s", strerror(errno)); (void) unlink(db_test_table); }
int proxy_db_open_with_version(pool *p, const char *table_path, const char *schema_name, unsigned int schema_version, int flags) { pool *tmp_pool; int res, xerrno = 0; unsigned int current_version = 0; res = proxy_db_open(p, table_path, schema_name); if (res < 0) { return -1; } tmp_pool = make_sub_pool(p); res = get_schema_version(tmp_pool, schema_name, ¤t_version); if (res < 0) { xerrno = errno; destroy_pool(tmp_pool); errno = xerrno; return -1; } if (current_version >= schema_version) { pr_trace_msg(trace_channel, 11, "schema version %u >= desired version %u for schema '%s'", current_version, schema_version, schema_name); return 0; } if (flags & PROXY_DB_OPEN_FL_ERROR_ON_SCHEMA_VERSION_SKEW) { pr_trace_msg(trace_channel, 5, "schema version %u < desired version %u for schema '%s', failing", current_version, schema_version, schema_name); destroy_pool(tmp_pool); errno = EPERM; return -1; } proxy_db_close(p, schema_name); if (unlink(table_path) < 0) { pr_log_pri(PR_LOG_NOTICE, MOD_PROXY_VERSION ": error deleting '%s': %s", table_path, strerror(errno)); } res = proxy_db_open(p, table_path, schema_name); if (res < 0) { xerrno = errno; destroy_pool(tmp_pool); errno = xerrno; return -1; } res = set_schema_version(tmp_pool, schema_name, schema_version); xerrno = errno; destroy_pool(tmp_pool); if (res < 0) { errno = xerrno; return -1; } return 0; }