#!/usr/bin/env bats load $BATS_TEST_DIRNAME/helper/common.bash setup() { setup_common TMPDIRS=$(pwd)/tmpdirs mkdir -p $TMPDIRS/{bac1,rem1,repo1} # repo1 -> bac1 -> repo2 cd $TMPDIRS/repo1 dolt init dolt branch feature dolt remote add backup1 file://../bac1 dolt remote add remote1 file://../rem1 dolt push remote1 main cd $TMPDIRS } teardown() { teardown_common rm -rf $TMPDIRS cd $BATS_TMPDIR } @test "replication: configuration errors" { cd repo1 dolt sql -q "SET @@persist.dolt_read_replica_remote = 'doesNotExist';" run dolt sql -q "show tables" [ "$status" -eq 0 ] [[ "$output" =~ "replication disabled" ]] || false dolt sql -q "SET @@persist.dolt_read_replica_remote = 'remote1';" run dolt sql -q "show tables" [ "$status" -eq 0 ] [[ "$output" =~ "replication disabled" ]] || false dolt sql -q "SET @@persist.dolt_replicate_all_heads = 1"; dolt sql -q "SET @@persist.dolt_replicate_heads = 'main';"; run dolt sql -q "show tables" [ "$status" -eq 0 ] [[ "$output" =~ "replication disabled" ]] || false dolt sql -q "SET @@persist.dolt_replicate_heads = '';"; run dolt sql -q "show tables" [ "$status" -eq 0 ] [[ ! "$output" =~ "replication disabled" ]] || false } @test "replication: default no replication" { cd repo1 dolt sql -q "create table t1 (a int primary key)" dolt add . dolt commit -am "cm" [ ! -d "../bac1/.dolt" ] || false } @test "replication: push on cli commit" { cd repo1 dolt config --local --add sqlserver.global.dolt_replicate_to_remote backup1 dolt sql -q "create table t1 (a int primary key)" dolt add . dolt commit -am "cm" cd .. run dolt clone file://./bac1 repo2 [ "$status" -eq 0 ] cd repo2 run dolt ls [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] [[ "$output" =~ "t1" ]] || false } @test "replication: push on cli engine commit" { cd repo1 dolt config --local --add sqlserver.global.dolt_replicate_to_remote backup1 dolt sql -q "create table t1 (a int primary key)" dolt sql -q "call dolt_add('.')" dolt sql -q "call dolt_commit('-am', 'cm')" cd .. dolt clone file://./bac1 repo2 cd repo2 run dolt ls [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] [[ "$output" =~ "t1" ]] || false } @test "replication: push branch delete" { cd repo1 dolt push remote1 feature dolt config --local --add sqlserver.global.dolt_replicate_to_remote remote1 dolt sql -q "call dolt_branch('-df', 'feature');" cd .. dolt clone file://./rem1 repo2 cd repo2 run dolt sql -q "select name from dolt_branches" -r csv [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] [[ "$output" =~ "main" ]] || false [[ ! "$output" =~ "feature" ]] || false } @test "replication: push tag delete, pull delete on read" { cd repo1 dolt tag tag1 dolt tag tag2 dolt push remote1 tag1 dolt push remote1 tag2 cd .. dolt clone file://./rem1 repo2 cd repo2 dolt config --local --add sqlserver.global.dolt_read_replica_remote origin dolt config --local --add sqlserver.global.dolt_replicate_all_heads 1 run dolt sql -q "select tag_name from dolt_tags" -r csv [ "$status" -eq 0 ] [[ "$output" =~ "tag1" ]] || false [[ "$output" =~ "tag2" ]] || false cd ../repo1 dolt config --local --add sqlserver.global.dolt_replicate_to_remote remote1 dolt tag -d tag1 cd ../repo2 run dolt sql -q "select tag_name from dolt_tags" -r csv [ "$status" -eq 0 ] [[ ! "$output" =~ "tag1" ]] || false [[ "$output" =~ "tag2" ]] || false } @test "replication: pull branch delete on read" { cd repo1 dolt push remote1 feature cd .. dolt clone file://./rem1 repo2 cd repo2 dolt push origin :feature cd ../repo1 run dolt sql -q "select name from dolt_branches" -r csv [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] [[ "$output" =~ "main" ]] || false [[ "$output" =~ "feature" ]] || false dolt config --local --add sqlserver.global.dolt_read_replica_remote remote1 dolt config --local --add sqlserver.global.dolt_replicate_all_heads 1 run dolt sql -q "select name from dolt_branches" -r csv [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] [[ "$output" =~ "main" ]] || false [[ ! "$output" =~ "feature" ]] || false } # Asserts that when a branch is deleted and a tag is created and they have the same name, # the replica is able to correctly apply both changes. @test "replication: pull branch delete and tag create with same name on read" { # Configure repo1 to push changes on commit and create branch b1 cd repo1 dolt config --local --add sqlserver.global.dolt_replicate_to_remote remote1 dolt sql -q "call dolt_branch('b1');" # Configure repo2 to pull changes on read and assert the b1 branch exists cd .. dolt clone file://./rem1 repo2 cd repo2 dolt config --local --add sqlserver.global.dolt_read_replica_remote origin dolt config --local --add sqlserver.global.dolt_replicate_all_heads 1 run dolt sql -q "select name from dolt_branches" -r csv [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] [[ "$output" =~ "name" ]] || false [[ "$output" =~ "main" ]] || false [[ "$output" =~ "b1" ]] || false # Delete branch b1 in repo1 and create tag b1 cd ../repo1 dolt sql -q "call dolt_branch('-D', 'b1'); call dolt_tag('b1');" # Confirm that branch b1 is deleted and tag b1 is created in repo2 cd ../repo2 run dolt sql -q "select name from dolt_branches" -r csv [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] [[ "$output" =~ "main" ]] || false run dolt sql -q "select tag_name from dolt_tags" -r csv [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] [[ "$output" =~ "tag_name" ]] || false [[ "$output" =~ "b1" ]] || false } # When a replica pulls refs, the remote refs are compared with the local refs to identify which local refs # need to be deleted. Branches, tags, and remotes all share the ref space and previous versions of Dolt could # incorrectly map remote refs and local refs, resulting in local refs being incorrectly removed, until future # runs of replica synchronization. @test "replication: local tag refs are not deleted" { # Configure repo1 to push changes on commit and create tag a1 cd repo1 dolt config --local --add sqlserver.global.dolt_replicate_to_remote remote1 dolt sql -q "call dolt_tag('a1');" # Configure repo2 to pull changes on read cd .. dolt clone file://./rem1 repo2 cd repo2 dolt config --local --add sqlserver.global.dolt_read_replica_remote origin dolt config --local --add sqlserver.global.dolt_replicate_all_heads 1 run dolt sql -q "select tag_name from dolt_tags;" [ "$status" -eq 0 ] [[ "$output" =~ "| tag_name |" ]] || false [[ "$output" =~ "| a1 |" ]] || false # Create branch new1 in repo1 – "new1" sorts after "main", but before "a1", and previous # versions of Dolt had problems computing which local refs to delete in this case. cd ../repo1 dolt sql -q "call dolt_branch('new1');" # Confirm that tag a1 has not been deleted. Note that we need to check for this immediately after # creating branch new1 (i.e. before looking at branches), because the bug in the previous versions # of Dolt would only manifest in the next command, and would be fixed by later remote pulls. cd ../repo2 run dolt sql -q "select tag_name from dolt_tags;" [ "$status" -eq 0 ] [[ "$output" =~ "| tag_name |" ]] || false [[ "$output" =~ "| a1 |" ]] || false # Try again to make sure the results are stable run dolt sql -q "select tag_name from dolt_tags;" [ "$status" -eq 0 ] [[ "$output" =~ "| tag_name |" ]] || false [[ "$output" =~ "| a1 |" ]] || false } @test "replication: pull branch delete current branch" { skip "broken by latest transaction changes" cd repo1 dolt push remote1 feature cd .. dolt clone file://./rem1 repo2 cd repo2 dolt push origin :feature cd ../repo1 run dolt sql -q "select name from dolt_branches" -r csv [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 3 ] [[ "$output" =~ "main" ]] || false [[ "$output" =~ "feature" ]] || false dolt config --local --add sqlserver.global.dolt_read_replica_remote remote1 dolt config --local --add sqlserver.global.dolt_replicate_all_heads 1 dolt checkout feature run dolt sql -q "select name from dolt_branches" -r csv [ "$status" -eq 0 ] [ "${#lines[@]}" -eq 2 ] [[ "$output" =~ "main" ]] || false [[ ! "$output" =~ "feature" ]] || false } @test "replication: table functions work" { cd repo1 dolt sql <