github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/systests/retry_test.go (about)

     1  package systests
     2  
     3  import (
     4  	"github.com/keybase/client/go/libkb"
     5  	"sync"
     6  	"testing"
     7  )
     8  
     9  type testRunFunc func(t libkb.TestingTB)
    10  
    11  type testAttempt struct {
    12  	sync.Mutex
    13  	t      *testing.T
    14  	failed bool
    15  }
    16  
    17  func (t *testAttempt) Error(args ...interface{}) {
    18  	t.Log(args...)
    19  }
    20  
    21  func (t *testAttempt) Errorf(format string, args ...interface{}) {
    22  	t.Logf(format, args...)
    23  }
    24  
    25  func (t *testAttempt) Fail() {
    26  	t.Lock()
    27  	t.failed = true
    28  	t.Unlock()
    29  }
    30  
    31  func (t *testAttempt) FailNow() {
    32  	t.Lock()
    33  	t.failed = true
    34  	t.Unlock()
    35  	panic("FailNow call")
    36  }
    37  
    38  func (t *testAttempt) Failed() bool {
    39  	t.Lock()
    40  	defer t.Unlock()
    41  	return t.failed
    42  }
    43  
    44  func (t *testAttempt) Fatal(args ...interface{}) {
    45  	t.Log(args...)
    46  	t.Lock()
    47  	t.failed = true
    48  	t.Unlock()
    49  	panic("Fatal call")
    50  }
    51  
    52  func (t *testAttempt) Fatalf(format string, args ...interface{}) {
    53  	t.Logf(format, args...)
    54  	t.Lock()
    55  	t.failed = true
    56  	t.Unlock()
    57  	panic("Fatalf call")
    58  }
    59  
    60  func (t *testAttempt) Log(args ...interface{}) {
    61  	t.t.Log(args...)
    62  }
    63  
    64  func (t *testAttempt) Logf(format string, args ...interface{}) {
    65  	t.t.Logf(format, args...)
    66  }
    67  
    68  func (t *testAttempt) Name() string {
    69  	return t.t.Name()
    70  }
    71  
    72  func (t *testAttempt) Skip(args ...interface{}) {
    73  	t.t.Skip(args...)
    74  }
    75  
    76  func (t *testAttempt) SkipNow() {
    77  	t.t.SkipNow()
    78  }
    79  func (t *testAttempt) Skipf(format string, args ...interface{}) {
    80  	t.t.Skipf(format, args...)
    81  }
    82  func (t *testAttempt) Skipped() bool {
    83  	return t.t.Skipped()
    84  }
    85  
    86  func (t *testAttempt) Helper() {
    87  	t.t.Helper()
    88  }
    89  
    90  // retryFlakeyTestOnlyUseIfPermitted is not ideal, so please do no use it
    91  // unless you ask max first. Right now, it's only being used for TestRekey,
    92  // which has a flake in it but hopefully is going to be phased out, so not
    93  // really worth fixing the flake.
    94  func retryFlakeyTestOnlyUseIfPermitted(t *testing.T, numTries int, test testRunFunc) {
    95  
    96  	for i := 0; i < numTries-1; i++ {
    97  		attempt := testAttempt{t: t}
    98  		if attempt.run(test) {
    99  			return
   100  		}
   101  	}
   102  	// The last time, run with the standard test failure system.
   103  	test(t)
   104  }
   105  
   106  func (t *testAttempt) run(testRun testRunFunc) (ret bool) {
   107  	ret = true
   108  	defer func() {
   109  		if r := recover(); r != nil {
   110  			t.t.Logf("Recovered from fatal test failure: %s", r)
   111  			ret = false
   112  		}
   113  	}()
   114  	testRun(t)
   115  	ret = !t.failed
   116  	return ret
   117  }