Skip to content

Commit 962259c

Browse files
authored
Fix e2e (#682)
* speedup e2e tests * try to detect health of running app in e2e tests
1 parent e33e881 commit 962259c

File tree

13 files changed

+259
-16
lines changed

13 files changed

+259
-16
lines changed

cmd/mockbackend/e2etesting.go

+32-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"bufio"
45
"context"
56
"crypto/sha256"
67
"encoding/base64"
@@ -11,8 +12,10 @@ import (
1112
"math"
1213
"net/http"
1314
"net/url"
15+
"os"
1416
"strconv"
1517
"strings"
18+
"sync"
1619
"time"
1720

1821
merry2 "github.com/ansel1/merry"
@@ -281,21 +284,27 @@ func doTest(logger *zap.Logger, t *Query) []error {
281284
return failures
282285
}
283286

284-
func e2eTest(logger *zap.Logger, noapp bool) bool {
287+
func e2eTest(logger *zap.Logger, noapp, breakOnError bool) bool {
285288
failed := false
286289
logger.Info("will run test",
287290
zap.Any("config", cfg.Test),
288291
)
289292
runningApps := make(map[string]*runner)
290293
if !noapp {
294+
wgStart := sync.WaitGroup{}
291295
for i, c := range cfg.Test.Apps {
292296
r := new(&cfg.Test.Apps[i], logger)
297+
wgStart.Add(1)
293298
runningApps[c.Name] = r
294-
go r.Run()
299+
go func() {
300+
wgStart.Done()
301+
r.Run()
302+
}()
295303
}
296304

297-
logger.Info("will sleep for 5 seconds to start all required apps")
298-
time.Sleep(5 * time.Second)
305+
wgStart.Wait()
306+
logger.Info("will sleep for 1 seconds to start all required apps")
307+
time.Sleep(1 * time.Second)
299308
}
300309

301310
for _, t := range cfg.Test.Queries {
@@ -306,6 +315,22 @@ func e2eTest(logger *zap.Logger, noapp bool) bool {
306315
logger.Error("test failed",
307316
zap.Errors("failures", failures),
308317
)
318+
for _, v := range runningApps {
319+
if !v.IsRunning() {
320+
logger.Error("unexpected app crash", zap.Any("app", v))
321+
}
322+
}
323+
if breakOnError {
324+
for {
325+
fmt.Print("Some queries was failed, press y for continue after debug test:")
326+
in := bufio.NewScanner(os.Stdin)
327+
in.Scan()
328+
s := in.Text()
329+
if s == "y" || s == "Y" {
330+
break
331+
}
332+
}
333+
}
309334
} else {
310335
logger.Info("test OK")
311336
}
@@ -318,6 +343,9 @@ func e2eTest(logger *zap.Logger, noapp bool) bool {
318343

319344
if failed {
320345
logger.Error("tests failed")
346+
for _, v := range runningApps {
347+
logger.Info("app out", zap.Any("app", v), zap.String("out", v.Out()))
348+
}
321349
} else {
322350
logger.Info("All tests OK")
323351
}

cmd/mockbackend/http_common.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,7 @@ func copyResponse(src Response) Response {
9797
Step: src.Data[i].Step,
9898
}
9999

100-
for j := range src.Data[i].Values {
101-
dst.Data[i].Values[j] = src.Data[i].Values[j]
102-
}
100+
copy(dst.Data[i].Values, src.Data[i].Values)
103101
}
104102

105103
return dst

cmd/mockbackend/main.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func main() {
4040
testonly := flag.Bool("testonly", false, "run only unit test")
4141
noapp := flag.Bool("noapp", false, "do not run application")
4242
test := flag.Bool("test", false, "run unit test if present")
43+
breakOnError := flag.Bool("break", false, "break and wait user response if request failed")
4344
flag.Parse()
4445
logger, err := zap.NewProduction()
4546
if err != nil {
@@ -67,6 +68,7 @@ func main() {
6768

6869
httpServers := make([]*http.Server, 0)
6970
wg := sync.WaitGroup{}
71+
wgStart := sync.WaitGroup{}
7072
if !*testonly {
7173
for _, c := range cfg.Listeners {
7274
logger := logger.With(zap.String("listener", c.Address))
@@ -95,28 +97,31 @@ func main() {
9597
mux.HandleFunc("/metrics/find/", listener.findHandler)
9698

9799
wg.Add(1)
100+
wgStart.Add(1)
98101
server := &http.Server{
99102
Addr: listener.Address,
100103
Handler: mux,
101104
}
102105
go func(h *http.Server) {
106+
wgStart.Done()
103107
err = h.ListenAndServe()
104-
if err != nil {
108+
if err != nil && err != http.ErrServerClosed {
105109
logger.Error("failed to start server",
106110
zap.Error(err),
107111
)
108112
}
109113
wg.Done()
110114
}(server)
111115

116+
wgStart.Wait()
112117
httpServers = append(httpServers, server)
113118
}
114119
logger.Info("all listeners started")
115120
}
116121

117122
failed := false
118123
if cfg.Test != nil && (*test || *testonly) {
119-
failed = e2eTest(logger, *noapp)
124+
failed = e2eTest(logger, *noapp, *breakOnError)
120125
}
121126

122127
if !*testonly {

cmd/mockbackend/runner.go

+22-5
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@ import (
44
"context"
55
"fmt"
66
"os/exec"
7+
"sync"
78

9+
"github.com/tevino/abool"
810
"go.uber.org/zap"
911
)
1012

1113
type runner struct {
1214
App
1315

14-
isRunning bool
16+
out string
17+
18+
isRunning *abool.AtomicBool
1519
ctx context.Context
1620
cancel context.CancelFunc
1721
logger *zap.Logger
22+
wg sync.WaitGroup
1823
}
1924

2025
func new(config *App, logger *zap.Logger) *runner {
@@ -23,13 +28,17 @@ func new(config *App, logger *zap.Logger) *runner {
2328
logger: logger.With(
2429
zap.String("name", config.Name),
2530
),
31+
isRunning: abool.New(),
2632
}
2733

2834
return r
2935
}
3036

3137
func (r *runner) Run() {
32-
if r.isRunning {
38+
r.wg.Add(1)
39+
defer r.wg.Done()
40+
41+
if !r.isRunning.SetToIf(false, true) {
3342
r.logger.Fatal("app is already running")
3443
}
3544
r.logger.Debug("will start application",
@@ -39,20 +48,28 @@ func (r *runner) Run() {
3948

4049
cmd := exec.CommandContext(r.ctx, r.Binary, r.Args...)
4150
out, err := cmd.CombinedOutput()
51+
r.out = string(out)
4252
if err != nil {
4353
r.logger.Error("error running program",
4454
zap.Any("config", r.App),
4555
zap.String("output", "will follow next"),
4656
zap.Error(err),
4757
)
48-
fmt.Print(string(out))
58+
fmt.Print(r.out)
4959
}
5060

51-
r.isRunning = true
61+
r.isRunning.UnSet()
5262
}
5363

5464
func (r *runner) Finish() {
5565
r.cancel()
66+
r.wg.Wait()
67+
}
68+
69+
func (r *runner) IsRunning() bool {
70+
return r.isRunning.IsSet()
71+
}
5672

57-
r.isRunning = false
73+
func (r *runner) Out() string {
74+
return r.out
5875
}

e2e_test.sh

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
TESTS=$(ls cmd/mockbackend/testcases/)
44

5+
OPTIONS=""
6+
if [[ "$1" == "-break" ]]; then
7+
OPTIONS="${OPTIONS} -break"
8+
shift
9+
fi
10+
511
if [[ ! -z "${1}" ]]; then
612
TESTS="${1}"
713
fi
@@ -14,15 +20,15 @@ for t in ${TESTS}; do
1420
fi
1521

1622
echo "RUNNING TEST ${t}"
17-
./mockbackend -test -config cmd/mockbackend/testcases/${t}/${t}.yaml
23+
./mockbackend ${OPTIONS} -test -config cmd/mockbackend/testcases/${t}/${t}.yaml
1824
status=$?
1925

2026
if [[ "${TRAVIS}" == "true" ]]; then
2127
travis_time_finish
2228
travis_fold end "test_${t}"
2329
fi
2430

25-
sleep 10
31+
sleep 2
2632
if [[ ${status} -ne 0 ]]; then
2733
FAILED_TESTS="${FAILED_TESTS} ${t}"
2834
echo "test_${t}: FAIL"

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ require (
3737
github.com/spf13/viper v1.12.0
3838
github.com/stretchr/testify v1.7.1
3939
github.com/subosito/gotenv v1.4.0 // indirect
40+
github.com/tevino/abool v1.2.0 // indirect
4041
github.com/tinylib/msgp v1.1.6
4142
github.com/valyala/fastjson v1.6.3
4243
github.com/wangjohn/quickselect v0.0.0-20161129230411-ed8402a42d5f

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
494494
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
495495
github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=
496496
github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo=
497+
github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA=
498+
github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg=
497499
github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw=
498500
github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw=
499501
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=

vendor/github.com/tevino/abool/.gitignore

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/tevino/abool/LICENSE

+21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/tevino/abool/README.md

+64
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)