Handle errors in integration test setups
Thanks @kev-the-dev Closes #1460 Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
parent
63caf9a222
commit
b4a4d0f760
55 changed files with 829 additions and 1118 deletions
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/juanfont/headscale/integration/tsic"
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/puzpuzpuz/xsync/v2"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -33,30 +34,33 @@ var (
|
|||
tailscaleVersions2021 = []string{
|
||||
"head",
|
||||
"unstable",
|
||||
"1.40.0",
|
||||
"1.38.4",
|
||||
"1.36.2",
|
||||
"1.34.2",
|
||||
"1.32.3",
|
||||
"1.30.2",
|
||||
"1.48",
|
||||
"1.46",
|
||||
"1.44",
|
||||
"1.42",
|
||||
"1.40",
|
||||
"1.38",
|
||||
"1.36",
|
||||
"1.34",
|
||||
"1.32",
|
||||
"1.30",
|
||||
}
|
||||
|
||||
tailscaleVersions2019 = []string{
|
||||
"1.28.0",
|
||||
"1.26.2",
|
||||
"1.24.2",
|
||||
"1.22.2",
|
||||
"1.20.4",
|
||||
"1.28",
|
||||
"1.26",
|
||||
"1.24",
|
||||
"1.22",
|
||||
"1.20",
|
||||
"1.18",
|
||||
}
|
||||
|
||||
// tailscaleVersionsUnavailable = []string{
|
||||
// // These versions seem to fail when fetching from apt.
|
||||
// "1.18.2",
|
||||
// "1.16.2",
|
||||
// "1.14.6",
|
||||
// "1.12.4",
|
||||
// "1.10.2",
|
||||
// "1.8.7",
|
||||
// "1.14.6",
|
||||
// "1.12.4",
|
||||
// "1.10.2",
|
||||
// "1.8.7",
|
||||
// }.
|
||||
|
||||
// TailscaleVersions represents a list of Tailscale versions the suite
|
||||
|
@ -79,9 +83,9 @@ var (
|
|||
type User struct {
|
||||
Clients map[string]TailscaleClient
|
||||
|
||||
createWaitGroup sync.WaitGroup
|
||||
joinWaitGroup sync.WaitGroup
|
||||
syncWaitGroup sync.WaitGroup
|
||||
createWaitGroup errgroup.Group
|
||||
joinWaitGroup errgroup.Group
|
||||
syncWaitGroup errgroup.Group
|
||||
}
|
||||
|
||||
// Scenario is a representation of an environment with one ControlServer and
|
||||
|
@ -148,7 +152,7 @@ func NewScenario() (*Scenario, error) {
|
|||
// 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 (s *Scenario) Shutdown() error {
|
||||
func (s *Scenario) Shutdown() {
|
||||
s.controlServers.Range(func(_ string, control ControlServer) bool {
|
||||
err := control.Shutdown()
|
||||
if err != nil {
|
||||
|
@ -166,21 +170,19 @@ func (s *Scenario) Shutdown() error {
|
|||
log.Printf("removing client %s in user %s", client.Hostname(), userName)
|
||||
err := client.Shutdown()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to tear down client: %w", err)
|
||||
log.Printf("failed to tear down client: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.pool.RemoveNetwork(s.network); err != nil {
|
||||
return fmt.Errorf("failed to remove network: %w", err)
|
||||
log.Printf("failed to remove network: %s", err)
|
||||
}
|
||||
|
||||
// TODO(kradalby): This seem redundant to the previous call
|
||||
// if err := s.network.Close(); err != nil {
|
||||
// return fmt.Errorf("failed to tear down network: %w", err)
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Users returns the name of all users associated with the Scenario.
|
||||
|
@ -213,7 +215,7 @@ func (s *Scenario) Headscale(opts ...hsic.Option) (ControlServer, error) {
|
|||
return nil, fmt.Errorf("failed to create headscale container: %w", err)
|
||||
}
|
||||
|
||||
err = headscale.WaitForReady()
|
||||
err = headscale.WaitForRunning()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed reach headscale container: %w", err)
|
||||
}
|
||||
|
@ -286,17 +288,12 @@ func (s *Scenario) CreateTailscaleNodesInUser(
|
|||
cert := headscale.GetCert()
|
||||
hostname := headscale.GetHostname()
|
||||
|
||||
user.createWaitGroup.Add(1)
|
||||
|
||||
opts = append(opts,
|
||||
tsic.WithHeadscaleTLS(cert),
|
||||
tsic.WithHeadscaleName(hostname),
|
||||
)
|
||||
|
||||
go func() {
|
||||
defer user.createWaitGroup.Done()
|
||||
|
||||
// TODO(kradalby): error handle this
|
||||
user.createWaitGroup.Go(func() error {
|
||||
tsClient, err := tsic.New(
|
||||
s.pool,
|
||||
version,
|
||||
|
@ -304,20 +301,30 @@ func (s *Scenario) CreateTailscaleNodesInUser(
|
|||
opts...,
|
||||
)
|
||||
if err != nil {
|
||||
// return fmt.Errorf("failed to add tailscale node: %w", err)
|
||||
log.Printf("failed to create tailscale node: %s", err)
|
||||
return fmt.Errorf(
|
||||
"failed to create tailscale (%s) node: %w",
|
||||
tsClient.Hostname(),
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
err = tsClient.WaitForReady()
|
||||
err = tsClient.WaitForNeedsLogin()
|
||||
if err != nil {
|
||||
// return fmt.Errorf("failed to add tailscale node: %w", err)
|
||||
log.Printf("failed to wait for tailscaled: %s", err)
|
||||
return fmt.Errorf(
|
||||
"failed to wait for tailscaled (%s) to need login: %w",
|
||||
tsClient.Hostname(),
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
user.Clients[tsClient.Hostname()] = tsClient
|
||||
}()
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if err := user.createWaitGroup.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
user.createWaitGroup.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -332,29 +339,20 @@ func (s *Scenario) RunTailscaleUp(
|
|||
) error {
|
||||
if user, ok := s.users[userStr]; ok {
|
||||
for _, client := range user.Clients {
|
||||
user.joinWaitGroup.Add(1)
|
||||
|
||||
go func(c TailscaleClient) {
|
||||
defer user.joinWaitGroup.Done()
|
||||
|
||||
// TODO(kradalby): error handle this
|
||||
_ = c.Up(loginServer, authKey)
|
||||
}(client)
|
||||
|
||||
err := client.WaitForReady()
|
||||
if err != nil {
|
||||
log.Printf("error waiting for client %s to be ready: %s", client.Hostname(), err)
|
||||
}
|
||||
c := client
|
||||
user.joinWaitGroup.Go(func() error {
|
||||
return c.Login(loginServer, authKey)
|
||||
})
|
||||
}
|
||||
|
||||
user.joinWaitGroup.Wait()
|
||||
if err := user.joinWaitGroup.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, client := range user.Clients {
|
||||
err := client.WaitForReady()
|
||||
err := client.WaitForRunning()
|
||||
if err != nil {
|
||||
log.Printf("client %s was not ready: %s", client.Hostname(), err)
|
||||
|
||||
return fmt.Errorf("failed to up tailscale node: %w", err)
|
||||
return fmt.Errorf("%s failed to up tailscale node: %w", client.Hostname(), err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,18 +379,22 @@ func (s *Scenario) CountTailscale() int {
|
|||
func (s *Scenario) WaitForTailscaleSync() error {
|
||||
tsCount := s.CountTailscale()
|
||||
|
||||
return s.WaitForTailscaleSyncWithPeerCount(tsCount - 1)
|
||||
}
|
||||
|
||||
// WaitForTailscaleSyncWithPeerCount blocks execution until all the TailscaleClient reports
|
||||
// to have all other TailscaleClients present in their netmap.NetworkMap.
|
||||
func (s *Scenario) WaitForTailscaleSyncWithPeerCount(peerCount int) error {
|
||||
for _, user := range s.users {
|
||||
for _, client := range user.Clients {
|
||||
user.syncWaitGroup.Add(1)
|
||||
|
||||
go func(c TailscaleClient) {
|
||||
defer user.syncWaitGroup.Done()
|
||||
|
||||
// TODO(kradalby): error handle this
|
||||
_ = c.WaitForPeers(tsCount)
|
||||
}(client)
|
||||
c := client
|
||||
user.syncWaitGroup.Go(func() error {
|
||||
return c.WaitForPeers(peerCount)
|
||||
})
|
||||
}
|
||||
if err := user.syncWaitGroup.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
user.syncWaitGroup.Wait()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -555,18 +557,18 @@ func (s *Scenario) ListTailscaleClientsFQDNs(users ...string) ([]string, error)
|
|||
|
||||
// WaitForTailscaleLogout blocks execution until all TailscaleClients have
|
||||
// logged out of the ControlServer.
|
||||
func (s *Scenario) WaitForTailscaleLogout() {
|
||||
func (s *Scenario) WaitForTailscaleLogout() error {
|
||||
for _, user := range s.users {
|
||||
for _, client := range user.Clients {
|
||||
user.syncWaitGroup.Add(1)
|
||||
|
||||
go func(c TailscaleClient) {
|
||||
defer user.syncWaitGroup.Done()
|
||||
|
||||
// TODO(kradalby): error handle this
|
||||
_ = c.WaitForLogout()
|
||||
}(client)
|
||||
c := client
|
||||
user.syncWaitGroup.Go(func() error {
|
||||
return c.WaitForLogout()
|
||||
})
|
||||
}
|
||||
if err := user.syncWaitGroup.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
user.syncWaitGroup.Wait()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue