Websocket derp test fixes (#2247)

* integration testing: add and validate build-time options for tailscale head

* fixup! integration testing: add and validate build-time options for tailscale head

integration testing: comply with linter

* fixup! fixup! integration testing: add and validate build-time options for tailscale head

integration testing: tsic.New must never return nil

* fixup! fixup! fixup! integration testing: add and validate build-time options for tailscale head

* minor fixes
This commit is contained in:
enoperm 2024-11-22 11:57:01 +01:00 committed by GitHub
parent 6275399327
commit 5fbf3f8327
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 66 additions and 4 deletions

View File

@ -28,7 +28,9 @@ ARG VERSION_GIT_HASH=""
ENV VERSION_GIT_HASH=$VERSION_GIT_HASH ENV VERSION_GIT_HASH=$VERSION_GIT_HASH
ARG TARGETARCH ARG TARGETARCH
RUN GOARCH=$TARGETARCH go install -ldflags="\ ARG BUILD_TAGS=""
RUN GOARCH=$TARGETARCH go install -tags="${BUILD_TAGS}" -ldflags="\
-X tailscale.com/version.longStamp=$VERSION_LONG \ -X tailscale.com/version.longStamp=$VERSION_LONG \
-X tailscale.com/version.shortStamp=$VERSION_SHORT \ -X tailscale.com/version.shortStamp=$VERSION_SHORT \
-X tailscale.com/version.gitCommitStamp=$VERSION_GIT_HASH" \ -X tailscale.com/version.gitCommitStamp=$VERSION_GIT_HASH" \

View File

@ -55,7 +55,7 @@ func TestDERPServerWebsocketScenario(t *testing.T) {
spec := map[string]ClientsSpec{ spec := map[string]ClientsSpec{
"user1": { "user1": {
Plain: 0, Plain: 0,
WebsocketDERP: len(MustTestVersions), WebsocketDERP: 2,
}, },
} }
@ -239,10 +239,13 @@ func (s *EmbeddedDERPServerScenario) CreateHeadscaleEnv(
if clientCount.WebsocketDERP > 0 { if clientCount.WebsocketDERP > 0 {
// Containers that use DERP-over-WebSocket // Containers that use DERP-over-WebSocket
// Note that these clients *must* be built
// from source, which is currently
// only done for HEAD.
err = s.CreateTailscaleIsolatedNodesInUser( err = s.CreateTailscaleIsolatedNodesInUser(
hash, hash,
userName, userName,
"all", tsic.VersionHead,
clientCount.WebsocketDERP, clientCount.WebsocketDERP,
tsic.WithWebsocketDERP(true), tsic.WithWebsocketDERP(true),
) )

View File

@ -12,6 +12,7 @@ import (
"net/netip" "net/netip"
"net/url" "net/url"
"os" "os"
"reflect"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -44,6 +45,11 @@ var (
errTailscaleCannotUpWithoutAuthkey = errors.New("cannot up without authkey") errTailscaleCannotUpWithoutAuthkey = errors.New("cannot up without authkey")
errTailscaleNotConnected = errors.New("tailscale not connected") errTailscaleNotConnected = errors.New("tailscale not connected")
errTailscaledNotReadyForLogin = errors.New("tailscaled not ready for login") errTailscaledNotReadyForLogin = errors.New("tailscaled not ready for login")
errInvalidClientConfig = errors.New("verifiably invalid client config requested")
)
const (
VersionHead = "head"
) )
func errTailscaleStatus(hostname string, err error) error { func errTailscaleStatus(hostname string, err error) error {
@ -74,6 +80,13 @@ type TailscaleInContainer struct {
withExtraHosts []string withExtraHosts []string
workdir string workdir string
netfilter string netfilter string
// build options, solely for HEAD
buildConfig TailscaleInContainerBuildConfig
}
type TailscaleInContainerBuildConfig struct {
tags []string
} }
// Option represent optional settings that can be given to a // Option represent optional settings that can be given to a
@ -175,6 +188,22 @@ func WithNetfilter(state string) Option {
} }
} }
// WithBuildTag adds an additional value to the `-tags=` parameter
// of the Go compiler, allowing callers to customize the Tailscale client build.
// This option is only meaningful when invoked on **HEAD** versions of the client.
// Attempts to use it with any other version is a bug in the calling code.
func WithBuildTag(tag string) Option {
return func(tsic *TailscaleInContainer) {
if tsic.version != VersionHead {
panic(errInvalidClientConfig)
}
tsic.buildConfig.tags = append(
tsic.buildConfig.tags, tag,
)
}
}
// New returns a new TailscaleInContainer instance. // New returns a new TailscaleInContainer instance.
func New( func New(
pool *dockertest.Pool, pool *dockertest.Pool,
@ -219,6 +248,12 @@ func New(
} }
if tsic.withWebsocketDERP { if tsic.withWebsocketDERP {
if version != VersionHead {
return tsic, errInvalidClientConfig
}
WithBuildTag("ts_debug_websockets")(tsic)
tailscaleOptions.Env = append( tailscaleOptions.Env = append(
tailscaleOptions.Env, tailscaleOptions.Env,
fmt.Sprintf("TS_DEBUG_DERP_WS_CLIENT=%t", tsic.withWebsocketDERP), fmt.Sprintf("TS_DEBUG_DERP_WS_CLIENT=%t", tsic.withWebsocketDERP),
@ -245,14 +280,36 @@ func New(
} }
var container *dockertest.Resource var container *dockertest.Resource
if version != VersionHead {
// build options are not meaningful with pre-existing images,
// let's not lead anyone astray by pretending otherwise.
defaultBuildConfig := TailscaleInContainerBuildConfig{}
hasBuildConfig := !reflect.DeepEqual(defaultBuildConfig, tsic.buildConfig)
if hasBuildConfig {
return tsic, errInvalidClientConfig
}
}
switch version { switch version {
case "head": case VersionHead:
buildOptions := &dockertest.BuildOptions{ buildOptions := &dockertest.BuildOptions{
Dockerfile: "Dockerfile.tailscale-HEAD", Dockerfile: "Dockerfile.tailscale-HEAD",
ContextDir: dockerContextPath, ContextDir: dockerContextPath,
BuildArgs: []docker.BuildArg{}, BuildArgs: []docker.BuildArg{},
} }
buildTags := strings.Join(tsic.buildConfig.tags, ",")
if len(buildTags) > 0 {
buildOptions.BuildArgs = append(
buildOptions.BuildArgs,
docker.BuildArg{
Name: "BUILD_TAGS",
Value: buildTags,
},
)
}
container, err = pool.BuildAndRunWithBuildOptions( container, err = pool.BuildAndRunWithBuildOptions(
buildOptions, buildOptions,
tailscaleOptions, tailscaleOptions,