Skip to content

Commit 89c05b2

Browse files
committed
attempt to run tests in a tester sidecar
Signed-off-by: R.I.Pienaar <[email protected]>
1 parent 09bc070 commit 89c05b2

File tree

16 files changed

+2269
-2168
lines changed

16 files changed

+2269
-2168
lines changed

.github/workflows/go.yaml

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,62 @@ on: [push, pull_request]
44
jobs:
55
lint_and_test:
66
runs-on: ubuntu-latest
7+
container: golang:1.24-alpine # required to run in the docker network and avoid badly performing
8+
# port range expose from docker
79

810
strategy:
911
matrix:
1012
go: [ "1.23", "1.24" ]
1113

14+
services:
15+
nats:
16+
image: ripienaar/testing.go
17+
options: --name jetstream # only needed to facilitate debugging with docker logs etc
18+
1219
steps:
1320
- name: Checkout code
1421
uses: actions/checkout@v4
1522

1623
- name: Setup Go
17-
uses: actions/setup-go@v4
24+
uses: actions/setup-go@v5
1825
with:
1926
go-version: ${{ matrix.go }}
2027

2128
- name: Install deps
22-
shell: bash --noprofile --norc -x -eo pipefail {0}
2329
run: |
30+
set -e
31+
2432
export GOPATH="$RUNNER_WORKSPACE"
2533
go version
2634
go install honnef.co/go/tools/cmd/staticcheck@latest
2735
go install github.com/client9/misspell/cmd/misspell@latest
2836
2937
- name: Lint
30-
shell: bash --noprofile --norc -x -eo pipefail {0}
3138
run: |
39+
set -e
40+
3241
export GOPATH="$RUNNER_WORKSPACE"
3342
PATH=$PATH:$GOPATH/bin
3443
$(exit $(go fmt $(go list ./...) | wc -l))
3544
find . -type f -name "*.go" | xargs misspell -error -locale US
36-
staticcheck -f stylish $(go list ./... | grep -v governor)
45+
staticcheck -f stylish $(go list ./...)
3746
go vet ./...
3847
3948
- name: Run tests
40-
shell: bash --noprofile --norc -x -eo pipefail {0}
4149
run: |
50+
set -e
51+
4252
export GOPATH="$RUNNER_WORKSPACE"
43-
go test -v -race -p 1 ./...
53+
export TESTER_URL="nats://nats:4222" # name here matches the service name
54+
55+
go test -v -p 1 -failfast ./...
56+
57+
# debugging only
58+
- name: docker logs
59+
if: always()
60+
run: |
61+
set -e
62+
63+
apk add docker
64+
docker ps -a
65+
docker logs jetstream

balancer/balancer_test.go

Lines changed: 31 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
package balancer
22

33
import (
4-
"context"
54
"fmt"
6-
"net/url"
75
"os"
8-
"path/filepath"
96
"testing"
107
"time"
118

129
"github.com/nats-io/jsm.go"
1310
"github.com/nats-io/jsm.go/api"
14-
"github.com/nats-io/nats-server/v2/server"
11+
testapi "github.com/nats-io/jsm.go/test/testing_client/api"
12+
"github.com/nats-io/jsm.go/test/testing_client/srvtest"
1513
"github.com/nats-io/nats.go"
1614
)
1715

