flakytest.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Package flakytest contains test helpers for marking a test as flaky. For
  4. // tests run using cmd/testwrapper, a failed flaky test will cause tests to be
  5. // re-run a few time until they succeed or exceed our iteration limit.
  6. package flakytest
  7. import (
  8. "fmt"
  9. "os"
  10. "regexp"
  11. "testing"
  12. )
  13. // FlakyTestLogMessage is a sentinel value that is printed to stderr when a
  14. // flaky test is marked. This is used by cmd/testwrapper to detect flaky tests
  15. // and retry them.
  16. const FlakyTestLogMessage = "flakytest: this is a known flaky test"
  17. // FlakeAttemptEnv is an environment variable that is set by cmd/testwrapper
  18. // when a flaky test is being (re)tried. It contains the attempt number,
  19. // starting at 1.
  20. const FlakeAttemptEnv = "TS_TESTWRAPPER_ATTEMPT"
  21. var issueRegexp = regexp.MustCompile(`\Ahttps://github\.com/tailscale/[a-zA-Z0-9_.-]+/issues/\d+\z`)
  22. // Mark sets the current test as a flaky test, such that if it fails, it will
  23. // be retried a few times on failure. issue must be a GitHub issue that tracks
  24. // the status of the flaky test being marked, of the format:
  25. //
  26. // https://github.com/tailscale/myRepo-H3re/issues/12345
  27. func Mark(t testing.TB, issue string) {
  28. if !issueRegexp.MatchString(issue) {
  29. t.Fatalf("bad issue format: %q", issue)
  30. }
  31. if _, ok := os.LookupEnv(FlakeAttemptEnv); ok {
  32. // We're being run under cmd/testwrapper so send our sentinel message
  33. // to stderr. (We avoid doing this when the env is absent to avoid
  34. // spamming people running tests without the wrapper)
  35. fmt.Fprintf(os.Stderr, "%s: %s\n", FlakyTestLogMessage, issue)
  36. }
  37. t.Logf("flakytest: issue tracking this flaky test: %s", issue)
  38. }