github.com/markdessain/sqlitego@v1.21.1/tcl_test.go (about) 1 // Copyright 2020 The Sqlite Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package sqlite // import "github.com/markdessain/sqlitego" 6 7 import ( 8 "bytes" 9 "flag" 10 "fmt" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "runtime" 15 "strings" 16 "testing" 17 18 "modernc.org/tcl" 19 ) 20 21 var ( 22 oMaxError = flag.Uint("maxerror", 0, "argument of -maxerror passed to the Tcl test suite") 23 oStart = flag.String("start", "", "argument of -start passed to the Tcl test suite (-start=[$permutation:]$testfile)") 24 oTclSuite = flag.String("suite", "full", "Tcl test suite [test-file] to run") 25 oVerbose = flag.String("verbose", "0", "argument of -verbose passed to the Tcl test suite, must be set to a boolean (0, 1) or to \"file\"") 26 ) 27 28 func TestTclTest(t *testing.T) { 29 if testing.Short() { 30 t.Skip("skipping test in short mode") 31 } 32 33 if err := setMaxOpenFiles(1024); err != nil { // Avoid misc7.test hanging for a long time. 34 t.Fatal(err) 35 } 36 37 blacklist := map[string]struct{}{} 38 switch runtime.GOARCH { 39 case "386", "arm": 40 // # This test causes thrashing on machines with smaller amounts of 41 // # memory. Make sure the host has at least 8GB available before running 42 // # this test. 43 blacklist["bigsort.test"] = struct{}{} 44 } 45 switch runtime.GOOS { 46 case "windows": 47 // See https://gitlab.com/cznic/sqlite/-/issues/23#note_599920077 for details. 48 blacklist["symlink2.test"] = struct{}{} 49 } 50 tclTests := "testdata/tcl/*" 51 m, err := filepath.Glob(filepath.FromSlash(tclTests)) 52 if err != nil { 53 t.Fatal(err) 54 } 55 56 dir, err := os.MkdirTemp("", "sqlite-test-") 57 if err != nil { 58 t.Fatal(err) 59 } 60 61 defer os.RemoveAll(dir) 62 63 bin := "testfixture" 64 if runtime.GOOS == "windows" { 65 bin += ".exe" 66 } 67 testfixture := filepath.Join(dir, bin) 68 args0 := []string{"build", "-o", testfixture} 69 tags := "-tags=libc.nofsync" 70 if s := *oXTags; s != "" { 71 tags += "," + s 72 } 73 args0 = append(args0, tags, "github.com/markdessain/sqlitego/internal/testfixture") 74 cmd := exec.Command("go", args0...) 75 if out, err := cmd.CombinedOutput(); err != nil { 76 t.Fatalf("%s\n%v", out, err) 77 } 78 79 wd, err := os.Getwd() 80 if err != nil { 81 t.Fatal(err) 82 } 83 84 defer os.Chdir(wd) 85 86 if err := os.Chdir(dir); err != nil { 87 t.Fatal(err) 88 } 89 90 for _, v := range m { 91 if _, ok := blacklist[filepath.Base(v)]; ok { 92 trc("skipping %v", v) 93 continue 94 } 95 96 s := filepath.Join(wd, v) 97 d := filepath.Join(dir, filepath.Base(v)) 98 f, err := os.ReadFile(s) 99 if err != nil { 100 t.Fatal(err) 101 } 102 103 if err := os.WriteFile(d, f, 0660); err != nil { 104 t.Fatal(err) 105 } 106 } 107 108 library := filepath.Join(dir, "library") 109 if err := tcl.Library(library); err != nil { 110 t.Fatal(err) 111 } 112 113 os.Setenv("TCL_LIBRARY", library) 114 var args []string 115 switch s := *oTclSuite; s { 116 case "": 117 args = []string{"all.test"} 118 default: 119 a := strings.Split(s, " ") 120 args = append([]string{"permutations.test"}, a...) 121 } 122 if *oVerbose != "" { 123 args = append(args, fmt.Sprintf("-verbose=%s", *oVerbose)) 124 } 125 if *oMaxError != 0 { 126 args = append(args, fmt.Sprintf("-maxerror=%d", *oMaxError)) 127 } 128 if *oStart != "" { 129 args = append(args, fmt.Sprintf("-start=%s", *oStart)) 130 } 131 os.Setenv("PATH", fmt.Sprintf("%s%c%s", dir, os.PathListSeparator, os.Getenv("PATH"))) 132 cmd = exec.Command(bin, args...) 133 var w echoWriter 134 cmd.Stdout = &w 135 cmd.Stderr = &w 136 if err := cmd.Run(); err != nil { 137 t.Fatal(err) 138 } 139 140 if b := w.w.Bytes(); bytes.Contains(b, []byte("while executing")) { 141 t.Fatal("silent/unreported error detected in output") 142 } 143 } 144 145 type echoWriter struct { 146 w bytes.Buffer 147 } 148 149 func (w *echoWriter) Write(b []byte) (int, error) { 150 os.Stdout.Write(b) 151 return w.w.Write(b) 152 }