Skip to content

Commit 67bba29

Browse files
author
Mikhail Podtserkovskiy
committed
concurrency tests
1 parent 9d70494 commit 67bba29

File tree

6 files changed

+269
-2
lines changed

6 files changed

+269
-2
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ go:
44
- 1.8.x
55

66
install: make get-deps prepare
7-
script: go test ./...
7+
script:
8+
- make test
9+
- make concurrency-test
810
services:
911
- mysql
1012

Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export CONFIG_PATH=./config.json
2+
3+
TEST_CONFIG_PATH=./config-test.json
24
all: get-deps build
35

46
.PHONY: help build fmt clean run test coverage check vet lint doc cfpush
@@ -26,3 +28,16 @@ prepare: fmt gen
2628

2729
run: build
2830
${GOPATH}/bin/service-entrypoint
31+
32+
test:
33+
go test ./...
34+
35+
concurrency-test-prepare: build
36+
go install github.com/qa-dev/jsonwire-grid/testing/webdriver-node-mock
37+
go install github.com/qa-dev/jsonwire-grid/testing/webdriver-mock-creator
38+
go install github.com/qa-dev/jsonwire-grid/testing/webdriver-concurrency-test
39+
CONFIG_PATH=$(TEST_CONFIG_PATH) nohup ${GOPATH}/bin/service-entrypoint >/dev/null 2>&1 &
40+
41+
concurrency-test: concurrency-test-prepare
42+
webdriver-concurrency-test
43+
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"errors"
7+
"flag"
8+
"fmt"
9+
"github.com/qa-dev/jsonwire-grid/jsonwire"
10+
"io/ioutil"
11+
"log"
12+
"net/http"
13+
"os"
14+
"os/exec"
15+
"os/signal"
16+
"strconv"
17+
"sync"
18+
"sync/atomic"
19+
"time"
20+
)
21+
22+
var (
23+
hubUrl *string
24+
level *int
25+
durationStr *string
26+
)
27+
28+
func main() {
29+
hubUrl = flag.String("hub", "http://127.0.0.1:4444", "address of hub, default http://127.0.0.1:4444")
30+
level = flag.Int("level", 100, "count parallell conections")
31+
durationStr = flag.String("duration", "30s", "duration of test, string format ex. 12m, see time.ParseDuration()")
32+
mockMaxDuration := flag.Int("mockMaxDuration", 100, "request duration [0 <=duration], default 0")
33+
mockStartPort := flag.Int("mockStartPort", 5000, "mockStartPort")
34+
flag.Parse()
35+
36+
duration, err := time.ParseDuration(*durationStr)
37+
if err != nil {
38+
log.Fatal("Invalid duration")
39+
}
40+
var counter uint64 = 0
41+
42+
stop := make(chan os.Signal)
43+
signal.Notify(stop, os.Interrupt)
44+
wg := sync.WaitGroup{}
45+
isAlive := true
46+
errChan := make(chan error, *level)
47+
48+
cmd := exec.Command(
49+
"webdriver-mock-creator",
50+
fmt.Sprintf("-hub=%v", *hubUrl),
51+
fmt.Sprintf("-startPort=%v", *mockStartPort),
52+
fmt.Sprintf("-maxDuration=%v", *mockMaxDuration),
53+
fmt.Sprintf("-countNodes=%v", *level),
54+
)
55+
56+
err = cmd.Start()
57+
if err != nil {
58+
log.Fatal(err)
59+
}
60+
61+
time.Sleep(time.Millisecond * 500)
62+
63+
go func() {
64+
for i := 1; i <= *level && isAlive; i++ {
65+
time.Sleep(time.Millisecond * 50)
66+
go func() {
67+
wg.Add(1)
68+
defer wg.Done()
69+
for {
70+
if !isAlive {
71+
break
72+
}
73+
err := runScenario()
74+
if err != nil {
75+
errChan <- errors.New("Run scenario, " + err.Error())
76+
}
77+
atomic.AddUint64(&counter, 1)
78+
}
79+
}()
80+
}
81+
}()
82+
83+
select {
84+
case <-time.After(duration):
85+
case err = <-errChan:
86+
case <-stop:
87+
}
88+
89+
isAlive = false
90+
91+
//wait end all running scenarios
92+
wg.Wait()
93+
94+
//wait interrupt child process
95+
cmd.Process.Signal(os.Interrupt)
96+
cmd.Wait()
97+
98+
if err != nil {
99+
log.Fatalf("Tests failed: %v, ", err)
100+
}
101+
log.Printf("Test ok, %v cycles passed", counter)
102+
}
103+
104+
func runScenario() error {
105+
sessionID, err := createSession()
106+
if err != nil {
107+
err = errors.New("Create session, " + err.Error())
108+
return err
109+
}
110+
err = sendAnyRequest(sessionID)
111+
if err != nil {
112+
err = errors.New("Send any request, " + err.Error())
113+
return err
114+
}
115+
err = closeSession(sessionID)
116+
if err != nil {
117+
err = errors.New("Close session, " + err.Error())
118+
return err
119+
}
120+
return nil
121+
}
122+
123+
func createSession() (sessionID string, err error) {
124+
resp, err := http.Post(*hubUrl+"/wd/hub/session", "application/json", bytes.NewBuffer([]byte(`{"desiredCapabilities":{"browserName": "firefox"}}`)))
125+
if err != nil {
126+
err = errors.New("Send request, " + err.Error())
127+
return
128+
}
129+
defer resp.Body.Close()
130+
b, err := ioutil.ReadAll(resp.Body)
131+
if err != nil {
132+
err = errors.New("Read response body, " + err.Error())
133+
return
134+
}
135+
136+
var message jsonwire.NewSession
137+
err = json.Unmarshal(b, &message)
138+
if err != nil {
139+
err = errors.New("Unmarshal json, " + err.Error() + ", given response body=[" + string(b) + "]")
140+
return
141+
}
142+
switch {
143+
case message.SessionId != "":
144+
sessionID = message.SessionId
145+
case message.Value.SessionId != "":
146+
sessionID = message.Value.SessionId
147+
default:
148+
err = errors.New("Field`s SessionId is empty")
149+
return
150+
}
151+
if resp.StatusCode != http.StatusOK {
152+
err = errors.New("Expected status code 200, actual: " + strconv.Itoa(resp.StatusCode) + ", given response body=[" + string(b) + "]")
153+
return
154+
}
155+
return sessionID, nil
156+
}
157+
158+
func sendAnyRequest(sessionID string) (err error) {
159+
resp, err := http.Get(*hubUrl + "/wd/hub/session/" + sessionID + "/url")
160+
if err != nil {
161+
err = errors.New("Send request, " + err.Error())
162+
return
163+
}
164+
defer resp.Body.Close()
165+
if resp.StatusCode != http.StatusOK {
166+
b, _ := ioutil.ReadAll(resp.Body)
167+
err = errors.New("Expected status code 200, actual: " + strconv.Itoa(resp.StatusCode) + ", given response body=[" + string(b) + "]")
168+
return
169+
}
170+
return
171+
}
172+
173+
func closeSession(sessionID string) (err error) {
174+
req, err := http.NewRequest(http.MethodDelete, *hubUrl+"/wd/hub/session/"+sessionID, nil)
175+
if err != nil {
176+
err = errors.New("Create request, " + err.Error())
177+
return
178+
}
179+
resp, err := http.DefaultClient.Do(req)
180+
if err != nil {
181+
err = errors.New("Send request, " + err.Error())
182+
return
183+
}
184+
defer resp.Body.Close()
185+
if resp.StatusCode != http.StatusOK {
186+
b, _ := ioutil.ReadAll(resp.Body)
187+
err = errors.New("Expected status code 200, actual: " + strconv.Itoa(resp.StatusCode) + ", given response body=[" + string(b) + "]")
188+
return
189+
}
190+
return
191+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
log "github.com/Sirupsen/logrus"
7+
"os"
8+
"os/exec"
9+
"os/signal"
10+
"time"
11+
)
12+
13+
func main() {
14+
hubUrl := flag.String("hub", "http://127.0.0.1:4444", "address of hub, default http://127.0.0.1:4444")
15+
startPort := flag.Int("startPort", 5000, "start port")
16+
maxDuration := flag.Int("maxDuration", 100, "request duration [0 <=duration], default 0")
17+
countNodes := flag.Int("countNodes", 100, "count nodes")
18+
flag.Parse()
19+
log.Infof("hub url: %v", *hubUrl)
20+
log.Infof("startPort: %v", *startPort)
21+
log.Infof("maxDuration: %v", *maxDuration)
22+
log.Infof("countNodes: %v", *countNodes)
23+
24+
stop := make(chan os.Signal)
25+
signal.Notify(stop, os.Interrupt)
26+
done := make(chan struct{})
27+
isAlive := true
28+
29+
go func() {
30+
<-stop
31+
isAlive = false
32+
done <- struct{}{}
33+
}()
34+
35+
for port := *startPort; port < *startPort+*countNodes && isAlive; port++ {
36+
time.Sleep(time.Millisecond)
37+
cmd := exec.Command(
38+
"webdriver-node-mock",
39+
fmt.Sprintf("-hub=%v", *hubUrl),
40+
fmt.Sprintf("-port=%v", port),
41+
fmt.Sprintf("-maxDuration=%v", *maxDuration),
42+
)
43+
cmd.Stdout = os.Stdout
44+
cmd.Stderr = os.Stderr
45+
err := cmd.Start()
46+
if err != nil {
47+
log.Error(err)
48+
}
49+
50+
//wait interrupt child process
51+
defer func(cmd *exec.Cmd) {
52+
cmd.Process.Signal(os.Interrupt)
53+
cmd.Process.Wait()
54+
}(cmd)
55+
log.Info("Created instance #", port-*startPort+1)
56+
}
57+
<-done
58+
59+
}

utils/mocks/node/main.go renamed to testing/webdriver-node-mock/webdriver-node-mock.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func main() {
4343

4444
go func() {
4545
for {
46-
<-time.Tick(time.Second)
46+
time.Sleep(time.Second)
4747
err := sendApiProxy()
4848
if err != nil {
4949
log.Errorf("Error send [api/proxy], ", err)

0 commit comments

Comments
 (0)