integration-tests/go-sql-server-driver: sqlserver_lock_test.go: Add a test documenting the current odd behavior where you can run two sql-servers against the same directory if they have no DoltDBs.

This commit is contained in:
Aaron Son
2023-11-29 17:57:06 -08:00
parent 751840ea61
commit 2e9546d902
@@ -29,270 +29,294 @@ import (
)
func TestSQLServerLockFile(t *testing.T) {
u, err := driver.NewDoltUser()
require.NoError(t, err)
t.Cleanup(func() {
u.Cleanup()
})
t.Run("With Two Repos", func(t *testing.T) {
u, err := driver.NewDoltUser()
require.NoError(t, err)
t.Cleanup(func() {
u.Cleanup()
})
rs, err := u.MakeRepoStore()
require.NoError(t, err)
dbOne, err := rs.MakeRepo("db_one")
require.NoError(t, err)
dbTwo, err := rs.MakeRepo("db_two")
require.NoError(t, err)
rs, err := u.MakeRepoStore()
require.NoError(t, err)
dbOne, err := rs.MakeRepo("db_one")
require.NoError(t, err)
dbTwo, err := rs.MakeRepo("db_two")
require.NoError(t, err)
t.Run("With server running in root", func(t *testing.T) {
RunServerUntilEndOfTest(t, rs, &driver.Server{})
t.Run("With server running in root", func(t *testing.T) {
RunServerUntilEndOfTest(t, rs, &driver.Server{})
t.Run("sql-server.lock file exists", func(t *testing.T) {
t.Run("sql-server.lock file exists", func(t *testing.T) {
location := filepath.Join(rs.Dir, ".dolt/sql-server.lock")
f, err := os.Open(location)
require.NoError(t, err)
require.NoError(t, f.Close())
})
t.Run("Running again in root fails", func(t *testing.T) {
_ = MakeServer(t, rs, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running in db_one fails", func(t *testing.T) {
_ = MakeServer(t, dbOne, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running dolt sql -q in /server connects to server", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("Running dolt sql -q in /server/db_two connects to server on db_two", func(t *testing.T) {
cmd := dbTwo.DoltCmd("sql", "-q", "select database()")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_two", outstr)
})
t.Run("Running dolt sql -q in /server/db_two/.dolt/noms connects to server on no database", func(t *testing.T) {
cmd := dbTwo.DoltCmd("sql", "-q", "select database()")
cmd.Dir = filepath.Join(cmd.Dir, ".dolt/noms")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "NULL", outstr)
cmd = dbTwo.DoltCmd("sql", "-q", "show databases")
cmd.Dir = filepath.Join(cmd.Dir, ".dolt/noms")
output, err = cmd.CombinedOutput()
outstr = string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
})
t.Run("sql-server.lock in root no longer exists", func(t *testing.T) {
location := filepath.Join(rs.Dir, ".dolt/sql-server.lock")
f, err := os.Open(location)
require.NoError(t, err)
require.NoError(t, f.Close())
if f != nil {
defer f.Close()
}
require.ErrorIs(t, err, fs.ErrNotExist)
})
t.Run("Running again in root fails", func(t *testing.T) {
_ = MakeServer(t, rs, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running in db_one fails", func(t *testing.T) {
_ = MakeServer(t, dbOne, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running dolt sql -q in /server connects to server", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("Running dolt sql -q in /server/db_two connects to server on db_two", func(t *testing.T) {
cmd := dbTwo.DoltCmd("sql", "-q", "select database()")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_two", outstr)
})
t.Run("Running dolt sql -q in /server/db_two/.dolt/noms connects to server on no database", func(t *testing.T) {
cmd := dbTwo.DoltCmd("sql", "-q", "select database()")
cmd.Dir = filepath.Join(cmd.Dir, ".dolt/noms")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "NULL", outstr)
cmd = dbTwo.DoltCmd("sql", "-q", "show databases")
cmd.Dir = filepath.Join(cmd.Dir, ".dolt/noms")
output, err = cmd.CombinedOutput()
outstr = string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
})
t.Run("sql-server.lock in root no longer exists", func(t *testing.T) {
location := filepath.Join(rs.Dir, ".dolt/sql-server.lock")
f, err := os.Open(location)
if f != nil {
defer f.Close()
}
require.ErrorIs(t, err, fs.ErrNotExist)
})
t.Run("With server running in db_one", func(t *testing.T) {
RunServerUntilEndOfTest(t, dbOne, &driver.Server{})
t.Run("Running server in root fails", func(t *testing.T) {
_ = MakeServer(t, rs, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running server in db_two succeeds", func(t *testing.T) {
RunServerUntilEndOfTest(t, dbTwo, &driver.Server{
Args: []string{"--port", "3310"},
Port: 3310,
})
})
t.Run("dolt sql -q in root succeeds", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("dolt sql -q in root can write to db_two", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_two.vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.NoError(t, err)
})
t.Run("dolt sql -q in root cannot write to db_one", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_one.vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.Error(t, err)
})
})
t.Run("Given a running dolt sql process in root", func(t *testing.T) {
RunDoltSQLUntilEndOfTest(t, rs)
t.Run("Running server in root fails", func(t *testing.T) {
_ = MakeServer(t, rs, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running server in db_one fails", func(t *testing.T) {
_ = MakeServer(t, dbOne, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("dolt sql -q in root succeeds", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("dolt sql -q in root cannot write to db_one", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_one.vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.Error(t, err)
})
})
t.Run("Given a running dolt sql process in db_one", func(t *testing.T) {
RunDoltSQLUntilEndOfTest(t, dbOne)
t.Run("Running server in root fails", func(t *testing.T) {
_ = MakeServer(t, rs, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running server in db_one fails", func(t *testing.T) {
_ = MakeServer(t, dbOne, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running server in db_two succeeds", func(t *testing.T) {
RunServerUntilEndOfTest(t, dbTwo, &driver.Server{})
})
t.Run("dolt sql -q in root succeeds", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("dolt sql -q in root can write to db_two", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_two.another_vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.NoError(t, err)
})
t.Run("dolt sql -q in root cannot write to db_one", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_one.vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.Error(t, err)
})
})
t.Run("With stale sql-server.lock file in root", func(t *testing.T) {
Setup := func(t *testing.T) {
path := filepath.Join(rs.Dir, ".dolt/sql-server.lock")
err := os.WriteFile(path, []byte("1:3306:this_is_not_a_real_secret"), 0600)
require.NoError(t, err)
t.Cleanup(func() { os.Remove(path) })
}
t.Run("sql-server can run in root", func(t *testing.T) {
Setup(t)
RunServerUntilEndOfTest(t, rs, &driver.Server{})
})
t.Run("sql-server can run in db_one", func(t *testing.T) {
Setup(t)
t.Run("With server running in db_one", func(t *testing.T) {
RunServerUntilEndOfTest(t, dbOne, &driver.Server{})
})
t.Run("sql can run in root", func(t *testing.T) {
Setup(t)
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("sql can run in db_one", func(t *testing.T) {
Setup(t)
cmd := dbOne.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
})
})
t.Run("With malformed sql-server.lock file in root", func(t *testing.T) {
Setup := func(t *testing.T) {
path := filepath.Join(rs.Dir, ".dolt/sql-server.lock")
err := os.WriteFile(path, []byte("1:3306:this_is_not_a_real_secret:extra:fields:make:it:fail"), 0600)
require.NoError(t, err)
t.Cleanup(func() { os.Remove(path) })
}
t.Run("sql-server can run in root", func(t *testing.T) {
Setup(t)
RunServerUntilEndOfTest(t, rs, &driver.Server{})
})
t.Run("sql-server can run in db_one", func(t *testing.T) {
Setup(t)
RunServerUntilEndOfTest(t, rs, &driver.Server{})
})
t.Run("sql can run in root", func(t *testing.T) {
Setup(t)
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("sql can run in db_one", func(t *testing.T) {
Setup(t)
cmd := dbOne.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
})
t.Run("with dolt sql running in db_one", func(t *testing.T) {
RunDoltSQLUntilEndOfTest(t, dbOne)
t.Run("dolt sql -q fails in db_one", func(t *testing.T) {
Setup(t)
cmd := dbOne.DoltCmd("sql", "-q", "show databases")
_, err = cmd.CombinedOutput()
t.Run("Running server in root fails", func(t *testing.T) {
_ = MakeServer(t, rs, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running server in db_two succeeds", func(t *testing.T) {
RunServerUntilEndOfTest(t, dbTwo, &driver.Server{
Args: []string{"--port", "3310"},
Port: 3310,
})
})
t.Run("dolt sql -q in root succeeds", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("dolt sql -q in root can write to db_two", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_two.vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.NoError(t, err)
})
t.Run("dolt sql -q in root cannot write to db_one", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_one.vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.Error(t, err)
})
t.Run("dolt sql -q succeeds in root", func(t *testing.T) {
})
t.Run("Given a running dolt sql process in root", func(t *testing.T) {
RunDoltSQLUntilEndOfTest(t, rs)
t.Run("Running server in root fails", func(t *testing.T) {
_ = MakeServer(t, rs, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running server in db_one fails", func(t *testing.T) {
_ = MakeServer(t, dbOne, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("dolt sql -q in root succeeds", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("dolt sql -q in root cannot write to db_one", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_one.vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.Error(t, err)
})
})
t.Run("Given a running dolt sql process in db_one", func(t *testing.T) {
RunDoltSQLUntilEndOfTest(t, dbOne)
t.Run("Running server in root fails", func(t *testing.T) {
_ = MakeServer(t, rs, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running server in db_one fails", func(t *testing.T) {
_ = MakeServer(t, dbOne, &driver.Server{
ErrorMatches: []string{
"locked by another dolt process",
},
})
})
t.Run("Running server in db_two succeeds", func(t *testing.T) {
RunServerUntilEndOfTest(t, dbTwo, &driver.Server{})
})
t.Run("dolt sql -q in root succeeds", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("dolt sql -q in root can write to db_two", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_two.another_vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.NoError(t, err)
})
t.Run("dolt sql -q in root cannot write to db_one", func(t *testing.T) {
cmd := rs.DoltCmd("sql", "-q", "create table db_one.vals (id int primary key)")
_, err := cmd.CombinedOutput()
require.Error(t, err)
})
})
t.Run("With stale sql-server.lock file in root", func(t *testing.T) {
Setup := func(t *testing.T) {
path := filepath.Join(rs.Dir, ".dolt/sql-server.lock")
err := os.WriteFile(path, []byte("1:3306:this_is_not_a_real_secret"), 0600)
require.NoError(t, err)
t.Cleanup(func() { os.Remove(path) })
}
t.Run("sql-server can run in root", func(t *testing.T) {
Setup(t)
RunServerUntilEndOfTest(t, rs, &driver.Server{})
})
t.Run("sql-server can run in db_one", func(t *testing.T) {
Setup(t)
RunServerUntilEndOfTest(t, dbOne, &driver.Server{})
})
t.Run("sql can run in root", func(t *testing.T) {
Setup(t)
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
require.NoError(t, err)
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("sql can run in db_one", func(t *testing.T) {
Setup(t)
cmd := dbOne.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
})
})
t.Run("With malformed sql-server.lock file in root", func(t *testing.T) {
Setup := func(t *testing.T) {
path := filepath.Join(rs.Dir, ".dolt/sql-server.lock")
err := os.WriteFile(path, []byte("1:3306:this_is_not_a_real_secret:extra:fields:make:it:fail"), 0600)
require.NoError(t, err)
t.Cleanup(func() { os.Remove(path) })
}
t.Run("sql-server can run in root", func(t *testing.T) {
Setup(t)
RunServerUntilEndOfTest(t, rs, &driver.Server{})
})
t.Run("sql-server can run in db_one", func(t *testing.T) {
Setup(t)
RunServerUntilEndOfTest(t, rs, &driver.Server{})
})
t.Run("sql can run in root", func(t *testing.T) {
Setup(t)
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
t.Run("sql can run in db_one", func(t *testing.T) {
Setup(t)
cmd := dbOne.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
outstr := string(output)
require.NoError(t, err)
require.Regexp(t, "db_one", outstr)
})
t.Run("with dolt sql running in db_one", func(t *testing.T) {
RunDoltSQLUntilEndOfTest(t, dbOne)
t.Run("dolt sql -q fails in db_one", func(t *testing.T) {
Setup(t)
cmd := dbOne.DoltCmd("sql", "-q", "show databases")
_, err = cmd.CombinedOutput()
require.Error(t, err)
})
t.Run("dolt sql -q succeeds in root", func(t *testing.T) {
Setup(t)
cmd := rs.DoltCmd("sql", "-q", "show databases")
output, err := cmd.CombinedOutput()
require.NoError(t, err)
outstr := string(output)
require.Regexp(t, "db_one", outstr)
require.Regexp(t, "db_two", outstr)
})
})
})
})
t.Run("With Empty RepoStore", func(t *testing.T) {
u, err := driver.NewDoltUser()
require.NoError(t, err)
t.Cleanup(func() {
u.Cleanup()
})
rs, err := u.MakeRepoStore()
require.NoError(t, err)
// TODO: This is strange behavior which the current implementation allows.
// If the top-level directory is empty when both servers are
// started, they can both run against it. Only one of their
// credential files will win the write.
t.Run("Can Run Two Servers At Once", func(t *testing.T) {
RunServerUntilEndOfTest(t, rs, &driver.Server{})
RunServerUntilEndOfTest(t, rs, &driver.Server{
Args: []string{"--port", "3309"},
Port: 3309,
})
})
})
}