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  }