Previously, the orphaned connection cleanup job would not detect that a connection that was created before a worker had submitted a successful session info was orphaned. We now fall back to using the worker update time as an indicator if the session info time is not set.
112 lines
3.5 KiB
Go
112 lines
3.5 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package parallel
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/hashicorp/boundary/api/targets"
|
|
"github.com/hashicorp/boundary/internal/cmd/config"
|
|
"github.com/hashicorp/boundary/internal/daemon/controller"
|
|
"github.com/hashicorp/boundary/internal/daemon/worker"
|
|
"github.com/hashicorp/boundary/internal/session"
|
|
"github.com/hashicorp/boundary/internal/tests/helper"
|
|
"github.com/hashicorp/dawdle"
|
|
"github.com/hashicorp/go-hclog"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestSpeedyOrphanedConnectionCleanup tests that we successfully
|
|
// clean up connections that are orphaned to a worker that never
|
|
// successfully reported a session info.
|
|
func TestSpeedyOrphanedConnectionCleanup(t *testing.T) {
|
|
t.Parallel()
|
|
logger := hclog.New(&hclog.LoggerOptions{
|
|
Name: t.Name(),
|
|
Level: hclog.Trace,
|
|
})
|
|
|
|
conf, err := config.DevController()
|
|
require.NoError(t, err)
|
|
|
|
pl, err := net.Listen("tcp", "[::1]:0")
|
|
require.NoError(t, err)
|
|
c := controller.NewTestController(t, &controller.TestControllerOpts{
|
|
Config: conf,
|
|
InitialResourcesSuffix: "1234567890",
|
|
Logger: logger.Named("c1"),
|
|
PublicClusterAddr: pl.Addr().String(),
|
|
WorkerRPCGracePeriod: 2 * time.Second,
|
|
// Run the scheduler more often to speed up cleanup of orphaned connections
|
|
SchedulerRunJobInterval: time.Second,
|
|
})
|
|
|
|
helper.ExpectWorkers(t, c)
|
|
|
|
// Wire up the testing proxies
|
|
require.Len(t, c.ClusterAddrs(), 1)
|
|
proxy, err := dawdle.NewProxy("tcp", "", c.ClusterAddrs()[0],
|
|
dawdle.WithListener(pl),
|
|
dawdle.WithRbufSize(256),
|
|
dawdle.WithWbufSize(256),
|
|
)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() {
|
|
_ = proxy.Close()
|
|
})
|
|
require.NotEmpty(t, proxy.ListenerAddr())
|
|
|
|
w := worker.NewTestWorker(t, &worker.TestWorkerOpts{
|
|
WorkerAuthKms: c.Config().WorkerAuthKms,
|
|
InitialUpstreams: []string{proxy.ListenerAddr()},
|
|
Logger: logger.Named("w1"),
|
|
SuccessfulControllerRPCGracePeriodDuration: 2 * time.Second,
|
|
WorkerRPCInterval: time.Second,
|
|
})
|
|
|
|
helper.ExpectWorkers(t, c, w)
|
|
|
|
// Use an independent context for test things that take a context so
|
|
// that we aren't tied to any timeouts in the controller, etc. This
|
|
// can interfere with some of the test operations.
|
|
ctx := context.Background()
|
|
|
|
// Connect target
|
|
client := c.Client()
|
|
client.SetToken(c.Token().Token)
|
|
tcl := targets.NewClient(client)
|
|
tgt, err := tcl.Read(ctx, "ttcp_1234567890")
|
|
require.NoError(t, err)
|
|
require.NotNil(t, tgt)
|
|
|
|
// Create test server, update default port on target
|
|
ts := helper.NewTestTcpServer(t)
|
|
require.NotNil(t, ts)
|
|
t.Cleanup(ts.Close)
|
|
tgt, err = tcl.Update(ctx, tgt.Item.Id, tgt.Item.Version, targets.WithTcpTargetDefaultPort(ts.Port()), targets.WithSessionConnectionLimit(-1))
|
|
require.NoError(t, err)
|
|
require.NotNil(t, tgt)
|
|
|
|
// Authorize and connect
|
|
sess := helper.NewTestSession(ctx, t, tcl, "ttcp_1234567890")
|
|
sConn := sess.Connect(ctx, t)
|
|
|
|
// Run initial send/receive test, make sure things are working
|
|
t.Log("running initial send/recv test")
|
|
sConn.TestSendRecvAll(t)
|
|
|
|
// Kill the link before the worker has a chance to send a session info
|
|
t.Log("pausing controller/worker link")
|
|
proxy.Pause()
|
|
t.Cleanup(proxy.Resume) // Resume the proxy on cleanup to allow other cleanup to run
|
|
|
|
// Both the worker and the controller should detect that the worker is dead
|
|
// and close the connection.
|
|
sess.ExpectConnectionStateOnWorker(ctx, t, w, session.StatusClosed)
|
|
sess.ExpectConnectionStateOnController(ctx, t, c.Controller().ConnectionRepoFn, session.StatusClosed)
|
|
}
|