integration

package
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 17, 2023 License: BSD-3-Clause Imports: 17 Imported by: 0

README

Integration testing

Headscale relies on integration testing to ensure we remain compatible with Tailscale.

This is typically performed by starting a Headscale server and running a test "scenario" with an array of Tailscale clients and versions.

Headscale's test framework and the current set of scenarios are defined in this directory.

Tests are located in files ending with _test.go and the framework are located in the rest.

Running integration tests locally

The easiest way to run tests locally is to use [act](INSERT LINK), a local GitHub Actions runner:

act pull_request -W .github/workflows/test-integration-v2-TestPingAllByIP.yaml

Alternatively, the docker run command in each GitHub workflow file can be used.

Running integration tests on GitHub Actions

Each test currently runs as a separate workflows in GitHub actions, to add new test, run go generate inside ../cmd/gh-action-integration-generator/ and commit the result.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (

	// TailscaleVersions represents a list of Tailscale versions the suite
	// uses to test compatibility with the ControlServer.
	//
	// The list contains two special cases, "head" and "unstable" which
	// points to the current tip of Tailscale's main branch and the latest
	// released unstable version.
	//
	// The rest of the version represents Tailscale versions that can be
	// found in Tailscale's apt repository.
	TailscaleVersions = append(
		tailscaleVersions2021,
		tailscaleVersions2019...,
	)
)

Functions

This section is empty.

Types

type ControlServer

type ControlServer interface {
	Shutdown() error
	SaveLog(string) error
	Execute(command []string) (string, error)
	GetHealthEndpoint() string
	GetEndpoint() string
	WaitForReady() error
	CreateUser(user string) error
	CreateAuthKey(user string, reusable bool, ephemeral bool) (*v1.PreAuthKey, error)
	ListMachinesInUser(user string) ([]*v1.Machine, error)
	GetCert() []byte
	GetHostname() string
	GetIP() string
}

type Scenario

type Scenario struct {
	// contains filtered or unexported fields
}

Scenario is a representation of an environment with one ControlServer and one or more User's and its associated TailscaleClients. A Scenario is intended to simplify setting up a new testcase for testing a ControlServer with TailscaleClients. TODO(kradalby): make control server configurable, test correctness with Tailscale SaaS.

func NewScenario

func NewScenario() (*Scenario, error)

NewScenario creates a test Scenario which can be used to bootstraps a ControlServer with a set of Users and TailscaleClients.

func (*Scenario) CountTailscale

func (s *Scenario) CountTailscale() int

CountTailscale returns the total number of TailscaleClients in a Scenario. This is the sum of Users x TailscaleClients.

func (*Scenario) CreateHeadscaleEnv

func (s *Scenario) CreateHeadscaleEnv(
	users map[string]int,
	tsOpts []tsic.Option,
	opts ...hsic.Option,
) error

CreateHeadscaleEnv is a conventient method returning a complete Headcale test environment with nodes of all versions, joined to the server with X users.

func (*Scenario) CreatePreAuthKey

func (s *Scenario) CreatePreAuthKey(
	user string,
	reusable bool,
	ephemeral bool,
) (*v1.PreAuthKey, error)

CreatePreAuthKey creates a "pre authentorised key" to be created in the Headscale instance on behalf of the Scenario.

func (*Scenario) CreateTailscaleNodesInUser

func (s *Scenario) CreateTailscaleNodesInUser(
	userStr string,
	requestedVersion string,
	count int,
	opts ...tsic.Option,
) error

CreateTailscaleNodesInUser creates and adds a new TailscaleClient to a User in the Scenario.

func (*Scenario) CreateUser

func (s *Scenario) CreateUser(user string) error

CreateUser creates a User to be created in the Headscale instance on behalf of the Scenario.

func (*Scenario) FindTailscaleClientByIP

func (s *Scenario) FindTailscaleClientByIP(ip netip.Addr) (TailscaleClient, error)

FindTailscaleClientByIP returns a TailscaleClient associated with an IP address if it exists.

func (*Scenario) GetClients

func (s *Scenario) GetClients(user string) ([]TailscaleClient, error)

GetIPs returns all TailscaleClients associated with a User in a Scenario.

func (*Scenario) GetIPs

func (s *Scenario) GetIPs(user string) ([]netip.Addr, error)

GetIPs returns all netip.Addr of TailscaleClients associated with a User in a Scenario.

func (*Scenario) Headscale

func (s *Scenario) Headscale(opts ...hsic.Option) (ControlServer, error)

Headscale returns a ControlServer instance based on hsic (HeadscaleInContainer) If the Scenario already has an instance, the pointer to the running container will be return, otherwise a new instance will be created. TODO(kradalby): make port and headscale configurable, multiple instances support?

func (*Scenario) ListTailscaleClients

func (s *Scenario) ListTailscaleClients(users ...string) ([]TailscaleClient, error)

ListTailscaleClients returns a list of TailscaleClients given the Users passed as parameters.

func (*Scenario) ListTailscaleClientsFQDNs

func (s *Scenario) ListTailscaleClientsFQDNs(users ...string) ([]string, error)

ListTailscaleClientsIPs returns a list of FQDN based on Users passed as parameters.

func (*Scenario) ListTailscaleClientsIPs

func (s *Scenario) ListTailscaleClientsIPs(users ...string) ([]netip.Addr, error)

ListTailscaleClientsIPs returns a list of netip.Addr based on Users passed as parameters.

func (*Scenario) RunTailscaleUp

func (s *Scenario) RunTailscaleUp(
	userStr, loginServer, authKey string,
) error

RunTailscaleUp will log in all of the TailscaleClients associated with a User to the given ControlServer (by URL).

func (*Scenario) Shutdown

func (s *Scenario) Shutdown() error

Shutdown shuts down and cleans up all the containers (ControlServer, TailscaleClient) and networks associated with it. In addition, it will save the logs of the ControlServer to `/tmp/control` in the environment running the tests.

func (*Scenario) Users

func (s *Scenario) Users() []string

Users returns the name of all users associated with the Scenario.

func (*Scenario) WaitForTailscaleLogout

func (s *Scenario) WaitForTailscaleLogout()

WaitForTailscaleLogout blocks execution until all TailscaleClients have logged out of the ControlServer.

func (*Scenario) WaitForTailscaleSync

func (s *Scenario) WaitForTailscaleSync() error

WaitForTailscaleSync blocks execution until all the TailscaleClient reports to have all other TailscaleClients present in their netmap.NetworkMap.

type TailscaleClient

type TailscaleClient interface {
	Hostname() string
	Shutdown() error
	Version() string
	Execute(command []string) (string, string, error)
	Up(loginServer, authKey string) error
	UpWithLoginURL(loginServer string) (*url.URL, error)
	Logout() error
	IPs() ([]netip.Addr, error)
	FQDN() (string, error)
	Status() (*ipnstate.Status, error)
	WaitForReady() error
	WaitForLogout() error
	WaitForPeers(expected int) error
	Ping(hostnameOrIP string, opts ...tsic.PingOption) error
	Curl(url string, opts ...tsic.CurlOption) (string, error)
	ID() string
}

nolint

type User

type User struct {
	Clients map[string]TailscaleClient
	// contains filtered or unexported fields
}

User represents a User in the ControlServer and a map of TailscaleClient's associated with the User.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL