Skip to content

Commit 2c2ca6b

Browse files
committed
Add 10s delay test to ensure endpoints don't appear
1 parent 73ac7b9 commit 2c2ca6b

File tree

1 file changed

+77
-1
lines changed

1 file changed

+77
-1
lines changed

tailnet/conn_test.go

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"net/netip"
66
"testing"
7+
"time"
78

89
"github.com/google/uuid"
910
"github.com/stretchr/testify/assert"
@@ -412,9 +413,78 @@ parentLoop:
412413
require.True(t, client2.AwaitReachable(awaitReachableCtx4, ip))
413414
}
414415

416+
func TestConn_BlockEndpoints(t *testing.T) {
417+
t.Parallel()
418+
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
419+
420+
derpMap, _ := tailnettest.RunDERPAndSTUN(t)
421+
422+
// Setup conn 1.
423+
ip1 := tailnet.IP()
424+
conn1, err := tailnet.NewConn(&tailnet.Options{
425+
Addresses: []netip.Prefix{netip.PrefixFrom(ip1, 128)},
426+
Logger: logger.Named("w1"),
427+
DERPMap: derpMap,
428+
BlockEndpoints: true,
429+
})
430+
require.NoError(t, err)
431+
defer func() {
432+
err := conn1.Close()
433+
assert.NoError(t, err)
434+
}()
435+
436+
// Setup conn 2.
437+
ip2 := tailnet.IP()
438+
conn2, err := tailnet.NewConn(&tailnet.Options{
439+
Addresses: []netip.Prefix{netip.PrefixFrom(ip2, 128)},
440+
Logger: logger.Named("w2"),
441+
DERPMap: derpMap,
442+
BlockEndpoints: true,
443+
})
444+
require.NoError(t, err)
445+
defer func() {
446+
err := conn2.Close()
447+
assert.NoError(t, err)
448+
}()
449+
450+
// Connect them together and wait for them to be reachable.
451+
nodes1 := stitch(t, conn2, conn1)
452+
nodes2 := stitch(t, conn1, conn2)
453+
awaitReachableCtx, awaitReachableCancel := context.WithTimeout(context.Background(), testutil.WaitShort)
454+
defer awaitReachableCancel()
455+
require.True(t, conn1.AwaitReachable(awaitReachableCtx, ip2))
456+
457+
// Watch for 10 seconds to ensure that neither peer has any endpoints.
458+
// There's no good way to force endpoint updates, so we just wait.
459+
parentLoop:
460+
for {
461+
select {
462+
case node := <-nodes1:
463+
require.Empty(t, node.Endpoints, "conn1 got endpoints")
464+
case node := <-nodes2:
465+
require.Empty(t, node.Endpoints, "conn2 got endpoints")
466+
case <-time.After(testutil.WaitShort):
467+
break parentLoop
468+
}
469+
}
470+
471+
// Double check that both peers don't have endpoints for the other peer
472+
// according to magicsock.
473+
conn1Status, ok := conn1.Status().Peer[conn2.Node().Key]
474+
require.True(t, ok)
475+
require.Empty(t, conn1Status.Addrs)
476+
require.Empty(t, conn1Status.CurAddr)
477+
conn2Status, ok := conn2.Status().Peer[conn1.Node().Key]
478+
require.True(t, ok)
479+
require.Empty(t, conn2Status.Addrs)
480+
require.Empty(t, conn2Status.CurAddr)
481+
}
482+
415483
// stitch sends node updates from src Conn as peer updates to dst Conn. Sort of
416484
// like the Coordinator would, but without actually needing a Coordinator.
417-
func stitch(t *testing.T, dst, src *tailnet.Conn) {
485+
func stitch(t *testing.T, dst, src *tailnet.Conn) <-chan *tailnet.Node {
486+
// Buffered to avoid blocking the callback.
487+
out := make(chan *tailnet.Node, 50)
418488
srcID := uuid.New()
419489
src.SetNodeCallback(func(node *tailnet.Node) {
420490
pn, err := tailnet.NodeToProto(node)
@@ -427,5 +497,11 @@ func stitch(t *testing.T, dst, src *tailnet.Conn) {
427497
Kind: proto.CoordinateResponse_PeerUpdate_NODE,
428498
}})
429499
assert.NoError(t, err)
500+
501+
select {
502+
case out <- node:
503+
default:
504+
}
430505
})
506+
return out
431507
}

0 commit comments

Comments
 (0)