github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/creds/vault/reauther_test.go (about) 1 package vault 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "code.cloudfoundry.org/lager/lagertest" 9 10 "github.com/cenkalti/backoff" 11 ) 12 13 type MockAuther struct { 14 LoginAttempt chan bool 15 Renewed chan bool 16 Delay time.Duration 17 LoginError error 18 RenewError error 19 } 20 21 func (ma *MockAuther) Login() (time.Duration, error) { 22 loggedIn := true 23 if ma.LoginError != nil { 24 loggedIn = false 25 } 26 27 ma.LoginAttempt <- loggedIn 28 return ma.Delay, ma.LoginError 29 } 30 func (ma *MockAuther) Renew() (time.Duration, error) { 31 renewed := true 32 if ma.RenewError != nil { 33 renewed = false 34 } 35 36 ma.Renewed <- renewed 37 return ma.Delay, ma.RenewError 38 } 39 40 func TestReAuther(t *testing.T) { 41 testWithoutVaultErrors(t) 42 testExponentialBackoff(t) 43 } 44 45 func testWithoutVaultErrors(t *testing.T) { 46 ma := &MockAuther{ 47 LoginAttempt: make(chan bool, 1), 48 Renewed: make(chan bool, 1), 49 Delay: 1 * time.Second, 50 } 51 logger := lagertest.NewTestLogger("vault-test") 52 ra := NewReAuther(logger, ma, 10*time.Second, 1*time.Second, 64*time.Second) 53 select { 54 case <-ra.LoggedIn(): 55 case <-time.After(1 * time.Second): 56 t.Fatal("Didn't issue login within timeout") 57 } 58 59 select { 60 case li := <-ma.LoginAttempt: 61 if !li { 62 t.Error("Error, should have logged in after loggedin closed") 63 } 64 case <-time.After(1 * time.Second): 65 t.Fatal("Didn't issue login within timeout") 66 } 67 68 select { 69 case <-ma.LoginAttempt: 70 t.Error("Should not have logged in again") 71 case r := <-ma.Renewed: 72 if !r { 73 t.Error("Error, should have renewed in before the delay") 74 } 75 case <-time.After(2 * time.Second): 76 t.Fatal("Didn't issue login within timeout") 77 } 78 79 select { 80 case <-ma.LoginAttempt: 81 t.Error("Should not have logged in again") 82 case r := <-ma.Renewed: 83 if !r { 84 t.Error("Error, should have renewed again in before the delay") 85 } 86 case <-time.After(2 * time.Second): 87 t.Fatal("Didn't issue login within timeout") 88 } 89 90 select { 91 case <-ma.LoginAttempt: 92 case r := <-ma.Renewed: 93 if !r { 94 t.Error("Error, should have logged in again after the maxTTL") 95 } 96 case <-time.After(10 * time.Second): 97 t.Fatal("Didn't issue login within timeout") 98 } 99 100 } 101 102 func testExponentialBackoff(t *testing.T) { 103 maxRetryInterval := 2 * time.Second 104 105 ma := &MockAuther{ 106 LoginAttempt: make(chan bool, 1), 107 Renewed: make(chan bool, 1), 108 Delay: 1 * time.Second, 109 LoginError: fmt.Errorf("Could not login to Vault"), 110 } 111 logger := lagertest.NewTestLogger("vault-test") 112 ra := NewReAuther(logger, ma, 0, 1*time.Second, maxRetryInterval) 113 114 select { 115 case <-ra.LoggedIn(): 116 t.Error("error, shouldn't have logged in") 117 case <-time.After(1 * time.Second): 118 } 119 120 // Make enough login attempts to reach maxRetryInterval 121 var lastRetryInterval time.Duration 122 for i := 0; i < 4; i++ { 123 start := time.Now() 124 select { 125 case li := <-ma.LoginAttempt: 126 lastRetryInterval = time.Since(start) 127 if li { 128 t.Error("error, shouldn't have logged in succesfully") 129 } 130 case <-time.After(maxRetryInterval * 2): 131 t.Fatal("Took too long to retry login") 132 } 133 } 134 135 // default randomization factor is 0.5 136 smallestMaxRandomizedInterval := float64(maxRetryInterval) * (1 - backoff.DefaultRandomizationFactor) 137 138 if float64(lastRetryInterval) < smallestMaxRandomizedInterval { 139 t.Error("maxRetryInterval reached, but login was reattempted before maxRetryInterval") 140 } 141 }