1816
func TestBalancer(t *testing.T) {
19-
withJSCluster(t, func(t *testing.T, servers []*server.Server, nc *nats.Conn, mgr *jsm.Manager) error {
17+
withTesterJetStreamCluster(t, func(t *testing.T, mgr *jsm.Manager, _ *srvtest.Client, servers []*testapi.ManagedServer) {
2018
var err error
19+
20+
nc := mgr.NatsConn()
21+
firstServer := servers[0].Name
22+
2123
waitTime := 100 * time.Millisecond
2224
streams := []*jsm.Stream{}
2325
for i := 1; i <= 3; i++ {
@@ -28,8 +30,8 @@ func TestBalancer(t *testing.T) {
2830
t.Fatalf("could not create stream %s", err)
2931
}
3032
info, _ := s.ClusterInfo()
31-
if info.Leader != "s1" {
32-
placement := api.Placement{Preferred: "s1"}
33+
if info.Leader != firstServer {
34+
placement := api.Placement{Preferred: firstServer}
3335
err = s.LeaderStepDown(&placement)
3436
if err != nil {
3537
t.Fatalf("could not move stream %s", err)
@@ -59,29 +61,29 @@ func TestBalancer(t *testing.T) {
5961

6062
b, err := New(nc, api.NewDefaultLogger(api.DebugLevel))
6163
if err != nil {
62-
return err
64+
t.Fatalf("create failed: %v", err.Error())
6365
}
6466

6567
count, err := b.BalanceStreams(streams)
6668
if err != nil {
67-
return err
69+
t.Fatalf("Balance failed: %v", err.Error())
6870
}
6971

7072
if count == 0 {
71-
return err
73+
t.Fatal("Balanceed 0 streams")
7274
}
7375

7476
consumers := []*jsm.Consumer{}
7577
for i := 1; i <= 3; i++ {
7678
consumerName := fmt.Sprintf("testc%d", i)
7779
c, err := mgr.NewConsumer("tests1", jsm.DurableName(consumerName), jsm.ConsumerOverrideReplicas(3))
7880
if err != nil {
79-
return err
81+
t.Fatalf("could not create consumer %s", err)
8082
}
8183

8284
info, _ := c.ClusterInfo()
83-
if info.Leader != "s1" {
84-
placement := api.Placement{Preferred: "s1"}
85+
if info.Leader != firstServer {
86+
placement := api.Placement{Preferred: firstServer}
8587
err = c.LeaderStepDown(&placement)
8688
if err != nil {
8789
t.Fatalf("could not move consumer %s", err)
@@ -111,102 +113,34 @@ func TestBalancer(t *testing.T) {
111113

112114
count, err = b.BalanceConsumers(consumers)
113115
if err != nil {
114-
return err
116+
t.Fatalf("Balance failed: %v", err)
115117
}
116118

117119
if count == 0 {
118-
return err
120+
t.Fatal("Balanced 0 consumers")
119121
}
120-
121-
return nil
122122
})
123123
}
124124

125-
func withJSCluster(t *testing.T, cb func(*testing.T, []*server.Server, *nats.Conn, *jsm.Manager) error) {
125+
func withTesterJetStreamCluster(t *testing.T, fn func(*testing.T, *jsm.Manager, *srvtest.Client, []*testapi.ManagedServer)) {
126126
t.Helper()
127127

128-
d, err := os.MkdirTemp("", "jstest")
129-
if err != nil {
130-
t.Fatalf("temp dir could not be made: %s", err)
128+
url := os.Getenv("TESTER_URL")
129+
if url == "" {
130+
url = "nats://localhost:4222"
131131
}
132-
defer os.RemoveAll(d)
133-
134-
var (
135-
servers []*server.Server
136-
)
137-
138-
for i := 1; i <= 3; i++ {
139-
opts := &server.Options{
140-
JetStream: true,
141-
StoreDir: filepath.Join(d, fmt.Sprintf("s%d", i)),
142-
Port: -1,
143-
Host: "localhost",
144-
ServerName: fmt.Sprintf("s%d", i),
145-
LogFile: "/dev/null",
146-
Cluster: server.ClusterOpts{
147-
Name: "TEST",
148-
Port: 12000 + i,
149-
},
150-
Routes: []*url.URL{
151-
{Host: "localhost:12001"},
152-
{Host: "localhost:12002"},
153-
{Host: "localhost:12003"},
154-
},
155-
}
156132

157-
s, err := server.NewServer(opts)
133+
client := srvtest.New(t, url)
134+
t.Cleanup(func() {
135+
client.Reset(t)
136+
})
137+
138+
client.WithJetStreamCluster(t, 3, func(t *testing.T, nc *nats.Conn, servers []*testapi.ManagedServer) {
139+
mgr, err := jsm.New(nc)
158140
if err != nil {
159-
t.Fatalf("server %d start failed: %v", i, err)
160-
}
161-
s.ConfigureLogger()
162-
go s.Start()
163-
if !s.ReadyForConnections(10 * time.Second) {
164-
t.Errorf("nats server %d did not start", i)
141+
t.Fatal(err)
165142
}
166-
defer func() {
167-
s.Shutdown()
168-
}()
169-
170-
servers = append(servers, s)
171-
}
172-
173-
if len(servers) != 3 {
174-
t.Fatalf("servers did not start")
175-
}
176-
177-
nc, err := nats.Connect(servers[0].ClientURL(), nats.UseOldRequestStyle())
178-
if err != nil {
179-
t.Fatalf("client start failed: %s", err)
180-
}
181-
defer nc.Close()
182143

183-
mgr, err := jsm.New(nc, jsm.WithTimeout(5*time.Second))
184-
if err != nil {
185-
t.Fatalf("manager creation failed: %s", err)
186-
}
187-
188-
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
189-
defer cancel()
190-
ticker := time.NewTicker(250 * time.Millisecond)
191-
defer ticker.Stop()
192-
193-
for {
194-
select {
195-
case <-ticker.C:
196-
_, err := mgr.JetStreamAccountInfo()
197-
if err != nil {
198-
continue
199-
}
200-
201-
err = cb(t, servers, nc, mgr)
202-
203-
if err != nil {
204-
t.Fatal(err)
205-
}
206-
207-
return
208-
case <-ctx.Done():
209-
t.Fatalf("jetstream did not become available")
210-
}
211-
}
144+
fn(t, mgr, client, servers)
145+
})
212146
}

0 commit comments

Comments
 (0)