-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathpython3_test.go
150 lines (134 loc) · 2.94 KB
/
python3_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
142
143
144
145
146
147
148
149
150
package python3_test
import (
"fmt"
"log"
"net"
"net/http"
"net/http/httptest"
"os"
"os/exec"
"path/filepath"
"syscall"
"testing"
"time"
"github.com/yookoala/gofast/example/python3"
)
func examplePath() string {
basePath, err := os.Getwd()
if err != nil {
panic(err)
}
return filepath.Join(basePath, "webapp.py")
}
func testEnv() error {
// a short script to test python and flup installation
script := `
import sys
try:
from flup.server.fcgi import WSGIServer
except ImportError as err:
print(err)
sys.exit(1)
`
cmd := exec.Command("python", "-c", script)
res, err := cmd.CombinedOutput()
if err == nil {
return err
}
return fmt.Errorf("%s", res)
}
func waitConn(socket string) <-chan net.Conn {
chanConn := make(chan net.Conn)
go func() {
log.Printf("wait for socket: %s", socket)
for {
if conn, err := net.Dial("unix", socket); err != nil {
time.Sleep(time.Millisecond * 2)
} else {
chanConn <- conn
break
}
}
}()
return chanConn
}
func TestHandler(t *testing.T) {
if err := testEnv(); err != nil {
if os.Getenv("CI") != "" {
t.Errorf("environment setup error: %s", err)
return
}
t.Skipf("skip test: %s", err)
return
}
webapp := examplePath()
socket := filepath.Join(filepath.Dir(webapp), "test.sock")
// define webapp.py command
cmd := exec.Command(webapp)
cmd.Env = append(os.Environ(), "TEST_PY3FCGI_SOCK="+socket)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
// start the command and wait for its exit
done := make(chan error, 1)
go func() {
if err := cmd.Start(); err != nil {
done <- err
return
}
// wait if the command started successfully
log.Printf("started successfully")
log.Printf("process=%#v", cmd.Process)
done <- cmd.Wait()
log.Printf("wait ended")
}()
// wait until socket ready
conn := <-waitConn(socket)
conn.Close()
log.Printf("socket ready")
// start the proxy handler
h := python3.NewHandler(webapp, "unix", socket)
//cmd.Wait()
get := func(path string) (w *httptest.ResponseRecorder, err error) {
r, err := http.NewRequest("GET", path, nil)
if err != nil {
return
}
w = httptest.NewRecorder()
h.ServeHTTP(w, r)
return
}
testDone := make(chan bool)
go func() {
w, err := get("/")
if err != nil {
t.Errorf("unexpected error %v", err)
testDone <- false
return
}
if want, have := "hello index", w.Body.String(); want != have {
t.Errorf("expected %#v, got %#v", want, have)
testDone <- false
return
}
testDone <- true
}()
select {
case testSuccess := <-testDone:
if !testSuccess {
log.Printf("test failed")
}
case <-time.After(3 * time.Second):
log.Printf("test timeout")
case err := <-done:
if err != nil {
log.Printf("process done with error = %v", err)
} else {
log.Print("process done gracefully without error")
}
}
log.Printf("send SIGTERM")
if err := cmd.Process.Signal(syscall.SIGTERM); err != nil {
log.Fatal("failed to kill: ", err)
}
log.Println("process killed")
}