@@ -129,9 +129,67 @@ func TestDERP(t *testing.T) {
129
129
assert .True (t , report .Healthy )
130
130
assert .Equal (t , health .SeverityWarning , report .Severity )
131
131
assert .True (t , report .Dismissed )
132
- if assert .NotEmpty (t , report .Warnings ) {
132
+ if assert .Len (t , report .Warnings , 1 ) {
133
133
assert .Contains (t , report .Warnings [0 ].Code , health .CodeDERPOneNodeUnhealthy )
134
134
}
135
+ for _ , region := range report .Regions {
136
+ assert .True (t , region .Healthy )
137
+ assert .True (t , region .NodeReports [0 ].Healthy )
138
+ assert .Empty (t , region .NodeReports [0 ].Warnings )
139
+ assert .Equal (t , health .SeverityOK , region .NodeReports [0 ].Severity )
140
+ assert .False (t , region .NodeReports [1 ].Healthy )
141
+ assert .Equal (t , health .SeverityError , region .NodeReports [1 ].Severity )
142
+ assert .Len (t , region .Warnings , 1 )
143
+ }
144
+ })
145
+
146
+ t .Run ("HealthyWithNoSTUN" , func (t * testing.T ) {
147
+ t .Parallel ()
148
+
149
+ healthyDerpSrv := derp .NewServer (key .NewNode (), func (format string , args ... any ) { t .Logf (format , args ... ) })
150
+ defer healthyDerpSrv .Close ()
151
+ healthySrv := httptest .NewServer (derphttp .Handler (healthyDerpSrv ))
152
+ defer healthySrv .Close ()
153
+
154
+ var (
155
+ ctx = context .Background ()
156
+ report = derphealth.Report {}
157
+ derpURL , _ = url .Parse (healthySrv .URL )
158
+ opts = & derphealth.ReportOptions {
159
+ DERPMap : & tailcfg.DERPMap {Regions : map [int ]* tailcfg.DERPRegion {
160
+ 1 : {
161
+ EmbeddedRelay : true ,
162
+ RegionID : 999 ,
163
+ Nodes : []* tailcfg.DERPNode {{
164
+ Name : "1a" ,
165
+ RegionID : 999 ,
166
+ HostName : derpURL .Host ,
167
+ IPv4 : derpURL .Host ,
168
+ STUNPort : - 1 ,
169
+ InsecureForTests : true ,
170
+ ForceHTTP : true ,
171
+ }, {
172
+ Name : "badstun" ,
173
+ RegionID : 999 ,
174
+ HostName : derpURL .Host ,
175
+ STUNPort : 19302 ,
176
+ STUNOnly : true ,
177
+ InsecureForTests : true ,
178
+ ForceHTTP : true ,
179
+ }},
180
+ },
181
+ }},
182
+ }
183
+ )
184
+
185
+ report .Run (ctx , opts )
186
+
187
+ assert .True (t , report .Healthy )
188
+ assert .Equal (t , health .SeverityWarning , report .Severity )
189
+ if assert .Len (t , report .Warnings , 2 ) {
190
+ assert .EqualValues (t , report .Warnings [1 ].Code , health .CodeSTUNNoNodes )
191
+ assert .EqualValues (t , report .Warnings [0 ].Code , health .CodeDERPOneNodeUnhealthy )
192
+ }
135
193
for _ , region := range report .Regions {
136
194
assert .True (t , region .Healthy )
137
195
assert .True (t , region .NodeReports [0 ].Healthy )
@@ -291,8 +349,10 @@ func TestDERP(t *testing.T) {
291
349
report .Run (ctx , opts )
292
350
293
351
assert .True (t , report .Healthy )
352
+ assert .Equal (t , health .SeverityOK , report .Severity )
294
353
for _ , region := range report .Regions {
295
354
assert .True (t , region .Healthy )
355
+ assert .Equal (t , health .SeverityOK , region .Severity )
296
356
for _ , node := range region .NodeReports {
297
357
assert .True (t , node .Healthy )
298
358
assert .False (t , node .CanExchangeMessages )
@@ -304,6 +364,107 @@ func TestDERP(t *testing.T) {
304
364
}
305
365
}
306
366
})
367
+
368
+ t .Run ("STUNOnly/OneBadOneGood" , func (t * testing.T ) {
369
+ t .Parallel ()
370
+
371
+ var (
372
+ ctx = context .Background ()
373
+ report = derphealth.Report {}
374
+ opts = & derphealth.ReportOptions {
375
+ DERPMap : & tailcfg.DERPMap {
376
+ Regions : map [int ]* tailcfg.DERPRegion {
377
+ 1 : {
378
+ EmbeddedRelay : true ,
379
+ RegionID : 999 ,
380
+ Nodes : []* tailcfg.DERPNode {{
381
+ Name : "badstun" ,
382
+ RegionID : 999 ,
383
+ HostName : "badstun.example.com" ,
384
+ STUNPort : 19302 ,
385
+ STUNOnly : true ,
386
+ InsecureForTests : true ,
387
+ ForceHTTP : true ,
388
+ }, {
389
+ Name : "goodstun" ,
390
+ RegionID : 999 ,
391
+ HostName : "stun.l.google.com" ,
392
+ STUNPort : 19302 ,
393
+ STUNOnly : true ,
394
+ InsecureForTests : true ,
395
+ ForceHTTP : true ,
396
+ }},
397
+ },
398
+ },
399
+ },
400
+ }
401
+ )
402
+
403
+ report .Run (ctx , opts )
404
+ assert .True (t , report .Healthy )
405
+ assert .Equal (t , health .SeverityWarning , report .Severity )
406
+ if assert .Len (t , report .Warnings , 1 ) {
407
+ assert .Equal (t , health .CodeDERPOneNodeUnhealthy , report .Warnings [0 ].Code )
408
+ }
409
+ for _ , region := range report .Regions {
410
+ assert .True (t , region .Healthy )
411
+ assert .Equal (t , health .SeverityWarning , region .Severity )
412
+ // badstun
413
+ assert .False (t , region .NodeReports [0 ].Healthy )
414
+ assert .True (t , region .NodeReports [0 ].STUN .Enabled )
415
+ assert .False (t , region .NodeReports [0 ].STUN .CanSTUN )
416
+ assert .NotNil (t , region .NodeReports [0 ].STUN .Error )
417
+ // goodstun
418
+ assert .True (t , region .NodeReports [1 ].Healthy )
419
+ assert .True (t , region .NodeReports [1 ].STUN .Enabled )
420
+ assert .True (t , region .NodeReports [1 ].STUN .CanSTUN )
421
+ assert .Nil (t , region .NodeReports [1 ].STUN .Error )
422
+ }
423
+ })
424
+
425
+ t .Run ("STUNOnly/NoStun" , func (t * testing.T ) {
426
+ t .Parallel ()
427
+
428
+ var (
429
+ ctx = context .Background ()
430
+ report = derphealth.Report {}
431
+ opts = & derphealth.ReportOptions {
432
+ DERPMap : & tailcfg.DERPMap {
433
+ Regions : map [int ]* tailcfg.DERPRegion {
434
+ 1 : {
435
+ EmbeddedRelay : true ,
436
+ RegionID : 999 ,
437
+ Nodes : []* tailcfg.DERPNode {{
438
+ Name : "badstun" ,
439
+ RegionID : 999 ,
440
+ HostName : "badstun.example.com" ,
441
+ STUNPort : 19302 ,
442
+ STUNOnly : true ,
443
+ InsecureForTests : true ,
444
+ ForceHTTP : true ,
445
+ }},
446
+ },
447
+ },
448
+ },
449
+ }
450
+ )
451
+
452
+ report .Run (ctx , opts )
453
+ assert .False (t , report .Healthy )
454
+ assert .Equal (t , health .SeverityError , report .Severity )
455
+ for _ , region := range report .Regions {
456
+ assert .False (t , region .Healthy )
457
+ assert .Equal (t , health .SeverityError , region .Severity )
458
+ for _ , node := range region .NodeReports {
459
+ assert .False (t , node .Healthy )
460
+ assert .False (t , node .CanExchangeMessages )
461
+ assert .Empty (t , node .ClientLogs )
462
+ assert .True (t , node .STUN .Enabled )
463
+ assert .False (t , node .STUN .CanSTUN )
464
+ assert .NotNil (t , node .STUN .Error )
465
+ }
466
+ }
467
+ })
307
468
}
308
469
309
470
func tsDERPMap (ctx context.Context , t testing.TB ) * tailcfg.DERPMap {
0 commit comments