From ca15a53fad29482f86392d1e002d1fa7af316eab Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 31 Oct 2021 09:58:01 +0000 Subject: [PATCH] Add timeout to integration test for execCommand to fail faster --- integration_test.go | 58 +++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/integration_test.go b/integration_test.go index 07894188..1f30bcab 100644 --- a/integration_test.go +++ b/integration_test.go @@ -39,7 +39,7 @@ var ( headscale dockertest.Resource ) -var tailscaleVersions = []string{"1.14.3", "1.12.3"} +var tailscaleVersions = []string{"1.16.2", "1.14.3", "1.12.3"} type TestNamespace struct { count int @@ -99,26 +99,48 @@ func executeCommand(resource *dockertest.Resource, cmd []string, env []string) ( var stdout bytes.Buffer var stderr bytes.Buffer - exitCode, err := resource.Exec( - cmd, - dockertest.ExecOptions{ - Env: env, - StdOut: &stdout, - StdErr: &stderr, - }, - ) - if err != nil { - return "", err + // TODO(kradalby): Make configurable + timeout := 10 * time.Second + + type result struct { + exitCode int + err error } - if exitCode != 0 { - fmt.Println("Command: ", cmd) - fmt.Println("stdout: ", stdout.String()) - fmt.Println("stderr: ", stderr.String()) - return "", fmt.Errorf("command failed with: %s", stderr.String()) - } + resultChan := make(chan result, 1) - return stdout.String(), nil + // Run your long running function in it's own goroutine and pass back it's + // response into our channel. + go func() { + exitCode, err := resource.Exec( + cmd, + dockertest.ExecOptions{ + Env: env, + StdOut: &stdout, + StdErr: &stderr, + }, + ) + resultChan <- result{exitCode, err} + }() + + // Listen on our channel AND a timeout channel - which ever happens first. + select { + case res := <-resultChan: + if res.err != nil { + return "", res.err + } + + if res.exitCode != 0 { + fmt.Println("Command: ", cmd) + fmt.Println("stdout: ", stdout.String()) + fmt.Println("stderr: ", stderr.String()) + return "", fmt.Errorf("command failed with: %s", stderr.String()) + } + + return stdout.String(), nil + case <-time.After(timeout): + return "", fmt.Errorf("command timed out after %s", timeout) + } } func saveLog(resource *dockertest.Resource, basePath string) error {