blake.io/pqx@v0.2.2-0.20231231055241-83f2254c0a07/pqx_test.go (about) 1 package pqx_test 2 3 import ( 4 "bytes" 5 "database/sql" 6 "flag" 7 "fmt" 8 "io" 9 "os" 10 "os/exec" 11 "strings" 12 "testing" 13 "time" 14 15 "blake.io/pqx/pqxtest" 16 _ "github.com/lib/pq" 17 ) 18 19 func TestMain(m *testing.M) { 20 if os.Getenv("TESTING_ORPHAN") != "" { 21 flag.Parse() 22 23 // pqxtest bases the data directory off of the working 24 // directory, and we want to avoid conflicts with the parent 25 // process's postgres, so jump to a different directory before 26 // starting postgres with pqxtest as the child. 27 dir, err := os.MkdirTemp("", "pqxtest") 28 if err != nil { 29 panic(err) 30 } 31 _ = os.Chdir(dir) 32 33 os.Unsetenv("TESTING_ORPHAN") 34 pqxtest.Start(5*time.Second, 0) 35 36 // picked up by TestOrphan 37 fmt.Printf("dsn: %q\n", pqxtest.DSN()) 38 39 go func() { 40 panic("intentional panic") 41 }() 42 select {} // panic will kill us 43 } else { 44 pqxtest.TestMain(m) 45 } 46 } 47 48 func TestStart(t *testing.T) { 49 const schema = `CREATE TABLE foo (n int);` 50 db := pqxtest.CreateDB(t, schema) 51 _, err := db.Exec(`INSERT into foo values (1)`) 52 if err != nil { 53 t.Fatal(err) 54 } 55 } 56 57 func TestSubTestNames(t *testing.T) { 58 cases := []string{ 59 "a", 60 "a b c", 61 "a, b, c", 62 "(a)", 63 "(B)", 64 "a-b-c", 65 "*a*b*c", 66 "a*b*c", 67 } 68 69 for _, name := range cases { 70 t.Run(name, func(t *testing.T) { pqxtest.CreateDB(t, "") }) 71 } 72 } 73 74 func TestOrphan(t *testing.T) { 75 exe, err := os.Executable() 76 if err != nil { 77 t.Fatal(err) 78 } 79 cmd := exec.Command(exe, "-test.run=none") 80 cmd.Env = append(os.Environ(), "TESTING_ORPHAN=1") 81 out, err := cmd.CombinedOutput() 82 if err == nil { 83 t.Fatal("expected error") 84 } 85 t.Logf("output: \n%s", out) 86 if !strings.Contains(string(out), "intentional panic") { 87 t.Fatalf("expected panic") 88 } 89 r := bytes.NewReader(out) 90 dsn := scanString(t, r, "dsn: %q\n") 91 db, err := sql.Open("postgres", dsn) 92 if err != nil { 93 t.Fatal(err) 94 } 95 defer db.Close() 96 97 for { 98 if err := db.Ping(); err == nil { 99 t.Logf("ping failed: %v", err) 100 time.Sleep(100 * time.Millisecond) 101 continue 102 } 103 break 104 } 105 106 } 107 108 func TestParallel(t *testing.T) { 109 for i := 0; i < 10; i++ { 110 t.Run("r", func(t *testing.T) { 111 t.Parallel() 112 db := pqxtest.CreateDB(t, "") 113 _, err := db.Exec(`SELECT 1`) 114 if err != nil { 115 t.Fatal(err) 116 } 117 }) 118 } 119 t.Run("wait", func(t *testing.T) { 120 t.Logf("waiting") 121 }) 122 } 123 124 func scanString(t *testing.T, r io.Reader, format string) string { 125 t.Helper() 126 var s string 127 _, err := fmt.Fscanf(r, format, &s) 128 if err != nil { 129 t.Fatal(err) 130 } 131 return s 132 }