Skip to content

Commit 034416f

Browse files
authored
chore: Speed up port-forward tests (#3062)
* chore: Speed up port-forward tests * chore: Add t.Helper and ensure listener closure on error
1 parent cd74afc commit 034416f

File tree

1 file changed

+27
-22
lines changed

1 file changed

+27
-22
lines changed

cli/portforward_test.go

+27-22
Original file line numberDiff line numberDiff line change
@@ -142,21 +142,22 @@ func TestPortForward(t *testing.T) {
142142
},
143143
}
144144

145+
// Setup agent once to be shared between test-cases (avoid expensive
146+
// non-parallel setup).
147+
var (
148+
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
149+
user = coderdtest.CreateFirstUser(t, client)
150+
_, workspace = runAgent(t, client, user.UserID)
151+
)
152+
145153
for _, c := range cases { //nolint:paralleltest // the `c := c` confuses the linter
146154
c := c
147-
// Avoid parallel test here because setupLocal reserves
155+
// Delay parallel tests here because setupLocal reserves
148156
// a free open port which is not guaranteed to be free
149-
// after the listener closes.
150-
//nolint:paralleltest
157+
// between the listener closing and port-forward ready.
151158
t.Run(c.name, func(t *testing.T) {
152-
//nolint:paralleltest
153159
t.Run("OnePort", func(t *testing.T) {
154-
var (
155-
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
156-
user = coderdtest.CreateFirstUser(t, client)
157-
_, workspace = runAgent(t, client, user.UserID)
158-
p1 = setupTestListener(t, c.setupRemote(t))
159-
)
160+
p1 := setupTestListener(t, c.setupRemote(t))
160161

161162
// Create a flag that forwards from local to listener 1.
162163
localAddress, localFlag := c.setupLocal(t)
@@ -176,6 +177,8 @@ func TestPortForward(t *testing.T) {
176177
}()
177178
waitForPortForwardReady(t, buf)
178179

180+
t.Parallel() // Port is reserved, enable parallel execution.
181+
179182
// Open two connections simultaneously and test them out of
180183
// sync.
181184
d := net.Dialer{Timeout: 3 * time.Second}
@@ -196,11 +199,8 @@ func TestPortForward(t *testing.T) {
196199
//nolint:paralleltest
197200
t.Run("TwoPorts", func(t *testing.T) {
198201
var (
199-
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
200-
user = coderdtest.CreateFirstUser(t, client)
201-
_, workspace = runAgent(t, client, user.UserID)
202-
p1 = setupTestListener(t, c.setupRemote(t))
203-
p2 = setupTestListener(t, c.setupRemote(t))
202+
p1 = setupTestListener(t, c.setupRemote(t))
203+
p2 = setupTestListener(t, c.setupRemote(t))
204204
)
205205

206206
// Create a flags for listener 1 and listener 2.
@@ -223,6 +223,8 @@ func TestPortForward(t *testing.T) {
223223
}()
224224
waitForPortForwardReady(t, buf)
225225

226+
t.Parallel() // Port is reserved, enable parallel execution.
227+
226228
// Open a connection to both listener 1 and 2 simultaneously and
227229
// then test them out of order.
228230
d := net.Dialer{Timeout: 3 * time.Second}
@@ -246,10 +248,6 @@ func TestPortForward(t *testing.T) {
246248
//nolint:paralleltest
247249
t.Run("TCP2Unix", func(t *testing.T) {
248250
var (
249-
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
250-
user = coderdtest.CreateFirstUser(t, client)
251-
_, workspace = runAgent(t, client, user.UserID)
252-
253251
// Find the TCP and Unix cases so we can use their setupLocal and
254252
// setupRemote methods respectively.
255253
tcpCase = cases[0]
@@ -278,6 +276,8 @@ func TestPortForward(t *testing.T) {
278276
}()
279277
waitForPortForwardReady(t, buf)
280278

279+
t.Parallel() // Port is reserved, enable parallel execution.
280+
281281
// Open two connections simultaneously and test them out of
282282
// sync.
283283
d := net.Dialer{Timeout: 3 * time.Second}
@@ -299,9 +299,6 @@ func TestPortForward(t *testing.T) {
299299
//nolint:paralleltest
300300
t.Run("All", func(t *testing.T) {
301301
var (
302-
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
303-
user = coderdtest.CreateFirstUser(t, client)
304-
_, workspace = runAgent(t, client, user.UserID)
305302
// These aren't fixed size because we exclude Unix on Windows.
306303
dials = []addr{}
307304
flags = []string{}
@@ -339,6 +336,8 @@ func TestPortForward(t *testing.T) {
339336
}()
340337
waitForPortForwardReady(t, buf)
341338

339+
t.Parallel() // Port is reserved, enable parallel execution.
340+
342341
// Open connections to all items in the "dial" array.
343342
var (
344343
d = net.Dialer{Timeout: 3 * time.Second}
@@ -425,6 +424,8 @@ func runAgent(t *testing.T, client *codersdk.Client, userID uuid.UUID) ([]coders
425424
// setupTestListener starts accepting connections and echoing a single packet.
426425
// Returns the listener and the listen port or Unix path.
427426
func setupTestListener(t *testing.T, l net.Listener) string {
427+
t.Helper()
428+
428429
// Wait for listener to completely exit before releasing.
429430
done := make(chan struct{})
430431
t.Cleanup(func() {
@@ -440,6 +441,7 @@ func setupTestListener(t *testing.T, l net.Listener) string {
440441
for {
441442
c, err := l.Accept()
442443
if err != nil {
444+
_ = l.Close()
443445
return
444446
}
445447

@@ -479,6 +481,7 @@ func testAccept(t *testing.T, c net.Conn) {
479481
}
480482

481483
func assertReadPayload(t *testing.T, r io.Reader, payload []byte) {
484+
t.Helper()
482485
b := make([]byte, len(payload)+16)
483486
n, err := r.Read(b)
484487
assert.NoError(t, err, "read payload")
@@ -487,12 +490,14 @@ func assertReadPayload(t *testing.T, r io.Reader, payload []byte) {
487490
}
488491

489492
func assertWritePayload(t *testing.T, w io.Writer, payload []byte) {
493+
t.Helper()
490494
n, err := w.Write(payload)
491495
assert.NoError(t, err, "write payload")
492496
assert.Equal(t, len(payload), n, "payload length does not match")
493497
}
494498

495499
func waitForPortForwardReady(t *testing.T, output *threadSafeBuffer) {
500+
t.Helper()
496501
for i := 0; i < 100; i++ {
497502
time.Sleep(250 * time.Millisecond)
498503

0 commit comments

Comments
 (0)