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  }