mirror of
https://github.com/coder/coder.git
synced 2026-06-03 21:18:24 +00:00
bddb808b25
Fixes all our Go file imports to match the preferred spec that we've _mostly_ been using. For example: ``` import ( "context" "time" "github.com/prometheus/client_golang/prometheus" "golang.org/x/xerrors" "gopkg.in/natefinch/lumberjack.v2" "cdr.dev/slog/v3" "github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/serpent" ) ``` 3 groups: standard library, 3rd partly libs, Coder libs. This PR makes the change across the codebase. The PR in the stack above modifies our formatting to maintain this state of affairs, and is a separate PR so it's possible to review that one in detail.
333 lines
9.7 KiB
Go
333 lines
9.7 KiB
Go
package tailnet_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"cdr.dev/slog/v3"
|
|
"cdr.dev/slog/v3/sloggers/slogtest"
|
|
"github.com/coder/coder/v2/coderd/database/dbtestutil"
|
|
"github.com/coder/coder/v2/enterprise/tailnet"
|
|
agpl "github.com/coder/coder/v2/tailnet"
|
|
agpltest "github.com/coder/coder/v2/tailnet/test"
|
|
"github.com/coder/coder/v2/testutil"
|
|
)
|
|
|
|
// TestPGCoordinator_MultiAgent tests a single coordinator with a MultiAgent
|
|
// connecting to one agent.
|
|
//
|
|
// +--------+
|
|
// agent1 ---> | coord1 | <--- client
|
|
// +--------+
|
|
func TestPGCoordinator_MultiAgent(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
|
|
store, ps := dbtestutil.NewDB(t)
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
|
defer cancel()
|
|
coord1, err := tailnet.NewPGCoord(ctx, logger.Named("coord1"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord1.Close()
|
|
|
|
agent1 := agpltest.NewAgent(ctx, t, coord1, "agent1")
|
|
defer agent1.Close(ctx)
|
|
agent1.UpdateDERP(5)
|
|
|
|
ma1 := agpltest.NewPeer(ctx, t, coord1, "client")
|
|
defer ma1.Close(ctx)
|
|
|
|
ma1.AddTunnel(agent1.ID)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 5)
|
|
|
|
agent1.UpdateDERP(1)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 1)
|
|
|
|
ma1.UpdateDERP(3)
|
|
agent1.AssertEventuallyHasDERP(ma1.ID, 3)
|
|
|
|
ma1.Disconnect()
|
|
agent1.UngracefulDisconnect(ctx)
|
|
|
|
assertEventuallyNoClientsForAgent(ctx, t, store, agent1.ID)
|
|
assertEventuallyLost(ctx, t, store, agent1.ID)
|
|
}
|
|
|
|
func TestPGCoordinator_MultiAgent_CoordClose(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
|
|
store, ps := dbtestutil.NewDB(t)
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
|
defer cancel()
|
|
coord1, err := tailnet.NewPGCoord(ctx, logger.Named("coord1"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord1.Close()
|
|
|
|
ma1 := agpltest.NewPeer(ctx, t, coord1, "client")
|
|
defer ma1.Close(ctx)
|
|
|
|
err = coord1.Close()
|
|
require.NoError(t, err)
|
|
|
|
ma1.AssertEventuallyResponsesClosed(agpl.CloseErrCoordinatorClose)
|
|
}
|
|
|
|
// TestPGCoordinator_MultiAgent_UnsubscribeRace tests a single coordinator with
|
|
// a MultiAgent connecting to one agent. It tries to race a call to Unsubscribe
|
|
// with the MultiAgent closing.
|
|
//
|
|
// +--------+
|
|
// agent1 ---> | coord1 | <--- client
|
|
// +--------+
|
|
func TestPGCoordinator_MultiAgent_UnsubscribeRace(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
|
|
store, ps := dbtestutil.NewDB(t)
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
|
defer cancel()
|
|
coord1, err := tailnet.NewPGCoord(ctx, logger.Named("coord1"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord1.Close()
|
|
|
|
agent1 := agpltest.NewAgent(ctx, t, coord1, "agent1")
|
|
defer agent1.Close(ctx)
|
|
agent1.UpdateDERP(5)
|
|
|
|
ma1 := agpltest.NewPeer(ctx, t, coord1, "client")
|
|
defer ma1.Close(ctx)
|
|
|
|
ma1.AddTunnel(agent1.ID)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 5)
|
|
|
|
agent1.UpdateDERP(1)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 1)
|
|
|
|
ma1.UpdateDERP(3)
|
|
agent1.AssertEventuallyHasDERP(ma1.ID, 3)
|
|
|
|
ma1.RemoveTunnel(agent1.ID)
|
|
ma1.Close(ctx)
|
|
agent1.UngracefulDisconnect(ctx)
|
|
|
|
assertEventuallyNoClientsForAgent(ctx, t, store, agent1.ID)
|
|
assertEventuallyLost(ctx, t, store, agent1.ID)
|
|
}
|
|
|
|
// TestPGCoordinator_MultiAgent_Unsubscribe tests a single coordinator with a
|
|
// MultiAgent connecting to one agent. It unsubscribes before closing, and
|
|
// ensures node updates are no longer propagated.
|
|
//
|
|
// +--------+
|
|
// agent1 ---> | coord1 | <--- client
|
|
// +--------+
|
|
func TestPGCoordinator_MultiAgent_Unsubscribe(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
|
|
store, ps := dbtestutil.NewDB(t)
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
|
defer cancel()
|
|
coord1, err := tailnet.NewPGCoord(ctx, logger.Named("coord1"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord1.Close()
|
|
|
|
agent1 := agpltest.NewAgent(ctx, t, coord1, "agent1")
|
|
defer agent1.Close(ctx)
|
|
agent1.UpdateDERP(5)
|
|
|
|
ma1 := agpltest.NewPeer(ctx, t, coord1, "client")
|
|
defer ma1.Close(ctx)
|
|
|
|
ma1.AddTunnel(agent1.ID)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 5)
|
|
|
|
agent1.UpdateDERP(1)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 1)
|
|
|
|
ma1.UpdateDERP(3)
|
|
agent1.AssertEventuallyHasDERP(ma1.ID, 3)
|
|
|
|
ma1.RemoveTunnel(agent1.ID)
|
|
assertEventuallyNoClientsForAgent(ctx, t, store, agent1.ID)
|
|
|
|
func() {
|
|
ctx, cancel := context.WithTimeout(ctx, testutil.IntervalSlow*3)
|
|
defer cancel()
|
|
ma1.UpdateDERP(9)
|
|
agent1.AssertNeverHasDERPs(ctx, ma1.ID, 9)
|
|
}()
|
|
func() {
|
|
ctx, cancel := context.WithTimeout(ctx, testutil.IntervalSlow*3)
|
|
defer cancel()
|
|
agent1.UpdateDERP(8)
|
|
ma1.AssertNeverHasDERPs(ctx, agent1.ID, 8)
|
|
}()
|
|
|
|
ma1.Disconnect()
|
|
agent1.UngracefulDisconnect(ctx)
|
|
|
|
assertEventuallyNoClientsForAgent(ctx, t, store, agent1.ID)
|
|
assertEventuallyLost(ctx, t, store, agent1.ID)
|
|
}
|
|
|
|
// TestPGCoordinator_MultiAgent_MultiCoordinator tests two coordinators with a
|
|
// MultiAgent connecting to an agent on a separate coordinator.
|
|
//
|
|
// +--------+
|
|
// agent1 ---> | coord1 |
|
|
// +--------+
|
|
// +--------+
|
|
// | coord2 | <--- client
|
|
// +--------+
|
|
func TestPGCoordinator_MultiAgent_MultiCoordinator(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
|
|
store, ps := dbtestutil.NewDB(t)
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
|
defer cancel()
|
|
coord1, err := tailnet.NewPGCoord(ctx, logger.Named("coord1"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord1.Close()
|
|
coord2, err := tailnet.NewPGCoord(ctx, logger.Named("coord2"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord2.Close()
|
|
|
|
agent1 := agpltest.NewAgent(ctx, t, coord1, "agent1")
|
|
defer agent1.Close(ctx)
|
|
agent1.UpdateDERP(5)
|
|
|
|
ma1 := agpltest.NewPeer(ctx, t, coord2, "client")
|
|
defer ma1.Close(ctx)
|
|
|
|
ma1.AddTunnel(agent1.ID)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 5)
|
|
|
|
agent1.UpdateDERP(1)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 1)
|
|
|
|
ma1.UpdateDERP(3)
|
|
agent1.AssertEventuallyHasDERP(ma1.ID, 3)
|
|
|
|
ma1.Disconnect()
|
|
agent1.UngracefulDisconnect(ctx)
|
|
|
|
assertEventuallyNoClientsForAgent(ctx, t, store, agent1.ID)
|
|
assertEventuallyLost(ctx, t, store, agent1.ID)
|
|
}
|
|
|
|
// TestPGCoordinator_MultiAgent_MultiCoordinator_UpdateBeforeSubscribe tests two
|
|
// coordinators with a MultiAgent connecting to an agent on a separate
|
|
// coordinator. The MultiAgent updates its own node before subscribing.
|
|
//
|
|
// +--------+
|
|
// agent1 ---> | coord1 |
|
|
// +--------+
|
|
// +--------+
|
|
// | coord2 | <--- client
|
|
// +--------+
|
|
func TestPGCoordinator_MultiAgent_MultiCoordinator_UpdateBeforeSubscribe(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
|
|
store, ps := dbtestutil.NewDB(t)
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
|
defer cancel()
|
|
coord1, err := tailnet.NewPGCoord(ctx, logger.Named("coord1"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord1.Close()
|
|
coord2, err := tailnet.NewPGCoord(ctx, logger.Named("coord2"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord2.Close()
|
|
|
|
agent1 := agpltest.NewAgent(ctx, t, coord1, "agent1")
|
|
defer agent1.Close(ctx)
|
|
agent1.UpdateDERP(5)
|
|
|
|
ma1 := agpltest.NewPeer(ctx, t, coord2, "client")
|
|
defer ma1.Close(ctx)
|
|
|
|
ma1.UpdateDERP(3)
|
|
|
|
ma1.AddTunnel(agent1.ID)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 5)
|
|
agent1.AssertEventuallyHasDERP(ma1.ID, 3)
|
|
|
|
agent1.UpdateDERP(1)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 1)
|
|
|
|
ma1.Disconnect()
|
|
agent1.UngracefulDisconnect(ctx)
|
|
|
|
assertEventuallyNoClientsForAgent(ctx, t, store, agent1.ID)
|
|
assertEventuallyLost(ctx, t, store, agent1.ID)
|
|
}
|
|
|
|
// TestPGCoordinator_MultiAgent_TwoAgents tests three coordinators with a
|
|
// MultiAgent connecting to two agents on separate coordinators.
|
|
//
|
|
// +--------+
|
|
// agent1 ---> | coord1 |
|
|
// +--------+
|
|
// +--------+
|
|
// agent2 ---> | coord2 |
|
|
// +--------+
|
|
// +--------+
|
|
// | coord3 | <--- client
|
|
// +--------+
|
|
func TestPGCoordinator_MultiAgent_TwoAgents(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
|
|
store, ps := dbtestutil.NewDB(t)
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
|
defer cancel()
|
|
coord1, err := tailnet.NewPGCoord(ctx, logger.Named("coord1"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord1.Close()
|
|
coord2, err := tailnet.NewPGCoord(ctx, logger.Named("coord2"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord2.Close()
|
|
coord3, err := tailnet.NewPGCoord(ctx, logger.Named("coord3"), ps, store)
|
|
require.NoError(t, err)
|
|
defer coord3.Close()
|
|
|
|
agent1 := agpltest.NewAgent(ctx, t, coord1, "agent1")
|
|
defer agent1.Close(ctx)
|
|
agent1.UpdateDERP(5)
|
|
|
|
agent2 := agpltest.NewAgent(ctx, t, coord2, "agent2")
|
|
defer agent2.Close(ctx)
|
|
agent2.UpdateDERP(6)
|
|
|
|
ma1 := agpltest.NewPeer(ctx, t, coord3, "client")
|
|
defer ma1.Close(ctx)
|
|
|
|
ma1.AddTunnel(agent1.ID)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 5)
|
|
|
|
agent1.UpdateDERP(1)
|
|
ma1.AssertEventuallyHasDERP(agent1.ID, 1)
|
|
|
|
ma1.AddTunnel(agent2.ID)
|
|
ma1.AssertEventuallyHasDERP(agent2.ID, 6)
|
|
|
|
agent2.UpdateDERP(2)
|
|
ma1.AssertEventuallyHasDERP(agent2.ID, 2)
|
|
|
|
ma1.UpdateDERP(3)
|
|
agent1.AssertEventuallyHasDERP(ma1.ID, 3)
|
|
agent2.AssertEventuallyHasDERP(ma1.ID, 3)
|
|
|
|
ma1.Disconnect()
|
|
agent1.UngracefulDisconnect(ctx)
|
|
agent2.UngracefulDisconnect(ctx)
|
|
|
|
assertEventuallyNoClientsForAgent(ctx, t, store, agent1.ID)
|
|
assertEventuallyLost(ctx, t, store, agent1.ID)
|
|
}
|