#!/usr/bin/env bats # Bidirectional compatibility tests for doltgresql. # # Each test creates an isolated repository and alternates reads/writes between # two doltgres binaries — an older release (DOLTGRES_LEGACY_BIN) and the current # HEAD build (DOLTGRES_NEW_BIN). The tests run in both directions: the runner # swaps LEGACY and NEW to exercise forward and backward compatibility. # # Unlike the other compatibility tests, each test body manages its own server # lifecycle; setup() and teardown() only manage the scratch directory. # # Environment variables: # DOLTGRES_LEGACY_BIN — path to the "old" doltgres binary # DOLTGRES_NEW_BIN — path to the "new" (HEAD) doltgres binary # REPO_DIR — scratch directory base (empty, just needs to exist) # Note: helper is one directory up from this file. load $BATS_TEST_DIRNAME/../helper/common.bash BATS_REPO="" setup() { BATS_REPO="$BATS_TMPDIR/bidir-$$-$RANDOM" mkdir -p "$BATS_REPO" } teardown() { stop_doltgres rm -rf "$BATS_REPO" } # Convenience wrappers so test bodies read cleanly. old_server_start() { start_doltgres "$DOLTGRES_LEGACY_BIN" "$BATS_REPO" "$BATS_REPO/old.log"; } new_server_start() { start_doltgres "$DOLTGRES_NEW_BIN" "$BATS_REPO" "$BATS_REPO/new.log"; } # --------------------------------------------------------------------------- # Test 1: Scalar types DML — INT, VARCHAR, NUMERIC, TIMESTAMP round-trip. # Four rounds: old → HEAD → old → HEAD. # --------------------------------------------------------------------------- @test "bidirectional: scalar types round-trip across versions" { [ -n "$DOLTGRES_LEGACY_BIN" ] || skip "requires DOLTGRES_LEGACY_BIN" [ -n "$DOLTGRES_NEW_BIN" ] || skip "requires DOLTGRES_NEW_BIN" # --- Setup: old doltgres creates schema and seeds two rows --- old_server_start sql <>'old' FROM typed WHERE pk=6;" [ "$status" -eq 0 ] [[ "$output" =~ "true" ]] || false sql -c "INSERT INTO typed (pk, c_smallint, c_bigint, c_varchar, c_date, c_numeric, c_boolean, c_jsonb) VALUES (7, 70, 7000000, 'varchar-7', '2025-07-01', 21.988, true, '{\"head\":true}');" sql -c "SELECT dolt_add('.'); SELECT dolt_commit('-m', 'head: final insert using all columns');" stop_doltgres # Round 6: old reads HEAD's final insert — all columns visible old_server_start run sql_csv -c "SELECT pk, c_smallint, c_bigint, c_varchar, c_numeric FROM typed WHERE pk=7;" [ "$status" -eq 0 ] [[ "$output" =~ "7,70,7000000,varchar-7,21.988" ]] || false run sql_csv -c "SELECT count(*) FROM typed;" [ "$status" -eq 0 ] [[ "$output" =~ "7" ]] || false stop_doltgres } # --------------------------------------------------------------------------- # Test 6: JSONB round-trip — inline and large JSONB documents across versions. # --------------------------------------------------------------------------- @test "bidirectional: jsonb round-trip across versions" { [ -n "$DOLTGRES_LEGACY_BIN" ] || skip "requires DOLTGRES_LEGACY_BIN" [ -n "$DOLTGRES_NEW_BIN" ] || skip "requires DOLTGRES_NEW_BIN" # Setup: old creates table with small and large JSONB old_server_start sql <>'key', c_small->>'meta' FROM jsondocs WHERE pk=1;" [ "$status" -eq 0 ] [[ "$output" =~ "val1" ]] || false run sql_csv -c "SELECT pk, length(c_big->>'big') FROM jsondocs WHERE pk=2;" [ "$status" -eq 0 ] [[ "$output" =~ "2,5000" ]] || false sql -c "INSERT INTO jsondocs VALUES (3, '{\"head\":true}', json_build_object('hbig', repeat('H', 6000))::jsonb);" sql -c "UPDATE jsondocs SET c_small=c_small || '{\"updated\":true}' WHERE pk=1;" sql -c "SELECT dolt_add('.'); SELECT dolt_commit('-m', 'head: insert row 3, update row 1');" stop_doltgres # Round 2: old reads HEAD's changes old_server_start run sql_csv -c "SELECT pk, c_small->>'head' FROM jsondocs WHERE pk=3;" [ "$status" -eq 0 ] [[ "$output" =~ "true" ]] || false run sql_csv -c "SELECT pk, c_small->>'updated' FROM jsondocs WHERE pk=1;" [ "$status" -eq 0 ] [[ "$output" =~ "true" ]] || false run sql_csv -c "SELECT pk, length(c_big->>'hbig') FROM jsondocs WHERE pk=3;" [ "$status" -eq 0 ] [[ "$output" =~ "3,6000" ]] || false run sql_csv -c "SELECT count(*) FROM jsondocs;" [ "$status" -eq 0 ] [[ "$output" =~ "3" ]] || false stop_doltgres }