Skip to content

Commit

Permalink
Websocket derp test fixes (#2247)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
enoperm authored Nov 22, 2024
1 parent 6275399 commit 5fbf3f8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 4 deletions.
4 changes: 3 additions & 1 deletion Dockerfile.tailscale-HEAD
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ ARG VERSION_GIT_HASH=""
ENV VERSION_GIT_HASH=$VERSION_GIT_HASH
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.shortStamp=$VERSION_SHORT \
-X tailscale.com/version.gitCommitStamp=$VERSION_GIT_HASH" \
Expand Down
7 changes: 5 additions & 2 deletions integration/embedded_derp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestDERPServerWebsocketScenario(t *testing.T) {
spec := map[string]ClientsSpec{
"user1": {
Plain: 0,
WebsocketDERP: len(MustTestVersions),
WebsocketDERP: 2,
},
}

Expand Down Expand Up @@ -239,10 +239,13 @@ func (s *EmbeddedDERPServerScenario) CreateHeadscaleEnv(

if clientCount.WebsocketDERP > 0 {
// 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(
hash,
userName,
"all",
tsic.VersionHead,
clientCount.WebsocketDERP,
tsic.WithWebsocketDERP(true),
)
Expand Down
59 changes: 58 additions & 1 deletion integration/tsic/tsic.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"net/netip"
"net/url"
"os"
"reflect"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -44,6 +45,11 @@ var (
errTailscaleCannotUpWithoutAuthkey = errors.New("cannot up without authkey")
errTailscaleNotConnected = errors.New("tailscale not connected")
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 {
Expand Down Expand Up @@ -74,6 +80,13 @@ type TailscaleInContainer struct {
withExtraHosts []string
workdir 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
Expand Down Expand Up @@ -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.
func New(
pool *dockertest.Pool,
Expand Down Expand Up @@ -219,6 +248,12 @@ func New(
}

if tsic.withWebsocketDERP {
if version != VersionHead {
return tsic, errInvalidClientConfig
}

WithBuildTag("ts_debug_websockets")(tsic)

tailscaleOptions.Env = append(
tailscaleOptions.Env,
fmt.Sprintf("TS_DEBUG_DERP_WS_CLIENT=%t", tsic.withWebsocketDERP),
Expand All @@ -245,14 +280,36 @@ func New(
}

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 {
case "head":
case VersionHead:
buildOptions := &dockertest.BuildOptions{
Dockerfile: "Dockerfile.tailscale-HEAD",
ContextDir: dockerContextPath,
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(
buildOptions,
tailscaleOptions,
Expand Down

0 comments on commit 5fbf3f8

Please sign in to comment.