Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/supervisor/pkg/ports/served-ports_test.go
2500 views
1
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package ports
6
7
import (
8
"bytes"
9
"context"
10
"io"
11
"net"
12
"os"
13
"strings"
14
"testing"
15
"time"
16
17
"github.com/google/go-cmp/cmp"
18
)
19
20
const validTCPInput = ` sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
21
0: 00000000:59D8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 57008615 1 0000000000000000 100 0 0 10 0
22
1: 00000000:17C0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 57020850 1 0000000000000000 100 0 0 10 0
23
2: 0100007F:170C 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 57019442 1 0000000000000000 100 0 0 10 0
24
3: 0100007F:EB64 0100007F:59D7 01 00000000:00000000 02:00000348 00000000 33333 0 57010758 2 0000000000000000 20 4 1 10 -1
25
4: 940C380A:59D8 0302380A:BFFC 01 00000000:00000000 00:00000000 00000000 33333 0 57015718 3 0000000000000000 20 4 29 61 17
26
`
27
28
const validTCP6Input = ` sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
29
0: 00000000000000000000000000000000:59D7 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 57007063 1 0000000000000000 100 0 0 10 0
30
1: 00000000000000000000000000000000:8C3C 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 57022992 1 0000000000000000 100 0 0 10 0
31
2: 00000000000000000000000001000000:170C 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 57019446 1 0000000000000000 100 0 0 10 0
32
3: 00000000000000000000000000000000:8CF0 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 57018070 1 0000000000000000 100 0 0 10 0
33
4: 0000000000000000FFFF0000940C380A:59D7 0000000000000000FFFF00006100840A:E45C 06 00000000:00000000 03:00001002 00000000 0 0 0 3 0000000000000000
34
5: 0000000000000000FFFF0000940C380A:59D7 0000000000000000FFFF00006100840A:E38A 06 00000000:00000000 03:00000D46 00000000 0 0 0 3 0000000000000000
35
6: 0000000000000000FFFF0000940C380A:59D7 0000000000000000FFFF0000030C380A:DBFE 01 00000000:00000000 02:000005D2 00000000 33333 0 57015690 2 0000000000000000 20 4 0 10 -1
36
7: 0000000000000000FFFF0000940C380A:59D7 0000000000000000FFFF00006100840A:E08A 06 00000000:00000000 03:000003E6 00000000 0 0 0 3 0000000000000000
37
20: 0000000000000000FFFF00000100007F:59D7 0000000000000000FFFF00000100007F:EB64 01 00000000:00000000 02:000003D2 00000000 33333 0 57014424 2 0000000000000000 20 4 0 10 -1`
38
39
func TestObserve(t *testing.T) {
40
type Expectation [][]ServedPort
41
tests := []struct {
42
Name string
43
FileContents []string
44
Expectation Expectation
45
}{
46
{
47
Name: "basic positive",
48
FileContents: []string{
49
"", "",
50
validTCPInput, validTCP6Input,
51
},
52
Expectation: Expectation{
53
{
54
{Address: net.IPv4(127, 0, 0, 1), Port: 5900, BoundToLocalhost: true},
55
{Address: net.IPv4zero, Port: 6080},
56
{Address: net.IPv4zero, Port: 23000},
57
{Address: net.IPv6loopback, Port: 5900, BoundToLocalhost: true},
58
{Address: net.IPv6zero, Port: 22999},
59
{Address: net.IPv6zero, Port: 35900},
60
{Address: net.IPv6zero, Port: 36080},
61
},
62
},
63
},
64
{
65
Name: "the same port bound locally on ip4 and ip6",
66
FileContents: []string{
67
"", "",
68
`
69
0: 00000000:17C0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21757239 1 0000000000000000 100 0 0 10 0
70
1: 0100007F:170C 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21752303 1 0000000000000000 100 0 0 10 0
71
2: 00000000:59D8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21752496 1 0000000000000000 100 0 0 10 0`,
72
`
73
0: 00000000000000000000000000000000:EA60 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21750982 1 0000000000000000 100 0 0 10 0
74
1: 00000000000000000000000001000000:170C 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21752306 1 0000000000000000 100 0 0 10 0
75
2: 00000000000000000000000000000000:59D7 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21748173 1 0000000000000000 100 0 0 10 0`,
76
},
77
Expectation: Expectation{
78
{
79
{Address: net.IPv4(127, 0, 0, 1), Port: 5900, BoundToLocalhost: true},
80
{Address: net.IPv4zero, Port: 6080},
81
{Address: net.IPv4zero, Port: 23000},
82
{Address: net.IPv6loopback, Port: 5900, BoundToLocalhost: true},
83
{Address: net.IPv6zero, Port: 22999},
84
{Address: net.IPv6zero, Port: 60000},
85
},
86
},
87
},
88
{
89
Name: "the same port bound locally for ip4 and globally for ip6",
90
FileContents: []string{
91
"", "",
92
`
93
0: 00000000:17C0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21757239 1 0000000000000000 100 0 0 10 0
94
1: 0100007F:170C 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21752303 1 0000000000000000 100 0 0 10 0
95
2: 00000000:59D8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21752496 1 0000000000000000 100 0 0 10 0`,
96
`
97
0: 00000000000000000000000000000000:EA60 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21750982 1 0000000000000000 100 0 0 10 0
98
1: 00000000000000000000000000000000:170C 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21752306 1 0000000000000000 100 0 0 10 0
99
2: 00000000000000000000000000000000:59D7 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21748173 1 0000000000000000 100 0 0 10 0`,
100
},
101
Expectation: Expectation{
102
{
103
{Address: net.IPv4(127, 0, 0, 1), Port: 5900, BoundToLocalhost: true},
104
{Address: net.IPv4zero, Port: 6080},
105
{Address: net.IPv4zero, Port: 23000},
106
{Address: net.IPv6zero, Port: 5900, BoundToLocalhost: false},
107
{Address: net.IPv6zero, Port: 22999},
108
{Address: net.IPv6zero, Port: 60000},
109
},
110
},
111
},
112
{
113
Name: "the same port bound globally for ip4 and locally for ip6",
114
FileContents: []string{
115
"", "",
116
`
117
0: 00000000:17C0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21757239 1 0000000000000000 100 0 0 10 0
118
1: 00000000:170C 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21752303 1 0000000000000000 100 0 0 10 0
119
2: 00000000:59D8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21752496 1 0000000000000000 100 0 0 10 0`,
120
`
121
0: 00000000000000000000000000000000:EA60 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21750982 1 0000000000000000 100 0 0 10 0
122
1: 00000000000000000000000001000000:170C 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21752306 1 0000000000000000 100 0 0 10 0
123
2: 00000000000000000000000000000000:59D7 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 21748173 1 0000000000000000 100 0 0 10 0`,
124
},
125
Expectation: Expectation{
126
{
127
{Address: net.IPv4zero, Port: 5900},
128
{Address: net.IPv4zero, Port: 6080},
129
{Address: net.IPv4zero, Port: 23000},
130
{Address: net.IPv6loopback, Port: 5900, BoundToLocalhost: true},
131
{Address: net.IPv6zero, Port: 22999},
132
{Address: net.IPv6zero, Port: 60000},
133
},
134
},
135
},
136
{
137
Name: "multiple ports bound locally and globally",
138
FileContents: []string{
139
"", "",
140
`
141
0: AD0E600A:240D 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 53934502 1 0000000000000000 100 0 0 10 0
142
1: 0100007F:240D 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 53938101 1 0000000000000000 100 0 0 10 0
143
2: 00000000:59D8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 53939555 1 0000000000000000 100 0 0 10 0
144
3: 0100007F:6989 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 54384751 1 0000000000000000 100 0 0 10 1024
145
4: AD0E600A:6989 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 53934503 1 0000000000000000 100 0 0 10 0
146
5: 0100007F:AC48 0100007F:59D7 01 00000000:00000000 02:000004A8 00000000 0 0 53921525 2 0000000000000000 20 4 0 10 -1
147
6: 0100007F:6989 0100007F:C74E 01 00000000:00000000 02:0000653F 00000000 33333 0 54366989 2 0000000000000000 20 4 31 10 -1
148
7: 0100007F:AC40 0100007F:59D7 01 00000000:00000000 02:000004A8 00000000 0 0 53944840 2 0000000000000000 20 4 0 10 -1
149
8: 0100007F:B5D8 0100007F:59D7 01 00000000:00000000 02:0000018F 00000000 0 0 54068010 2 0000000000000000 20 4 0 10 -1
150
9: 0100007F:AC42 0100007F:59D7 01 00000000:00000000 02:000004C2 00000000 0 0 53938397 2 0000000000000000 20 4 0 10 -1
151
10: 0100007F:AC46 0100007F:59D7 01 00000000:00000000 02:000004C2 00000000 0 0 53921524 2 0000000000000000 20 4 0 10 -1
152
11: AD0E600A:B8CC F61BC768:01BB 01 00000000:00000000 02:0000034A 00000000 0 0 53880829 2 0000000000000000 21 4 26 10 -1
153
12: 0100007F:C74E 0100007F:6989 01 00000000:00000000 02:0000077F 00000000 33333 0 54384853 2 0000000000000000 20 4 30 10 -1
154
13: 0100007F:AC44 0100007F:59D7 01 00000000:00000000 02:00000300 00000000 0 0 53932419 2 0000000000000000 20 4 22 10 -1
155
14: 0100007F:AC4A 0100007F:59D7 01 00000000:00000000 02:000004C2 00000000 0 0 53920639 2 0000000000000000 20 4 0 10 -1
156
15: AD0E600A:BAEA F61BC768:01BB 01 00000000:00000000 00:00000000 00000000 33333 0 53962195 1 0000000000000000 20 4 28 10 -1
157
16: AD0E600A:59D8 760B600A:DA78 01 00000000:00000000 00:00000000 00000000 33333 0 53934581 3 0000000000000000 20 4 27 10 33
158
17: 0100007F:C6A6 0100007F:6989 01 00000000:00000000 02:00000360 00000000 33333 0 54383783 2 0000000000000000 20 4 30 10 -1
159
18: AD0E600A:59D8 760B600A:DAD0 01 00000000:00000000 00:00000000 00000000 33333 0 53961912 3 0000000000000000 20 4 31 10 -1
160
19: 0100007F:AC66 0100007F:59D7 01 00000000:00000000 00:00000000 00000000 33333 0 53939557 1 0000000000000000 20 4 0 10 -1
161
20: 0100007F:AE52 0100007F:59D7 01 00000000:00000000 00:00000000 00000000 33333 0 53963729 1 0000000000000000 20 4 0 10 -1
162
21: 0100007F:6989 0100007F:C6A6 01 00000000:00000000 02:00006120 00000000 33333 0 54366964 2 0000000000000000 20 4 20 10 -1`,
163
},
164
Expectation: Expectation{
165
{
166
{Address: net.IPv4(10, 96, 14, 173), Port: 9229},
167
{Address: net.IPv4(127, 0, 0, 1), Port: 9229, BoundToLocalhost: true},
168
{Address: net.IPv4zero, Port: 23000},
169
{Address: net.IPv4(10, 96, 14, 173), Port: 27017, BoundToLocalhost: false},
170
{Address: net.IPv4(127, 0, 0, 1), Port: 27017, BoundToLocalhost: true},
171
},
172
},
173
},
174
{
175
Name: "multiple ports bound locally and globally",
176
FileContents: []string{
177
"", "",
178
`
179
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
180
0: 220E600A:6989 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 61354170 1 0000000000000000 100 0 0 10 0
181
1: 220E600A:240D 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 61354169 1 0000000000000000 100 0 0 10 0
182
2: 0100007F:240D 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 61232087 1 0000000000000000 100 0 0 10 0
183
3: 00000000:59D8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 33333 0 61285963 1 0000000000000000 100 0 0 10 0
184
4: 0100007F:DD60 0100007F:59D7 01 00000000:00000000 02:00000366 00000000 0 0 61278087 2 0000000000000000 20 4 0 10 -1
185
5: 0100007F:DD5E 0100007F:59D7 01 00000000:00000000 02:00000380 00000000 0 0 61286915 2 0000000000000000 20 4 0 10 -1
186
6: 0100007F:DD64 0100007F:59D7 01 00000000:00000000 02:0000019A 00000000 0 0 61281217 2 0000000000000000 20 4 0 10 -1
187
7: 0100007F:E08C 0100007F:59D7 01 00000000:00000000 02:00000233 00000000 0 0 61342352 2 0000000000000000 20 4 0 10 -1
188
8: 0100007F:DD82 0100007F:59D7 01 00000000:00000000 00:00000000 00000000 33333 0 61285965 1 0000000000000000 20 4 0 10 -1
189
9: 220E600A:59D8 760B600A:E920 01 00000000:00000000 00:00000000 00000000 33333 0 61352088 3 0000000000000000 20 4 27 10 28
190
10: 0100007F:DD62 0100007F:59D7 01 00000000:00000000 02:0000019A 00000000 0 0 61278088 2 0000000000000000 20 4 0 10 -1
191
11: 0100007F:DD5C 0100007F:59D7 01 00000000:00000000 02:000000FE 00000000 0 0 61232037 2 0000000000000000 20 4 22 10 -1
192
12: 220E600A:BE20 F61BC768:01BB 01 00000000:00000000 00:00000000 00000000 33333 0 61342422 1 0000000000000000 21 4 26 10 -1
193
13: 0100007F:DD5A 0100007F:59D7 01 00000000:00000000 02:0000019A 00000000 0 0 61232036 2 0000000000000000 20 4 0 10 -1
194
14: 0100007F:E0C6 0100007F:59D7 01 00000000:00000000 00:00000000 00000000 33333 0 61342375 1 0000000000000000 20 4 0 10 -1
195
15: 220E600A:BAB0 F61BC768:01BB 01 00000000:00000000 02:00000418 00000000 0 0 61278493 2 0000000000000000 20 4 30 10 -1
196
16: 220E600A:59D8 760B600A:E96C 01 00000000:00000000 00:00000000 00000000 33333 0 61331984 3 0000000000000000 20 4 31 10 -1`,
197
},
198
Expectation: Expectation{
199
{
200
{Address: net.IPv4(10, 96, 14, 34), Port: 9229},
201
{Address: net.IPv4(127, 0, 0, 1), Port: 9229, BoundToLocalhost: true},
202
{Address: net.IPv4zero, Port: 23000},
203
{Address: net.IPv4(10, 96, 14, 34), Port: 27017},
204
},
205
},
206
},
207
}
208
209
for _, test := range tests {
210
t.Run(test.Name, func(t *testing.T) {
211
var f int
212
obs := PollingServedPortsObserver{
213
RefreshInterval: 100 * time.Millisecond,
214
fileOpener: func(fn string) (io.ReadCloser, error) {
215
if f >= len(test.FileContents) {
216
return nil, os.ErrNotExist
217
}
218
219
res := io.NopCloser(bytes.NewReader([]byte(test.FileContents[f])))
220
f++
221
return res, nil
222
},
223
}
224
225
ctx, cancel := context.WithCancel(context.Background())
226
updates, errs := obs.Observe(ctx)
227
go func() {
228
time.Sleep(500 * time.Millisecond)
229
cancel()
230
}()
231
go func() {
232
for range errs {
233
}
234
}()
235
236
var act Expectation
237
for up := range updates {
238
act = append(act, up)
239
}
240
241
if diff := cmp.Diff(test.Expectation, act); diff != "" {
242
t.Errorf("unexpected result (-want +got):\n%s", diff)
243
}
244
})
245
}
246
}
247
248
func TestReadNetTCPFile(t *testing.T) {
249
type Expectation struct {
250
Ports []ServedPort
251
Error error
252
}
253
tests := []struct {
254
Name string
255
Input string
256
ListeningOnly bool
257
Expectation Expectation
258
}{
259
{
260
Name: "valid tcp4 input",
261
Input: validTCPInput,
262
ListeningOnly: true,
263
Expectation: Expectation{
264
Ports: []ServedPort{
265
{Address: net.IPv4(127, 0, 0, 1), Port: 5900, BoundToLocalhost: true},
266
{Address: net.IPv4zero, Port: 6080},
267
{Address: net.IPv4zero, Port: 23000},
268
},
269
},
270
},
271
{
272
Name: "valid tcp6 input",
273
Input: validTCP6Input,
274
ListeningOnly: true,
275
Expectation: Expectation{
276
Ports: []ServedPort{
277
{Address: net.IPv6loopback, Port: 5900, BoundToLocalhost: true},
278
{Address: net.IPv6zero, Port: 22999},
279
{Address: net.IPv6zero, Port: 35900},
280
{Address: net.IPv6zero, Port: 36080},
281
},
282
},
283
},
284
{
285
Name: "invalid input",
286
Input: strings.ReplaceAll(validTCPInput, "0A", ""),
287
ListeningOnly: true,
288
Expectation: Expectation{},
289
},
290
}
291
292
for _, test := range tests {
293
t.Run(test.Name, func(t *testing.T) {
294
var act Expectation
295
act.Ports, act.Error = readNetTCPFile(bytes.NewReader([]byte(test.Input)), test.ListeningOnly)
296
297
if diff := cmp.Diff(test.Expectation, act); diff != "" {
298
t.Errorf("unexpected result (-want +got):\n%s", diff)
299
}
300
})
301
}
302
}
303
304