assertCommandOutputContains executes a command with exponential backoff retry until the output contains the expected string or timeout is reached (10 seconds). This implements eventual consistency patterns and should be used instead of [time.Sleep] before executing commands that depend on network st
(t *testing.T, c TailscaleClient, command []string, contains string)
| 902 | // Timeout: 10 seconds with exponential backoff |
| 903 | // Use cases: DNS resolution, route propagation, policy updates. |
| 904 | func assertCommandOutputContains(t *testing.T, c TailscaleClient, command []string, contains string) { |
| 905 | t.Helper() |
| 906 | |
| 907 | _, err := backoff.Retry(t.Context(), func() (struct{}, error) { |
| 908 | stdout, stderr, err := c.Execute(command) |
| 909 | if err != nil { |
| 910 | return struct{}{}, fmt.Errorf("executing command, stdout: %q stderr: %q, err: %w", stdout, stderr, err) |
| 911 | } |
| 912 | |
| 913 | if !strings.Contains(stdout, contains) { |
| 914 | return struct{}{}, fmt.Errorf("executing command, expected string %q not found in %q", contains, stdout) //nolint:err113 |
| 915 | } |
| 916 | |
| 917 | return struct{}{}, nil |
| 918 | }, backoff.WithBackOff(backoff.NewExponentialBackOff()), backoff.WithMaxElapsedTime(10*time.Second)) |
| 919 | |
| 920 | assert.NoError(t, err) |
| 921 | } |
| 922 | |
| 923 | // dockertestMaxWait returns the maximum wait time for Docker-based test operations. |
| 924 | // Uses longer timeouts in CI environments to account for slower resource allocation |