diff --git a/ci/scripts/build-linux.sh b/ci/scripts/build-linux.sh index e269e71fd..eac84890d 100755 --- a/ci/scripts/build-linux.sh +++ b/ci/scripts/build-linux.sh @@ -52,8 +52,6 @@ function install_platform_specific_dependencies() { make -j && make install popd - # dependencies of update tests - sudo pip install GitPython apt install -y ruby-full gem install bundler diff --git a/ci/scripts/build.sh b/ci/scripts/build.sh index 890effcf3..4b9b18e2b 100755 --- a/ci/scripts/build.sh +++ b/ci/scripts/build.sh @@ -63,6 +63,9 @@ function build_and_install() { bundler popd + # install update and WAL test dependencies + sudo pip install -r /tmp/lantern/scripts/requirements.txt + mkdir build cd build diff --git a/ci/scripts/run-tests-linux.sh b/ci/scripts/run-tests-linux.sh index 6c22b6c6a..4c02e1866 100755 --- a/ci/scripts/run-tests-linux.sh +++ b/ci/scripts/run-tests-linux.sh @@ -53,6 +53,7 @@ function run_db_tests(){ make test && \ make test-parallel && \ make test-client && \ + python3 ../scripts/test_wal.py && \ run_pgvector_tests && \ stop_current_postgres && \ if [[ "$ENABLE_COVERAGE" == "1" ]] diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 000000000..60022edc1 --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1,2 @@ +GitPython==3.1.43 +testgres==1.10.0 diff --git a/scripts/test_wal.py b/scripts/test_wal.py new file mode 100644 index 000000000..19666ddd2 --- /dev/null +++ b/scripts/test_wal.py @@ -0,0 +1,53 @@ +import testgres +import os + +print("Starting replication/WAL tests...") + +VECTOR_QUERY = "SELECT * FROM small_world WHERE b = FALSE order by v <-> '{1,0,0}' LIMIT 3;" + +with testgres.get_new_node() as primary: + + # run inidb + primary.init() + + primary.append_conf('enable_seqscan = off') + + primary.start() + + primary.execute('CREATE EXTENSION lantern') + # testgres safe_psql does not support specifying cwd, so we have to change the cwd of the current + # script to make sure relative paths in the target sql file work in testgres + os.chdir('../test/sql') + primary.safe_psql(filename='hnsw_delete.sql') + # create a backup + with primary.backup() as backup: + + # create and start a new replica + replica = backup.spawn_replica('replica').start() + + # catch up with master node + replica.catchup() + + # make sure we are using the index + assert 'Index Scan using small_world_v_idx on small_world' in str(primary.safe_psql(f"EXPLAIN {VECTOR_QUERY}")) + assert 'Index Scan using small_world_v_idx on small_world' in str(replica.safe_psql(f"EXPLAIN {VECTOR_QUERY}")) + + res = replica.execute(VECTOR_QUERY) + assert res[0][2] == [1.0, 0.0, 0.0] + # take only boolean columns + assert [i[1] for i in res] == [False] + + # Now, let's delete data on primary and see how it propagates to replica + primary.execute("INSERT INTO small_world (id, b, v) VALUES (42, FALSE, '{42,42,42}'), (43, FALSE, '{42,42,42}'), (44, FALSE, '{42,42,42}');") + + res = replica.execute(VECTOR_QUERY) + # changes have not propagated yet + assert res[0][2] == [1.0, 0.0, 0.0] + assert [i[1] for i in res] == [False] + replica.catchup() + res = replica.execute(VECTOR_QUERY) + assert res[0][2] == [1.0, 0.0, 0.0] + assert [i[1] for i in res] == [False, False, False], 'failed %s' % res + +print("WAL tests completed successfully!") +