Live video on the AT Protocol
at eli/detox-testing-github 139 lines 2.8 kB view raw
1package statedb 2 3import ( 4 "fmt" 5 "net/url" 6 "os" 7 "os/exec" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/google/uuid" 13 "github.com/stretchr/testify/require" 14 "gorm.io/driver/postgres" 15 "stream.place/streamplace/pkg/config" 16 "stream.place/streamplace/pkg/model" 17) 18 19var postgresURL string 20 21func TestMain(m *testing.M) { 22 postgresCommand := os.Getenv("STREAMPLACE_TEST_POSTGRES_COMMAND") 23 postgresURL = os.Getenv("STREAMPLACE_TEST_POSTGRES_URL") 24 if postgresCommand != "" { 25 // Start postgres process 26 fmt.Printf("Starting postgres process with command: %s\n", postgresCommand) 27 cmd := exec.Command("bash", "-c", postgresCommand) 28 err := cmd.Start() 29 if err != nil { 30 fmt.Printf("Failed to start postgres: %v\n", err) 31 os.Exit(1) 32 } 33 34 // Give postgres time to start up 35 time.Sleep(2 * time.Second) 36 37 // Run tests 38 exitCode := m.Run() 39 40 // Clean up postgres process 41 if cmd.Process != nil { 42 cmd2 := exec.Command("pkill", "postgres") 43 err := cmd2.Run() 44 if err != nil { 45 fmt.Printf("Failed to kill postgres: %v\n", err) 46 } 47 } 48 49 os.Exit(exitCode) 50 return 51 } 52 os.Exit(m.Run()) 53} 54 55func makePostgresURL(t *testing.T) string { 56 u, err := url.Parse(postgresURL) 57 if err != nil { 58 panic(err) 59 } 60 uu, err := uuid.NewV7() 61 if err != nil { 62 panic(err) 63 } 64 dbName := fmt.Sprintf("test_%s", strings.ReplaceAll(uu.String(), "-", "_")) 65 u.Path = fmt.Sprintf("/%s", dbName) 66 t.Cleanup(func() { 67 u, err := url.Parse(postgresURL) 68 if err != nil { 69 panic(err) 70 } 71 u.Path = "/postgres" 72 rootDial := postgres.Open(u.String()) 73 74 db, err := openDB(rootDial) 75 if err != nil { 76 t.Logf("Failed to open database: %v", err) 77 return 78 } 79 80 // Drop the test database 81 err = db.Exec(fmt.Sprintf("DROP DATABASE %s", dbName)).Error 82 if err != nil { 83 t.Logf("Failed to drop test database: %v", err) 84 } 85 }) 86 return u.String() 87} 88 89func TestPostgresLocks(t *testing.T) { 90 if postgresURL == "" { 91 t.Skip("no postgres url, skipping postgres tests") 92 return 93 } 94 dburl := makePostgresURL(t) 95 cli := config.CLI{ 96 DBURL: dburl, 97 } 98 mod, err := model.MakeDB(":memory:") 99 require.NoError(t, err) 100 state, err := MakeDB(&cli, nil, mod) 101 require.NoError(t, err) 102 103 unlock, err := state.GetNamedLock("test") 104 t.Log("got lock") 105 require.NoError(t, err) 106 require.NotNil(t, unlock) 107 108 shouldBeLocked := true 109 110 done := make(chan struct{}) 111 112 go func() { 113 unlock2, err := state.GetNamedLock("test") 114 t.Log("got lock 2") 115 require.Equal(t, shouldBeLocked, false) 116 require.NoError(t, err) 117 require.NotNil(t, unlock2) 118 unlock2() 119 close(done) 120 }() 121 122 time.Sleep(1 * time.Second) 123 124 t.Log("unlocking") 125 shouldBeLocked = false 126 unlock() 127 t.Log("unlocked") 128 129 select { 130 case <-done: 131 case <-time.After(1 * time.Second): 132 require.Fail(t, "lock not released") 133 } 134 sqlDB, err := state.DB.DB() 135 require.NoError(t, err) 136 137 // Close 138 sqlDB.Close() 139}