-
Notifications
You must be signed in to change notification settings - Fork 1
/
test.go
141 lines (121 loc) · 2.98 KB
/
test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"fmt"
"io/fs"
"os"
"os/exec"
"os/signal"
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
"time"
"github.com/Hellseher/go-shellquote"
)
func main() {
_, file, _, _ := runtime.Caller(0)
testdir := filepath.Dir(file)
logpath := filepath.Join(testdir, "xtemplate.log")
log := try(os.Create(logpath))("open log file")
try(log.Seek(0, 0))("seek to beginning")
defer log.Close()
// recreate the rw directory
{
path := filepath.Join(testdir, "dataw")
try0(os.RemoveAll(path), "delete dataw dir")
try0(os.Mkdir(path, os.ModeDir|os.ModePerm), "create dataw dir")
}
defer func() {
if err := recover(); err != nil {
fmt.Printf("exiting because: %v\n", err)
fmt.Printf("server logs: %s\n", logpath)
}
}()
command := ""
if len(os.Args) > 1 {
command = os.Args[1]
}
if command == "hurl" {
goto hurl
}
// Build xtemplate
{
args := split(`go build -o xtemplate ../cmd`)
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stdout
cmd.Dir = testdir
try0(cmd.Run(), "go build")
fmt.Println("~ Build ~")
}
// Run xtemplate, wait until its ready, exit test if it fails early
{
args := split(`./xtemplate --loglevel -4 -d DB:sql:sqlite3:file:test.sqlite -d FS:fs:./data --config-file config.json`)
cmd := exec.Command(args[0], args[1:]...)
cmd.Dir = testdir
cmd.Stdout = log
cmd.Stderr = log
try0(cmd.Start(), "start xtemplate")
defer kill(cmd)
go func() {
try0(cmd.Wait(), "wait for xtemplate")
time.Sleep(time.Second)
panic("xtemplate exited")
}()
waitUntilFileContainsString(logpath, "starting server")
fmt.Println("~ Run xtemplate ~")
}
hurl:
{
dir := filepath.Join(testdir, "tests")
files := try(fs.Glob(os.DirFS(dir), "*.hurl"))("glob files")
args := append(split("hurl --continue-on-error --test --report-html report"), files...)
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = dir
defer kill(cmd)
try0(cmd.Run(), "run hurl")
fmt.Println("~ Run hurl ~")
}
if command == "start" {
// block until ^C or xtemplate exits
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
fmt.Println("waiting for signal")
<-sigs
}
}
func split(a string) []string { return try(shellquote.Split(a))("split args") }
func kill(c *exec.Cmd) {
err := c.Process.Kill()
if err != nil && err != os.ErrProcessDone {
panic(fmt.Sprintf("failed to kill %s: %v", c.Path, err))
}
}
func try[T any](t T, err error) func(string) T {
return func(desc string) T {
try0(err, desc)
return t
}
}
func try0(err error, desc string) {
if err != nil {
panic(fmt.Sprintf("failed to %s: %v\n", desc, err))
}
}
func waitUntilFileContainsString(filename string, needle string) {
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
for {
if strings.Contains(string(try(os.ReadFile(filename))("read file")), needle) {
wg.Done()
break
}
time.Sleep(10 * time.Millisecond)
}
}()
wg.Wait()
}