@@ -21,10 +21,8 @@ import (
21
21
"github.com/coder/coder/testutil"
22
22
)
23
23
24
+ //nolint:tparallel,paralleltest // Subtests require setup that must not be done in parallel.
24
25
func TestPortForward (t * testing.T ) {
25
- t .Parallel ()
26
- t .Skip ("These tests flake... a lot. It seems related to the Tailscale change, but all other tests pass..." )
27
-
28
26
t .Run ("None" , func (t * testing.T ) {
29
27
t .Parallel ()
30
28
@@ -116,106 +114,102 @@ func TestPortForward(t *testing.T) {
116
114
workspace = runAgent (t , client , user .UserID )
117
115
)
118
116
119
- for _ , c := range cases { //nolint:paralleltest // the `c := c` confuses the linter
117
+ for _ , c := range cases {
120
118
c := c
121
119
// Delay parallel tests here because setupLocal reserves
122
120
// a free open port which is not guaranteed to be free
123
121
// between the listener closing and port-forward ready.
124
- t .Run (c .name , func (t * testing.T ) {
125
- t .Run ("OnePort" , func (t * testing.T ) {
126
- p1 := setupTestListener (t , c .setupRemote (t ))
127
-
128
- // Create a flag that forwards from local to listener 1.
129
- localAddress , localFlag := c .setupLocal (t )
130
- flag := fmt .Sprintf (c .flag , localFlag , p1 )
131
-
132
- // Launch port-forward in a goroutine so we can start dialing
133
- // the "local" listener.
134
- inv , root := clitest .New (t , "-v" , "port-forward" , workspace .Name , flag )
135
- clitest .SetupConfig (t , client , root )
136
- pty := ptytest .New (t )
137
- inv .Stdin = pty .Input ()
138
- inv .Stdout = pty .Output ()
139
- inv .Stderr = pty .Output ()
140
- ctx , cancel := context .WithCancel (context .Background ())
141
- defer cancel ()
142
- errC := make (chan error )
143
- go func () {
144
- errC <- inv .WithContext (ctx ).Run ()
145
- }()
146
- pty .ExpectMatch ("Ready!" )
147
-
148
- t .Parallel () // Port is reserved, enable parallel execution.
149
-
150
- // Open two connections simultaneously and test them out of
151
- // sync.
152
- d := net.Dialer {Timeout : testutil .WaitShort }
153
- c1 , err := d .DialContext (ctx , c .network , localAddress )
154
- require .NoError (t , err , "open connection 1 to 'local' listener" )
155
- defer c1 .Close ()
156
- c2 , err := d .DialContext (ctx , c .network , localAddress )
157
- require .NoError (t , err , "open connection 2 to 'local' listener" )
158
- defer c2 .Close ()
159
- testDial (t , c2 )
160
- testDial (t , c1 )
161
-
162
- cancel ()
163
- err = <- errC
164
- require .ErrorIs (t , err , context .Canceled )
165
- })
122
+ t .Run (c .name + "_OnePort" , func (t * testing.T ) {
123
+ p1 := setupTestListener (t , c .setupRemote (t ))
166
124
167
- //nolint:paralleltest
168
- t .Run ("TwoPorts" , func (t * testing.T ) {
169
- var (
170
- p1 = setupTestListener (t , c .setupRemote (t ))
171
- p2 = setupTestListener (t , c .setupRemote (t ))
172
- )
173
-
174
- // Create a flags for listener 1 and listener 2.
175
- localAddress1 , localFlag1 := c .setupLocal (t )
176
- localAddress2 , localFlag2 := c .setupLocal (t )
177
- flag1 := fmt .Sprintf (c .flag , localFlag1 , p1 )
178
- flag2 := fmt .Sprintf (c .flag , localFlag2 , p2 )
179
-
180
- // Launch port-forward in a goroutine so we can start dialing
181
- // the "local" listeners.
182
- inv , root := clitest .New (t , "-v" , "port-forward" , workspace .Name , flag1 , flag2 )
183
- clitest .SetupConfig (t , client , root )
184
- pty := ptytest .New (t )
185
- inv .Stdin = pty .Input ()
186
- inv .Stdout = pty .Output ()
187
- inv .Stderr = pty .Output ()
188
- ctx , cancel := context .WithCancel (context .Background ())
189
- defer cancel ()
190
- errC := make (chan error )
191
- go func () {
192
- errC <- inv .WithContext (ctx ).Run ()
193
- }()
194
- pty .ExpectMatch ("Ready!" )
195
-
196
- t .Parallel () // Port is reserved, enable parallel execution.
197
-
198
- // Open a connection to both listener 1 and 2 simultaneously and
199
- // then test them out of order.
200
- d := net.Dialer {Timeout : testutil .WaitShort }
201
- c1 , err := d .DialContext (ctx , c .network , localAddress1 )
202
- require .NoError (t , err , "open connection 1 to 'local' listener 1" )
203
- defer c1 .Close ()
204
- c2 , err := d .DialContext (ctx , c .network , localAddress2 )
205
- require .NoError (t , err , "open connection 2 to 'local' listener 2" )
206
- defer c2 .Close ()
207
- testDial (t , c2 )
208
- testDial (t , c1 )
209
-
210
- cancel ()
211
- err = <- errC
212
- require .ErrorIs (t , err , context .Canceled )
213
- })
125
+ // Create a flag that forwards from local to listener 1.
126
+ localAddress , localFlag := c .setupLocal (t )
127
+ flag := fmt .Sprintf (c .flag , localFlag , p1 )
128
+
129
+ // Launch port-forward in a goroutine so we can start dialing
130
+ // the "local" listener.
131
+ inv , root := clitest .New (t , "-v" , "port-forward" , workspace .Name , flag )
132
+ clitest .SetupConfig (t , client , root )
133
+ pty := ptytest .New (t )
134
+ inv .Stdin = pty .Input ()
135
+ inv .Stdout = pty .Output ()
136
+ inv .Stderr = pty .Output ()
137
+ ctx , cancel := context .WithCancel (context .Background ())
138
+ defer cancel ()
139
+ errC := make (chan error )
140
+ go func () {
141
+ errC <- inv .WithContext (ctx ).Run ()
142
+ }()
143
+ pty .ExpectMatch ("Ready!" )
144
+
145
+ t .Parallel () // Port is reserved, enable parallel execution.
146
+
147
+ // Open two connections simultaneously and test them out of
148
+ // sync.
149
+ d := net.Dialer {Timeout : testutil .WaitShort }
150
+ c1 , err := d .DialContext (ctx , c .network , localAddress )
151
+ require .NoError (t , err , "open connection 1 to 'local' listener" )
152
+ defer c1 .Close ()
153
+ c2 , err := d .DialContext (ctx , c .network , localAddress )
154
+ require .NoError (t , err , "open connection 2 to 'local' listener" )
155
+ defer c2 .Close ()
156
+ testDial (t , c2 )
157
+ testDial (t , c1 )
158
+
159
+ cancel ()
160
+ err = <- errC
161
+ require .ErrorIs (t , err , context .Canceled )
162
+ })
163
+
164
+ t .Run (c .name + "_TwoPorts" , func (t * testing.T ) {
165
+ var (
166
+ p1 = setupTestListener (t , c .setupRemote (t ))
167
+ p2 = setupTestListener (t , c .setupRemote (t ))
168
+ )
169
+
170
+ // Create a flags for listener 1 and listener 2.
171
+ localAddress1 , localFlag1 := c .setupLocal (t )
172
+ localAddress2 , localFlag2 := c .setupLocal (t )
173
+ flag1 := fmt .Sprintf (c .flag , localFlag1 , p1 )
174
+ flag2 := fmt .Sprintf (c .flag , localFlag2 , p2 )
175
+
176
+ // Launch port-forward in a goroutine so we can start dialing
177
+ // the "local" listeners.
178
+ inv , root := clitest .New (t , "-v" , "port-forward" , workspace .Name , flag1 , flag2 )
179
+ clitest .SetupConfig (t , client , root )
180
+ pty := ptytest .New (t )
181
+ inv .Stdin = pty .Input ()
182
+ inv .Stdout = pty .Output ()
183
+ inv .Stderr = pty .Output ()
184
+ ctx , cancel := context .WithCancel (context .Background ())
185
+ defer cancel ()
186
+ errC := make (chan error )
187
+ go func () {
188
+ errC <- inv .WithContext (ctx ).Run ()
189
+ }()
190
+ pty .ExpectMatch ("Ready!" )
191
+
192
+ t .Parallel () // Port is reserved, enable parallel execution.
193
+
194
+ // Open a connection to both listener 1 and 2 simultaneously and
195
+ // then test them out of order.
196
+ d := net.Dialer {Timeout : testutil .WaitShort }
197
+ c1 , err := d .DialContext (ctx , c .network , localAddress1 )
198
+ require .NoError (t , err , "open connection 1 to 'local' listener 1" )
199
+ defer c1 .Close ()
200
+ c2 , err := d .DialContext (ctx , c .network , localAddress2 )
201
+ require .NoError (t , err , "open connection 2 to 'local' listener 2" )
202
+ defer c2 .Close ()
203
+ testDial (t , c2 )
204
+ testDial (t , c1 )
205
+
206
+ cancel ()
207
+ err = <- errC
208
+ require .ErrorIs (t , err , context .Canceled )
214
209
})
215
210
}
216
211
217
212
// Test doing TCP and UDP at the same time.
218
- //nolint:paralleltest
219
213
t .Run ("All" , func (t * testing.T ) {
220
214
var (
221
215
dials = []addr {}
0 commit comments