mirror of
https://github.com/coder/coder.git
synced 2025-07-06 15:41:45 +00:00
chore: Speed up port-forward tests (#3062)
* chore: Speed up port-forward tests * chore: Add t.Helper and ensure listener closure on error
This commit is contained in:
committed by
GitHub
parent
cd74afcccc
commit
034416f141
@ -142,21 +142,22 @@ func TestPortForward(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup agent once to be shared between test-cases (avoid expensive
|
||||||
|
// non-parallel setup).
|
||||||
|
var (
|
||||||
|
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
|
||||||
|
user = coderdtest.CreateFirstUser(t, client)
|
||||||
|
_, workspace = runAgent(t, client, user.UserID)
|
||||||
|
)
|
||||||
|
|
||||||
for _, c := range cases { //nolint:paralleltest // the `c := c` confuses the linter
|
for _, c := range cases { //nolint:paralleltest // the `c := c` confuses the linter
|
||||||
c := c
|
c := c
|
||||||
// Avoid parallel test here because setupLocal reserves
|
// Delay parallel tests here because setupLocal reserves
|
||||||
// a free open port which is not guaranteed to be free
|
// a free open port which is not guaranteed to be free
|
||||||
// after the listener closes.
|
// between the listener closing and port-forward ready.
|
||||||
//nolint:paralleltest
|
|
||||||
t.Run(c.name, func(t *testing.T) {
|
t.Run(c.name, func(t *testing.T) {
|
||||||
//nolint:paralleltest
|
|
||||||
t.Run("OnePort", func(t *testing.T) {
|
t.Run("OnePort", func(t *testing.T) {
|
||||||
var (
|
p1 := setupTestListener(t, c.setupRemote(t))
|
||||||
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
|
|
||||||
user = coderdtest.CreateFirstUser(t, client)
|
|
||||||
_, workspace = runAgent(t, client, user.UserID)
|
|
||||||
p1 = setupTestListener(t, c.setupRemote(t))
|
|
||||||
)
|
|
||||||
|
|
||||||
// Create a flag that forwards from local to listener 1.
|
// Create a flag that forwards from local to listener 1.
|
||||||
localAddress, localFlag := c.setupLocal(t)
|
localAddress, localFlag := c.setupLocal(t)
|
||||||
@ -176,6 +177,8 @@ func TestPortForward(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
waitForPortForwardReady(t, buf)
|
waitForPortForwardReady(t, buf)
|
||||||
|
|
||||||
|
t.Parallel() // Port is reserved, enable parallel execution.
|
||||||
|
|
||||||
// Open two connections simultaneously and test them out of
|
// Open two connections simultaneously and test them out of
|
||||||
// sync.
|
// sync.
|
||||||
d := net.Dialer{Timeout: 3 * time.Second}
|
d := net.Dialer{Timeout: 3 * time.Second}
|
||||||
@ -196,11 +199,8 @@ func TestPortForward(t *testing.T) {
|
|||||||
//nolint:paralleltest
|
//nolint:paralleltest
|
||||||
t.Run("TwoPorts", func(t *testing.T) {
|
t.Run("TwoPorts", func(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
|
p1 = setupTestListener(t, c.setupRemote(t))
|
||||||
user = coderdtest.CreateFirstUser(t, client)
|
p2 = setupTestListener(t, c.setupRemote(t))
|
||||||
_, workspace = runAgent(t, client, user.UserID)
|
|
||||||
p1 = setupTestListener(t, c.setupRemote(t))
|
|
||||||
p2 = setupTestListener(t, c.setupRemote(t))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create a flags for listener 1 and listener 2.
|
// Create a flags for listener 1 and listener 2.
|
||||||
@ -223,6 +223,8 @@ func TestPortForward(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
waitForPortForwardReady(t, buf)
|
waitForPortForwardReady(t, buf)
|
||||||
|
|
||||||
|
t.Parallel() // Port is reserved, enable parallel execution.
|
||||||
|
|
||||||
// Open a connection to both listener 1 and 2 simultaneously and
|
// Open a connection to both listener 1 and 2 simultaneously and
|
||||||
// then test them out of order.
|
// then test them out of order.
|
||||||
d := net.Dialer{Timeout: 3 * time.Second}
|
d := net.Dialer{Timeout: 3 * time.Second}
|
||||||
@ -246,10 +248,6 @@ func TestPortForward(t *testing.T) {
|
|||||||
//nolint:paralleltest
|
//nolint:paralleltest
|
||||||
t.Run("TCP2Unix", func(t *testing.T) {
|
t.Run("TCP2Unix", func(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
|
|
||||||
user = coderdtest.CreateFirstUser(t, client)
|
|
||||||
_, workspace = runAgent(t, client, user.UserID)
|
|
||||||
|
|
||||||
// Find the TCP and Unix cases so we can use their setupLocal and
|
// Find the TCP and Unix cases so we can use their setupLocal and
|
||||||
// setupRemote methods respectively.
|
// setupRemote methods respectively.
|
||||||
tcpCase = cases[0]
|
tcpCase = cases[0]
|
||||||
@ -278,6 +276,8 @@ func TestPortForward(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
waitForPortForwardReady(t, buf)
|
waitForPortForwardReady(t, buf)
|
||||||
|
|
||||||
|
t.Parallel() // Port is reserved, enable parallel execution.
|
||||||
|
|
||||||
// Open two connections simultaneously and test them out of
|
// Open two connections simultaneously and test them out of
|
||||||
// sync.
|
// sync.
|
||||||
d := net.Dialer{Timeout: 3 * time.Second}
|
d := net.Dialer{Timeout: 3 * time.Second}
|
||||||
@ -299,9 +299,6 @@ func TestPortForward(t *testing.T) {
|
|||||||
//nolint:paralleltest
|
//nolint:paralleltest
|
||||||
t.Run("All", func(t *testing.T) {
|
t.Run("All", func(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
|
|
||||||
user = coderdtest.CreateFirstUser(t, client)
|
|
||||||
_, workspace = runAgent(t, client, user.UserID)
|
|
||||||
// These aren't fixed size because we exclude Unix on Windows.
|
// These aren't fixed size because we exclude Unix on Windows.
|
||||||
dials = []addr{}
|
dials = []addr{}
|
||||||
flags = []string{}
|
flags = []string{}
|
||||||
@ -339,6 +336,8 @@ func TestPortForward(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
waitForPortForwardReady(t, buf)
|
waitForPortForwardReady(t, buf)
|
||||||
|
|
||||||
|
t.Parallel() // Port is reserved, enable parallel execution.
|
||||||
|
|
||||||
// Open connections to all items in the "dial" array.
|
// Open connections to all items in the "dial" array.
|
||||||
var (
|
var (
|
||||||
d = net.Dialer{Timeout: 3 * time.Second}
|
d = net.Dialer{Timeout: 3 * time.Second}
|
||||||
@ -425,6 +424,8 @@ func runAgent(t *testing.T, client *codersdk.Client, userID uuid.UUID) ([]coders
|
|||||||
// setupTestListener starts accepting connections and echoing a single packet.
|
// setupTestListener starts accepting connections and echoing a single packet.
|
||||||
// Returns the listener and the listen port or Unix path.
|
// Returns the listener and the listen port or Unix path.
|
||||||
func setupTestListener(t *testing.T, l net.Listener) string {
|
func setupTestListener(t *testing.T, l net.Listener) string {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
// Wait for listener to completely exit before releasing.
|
// Wait for listener to completely exit before releasing.
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
@ -440,6 +441,7 @@ func setupTestListener(t *testing.T, l net.Listener) string {
|
|||||||
for {
|
for {
|
||||||
c, err := l.Accept()
|
c, err := l.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
_ = l.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,6 +481,7 @@ func testAccept(t *testing.T, c net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func assertReadPayload(t *testing.T, r io.Reader, payload []byte) {
|
func assertReadPayload(t *testing.T, r io.Reader, payload []byte) {
|
||||||
|
t.Helper()
|
||||||
b := make([]byte, len(payload)+16)
|
b := make([]byte, len(payload)+16)
|
||||||
n, err := r.Read(b)
|
n, err := r.Read(b)
|
||||||
assert.NoError(t, err, "read payload")
|
assert.NoError(t, err, "read payload")
|
||||||
@ -487,12 +490,14 @@ func assertReadPayload(t *testing.T, r io.Reader, payload []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func assertWritePayload(t *testing.T, w io.Writer, payload []byte) {
|
func assertWritePayload(t *testing.T, w io.Writer, payload []byte) {
|
||||||
|
t.Helper()
|
||||||
n, err := w.Write(payload)
|
n, err := w.Write(payload)
|
||||||
assert.NoError(t, err, "write payload")
|
assert.NoError(t, err, "write payload")
|
||||||
assert.Equal(t, len(payload), n, "payload length does not match")
|
assert.Equal(t, len(payload), n, "payload length does not match")
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitForPortForwardReady(t *testing.T, output *threadSafeBuffer) {
|
func waitForPortForwardReady(t *testing.T, output *threadSafeBuffer) {
|
||||||
|
t.Helper()
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
time.Sleep(250 * time.Millisecond)
|
time.Sleep(250 * time.Millisecond)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user