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  }