github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/btpmanager/credentials/utils_test.go (about) 1 package btpmgrcreds 2 3 import ( 4 "fmt" 5 "sync" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/assert" 10 ) 11 12 type foo struct { 13 x, y int 14 } 15 16 type fakeService struct { 17 reachable bool 18 ticks int 19 } 20 21 func (fs *fakeService) fakeCall1() (int, error) { 22 return 91, nil 23 } 24 25 func (fs *fakeService) fakeCall2() (foo, error) { 26 foo := foo{ 27 x: 1, 28 y: 4, 29 } 30 return foo, nil 31 } 32 33 func (fs *fakeService) fakeCall3() (any, error) { 34 return nil, fmt.Errorf("expected error") 35 } 36 37 func (fs *fakeService) fakeCall4() (any, error) { 38 return nil, nil 39 } 40 41 func (fs *fakeService) fakeCall5() (foo, error) { 42 if fs.reachable { 43 return foo{x: -1, y: -1999}, nil 44 } else { 45 return foo{}, fmt.Errorf("expected error") 46 } 47 } 48 49 func TestCallWithRetry(t *testing.T) { 50 t.Run("call without any problems 1", func(t *testing.T) { 51 fakeService := &fakeService{} 52 result, err := CallWithRetry(func() (int, error) { 53 return fakeService.fakeCall1() 54 }, 1, time.Second*1) 55 assert.NoError(t, err) 56 assert.Equal(t, 91, result) 57 }) 58 59 t.Run("call without any problems 2", func(t *testing.T) { 60 fakeService := &fakeService{} 61 result, err := CallWithRetry(func() (foo, error) { 62 return fakeService.fakeCall2() 63 }, 1, time.Second*1) 64 assert.NoError(t, err) 65 assert.Equal(t, foo{ 66 x: 1, 67 y: 4, 68 }, result) 69 }) 70 71 t.Run("call with error 1", func(t *testing.T) { 72 fakeService := &fakeService{} 73 result, err := CallWithRetry(func() (any, error) { 74 return fakeService.fakeCall3() 75 }, 1, time.Second*1) 76 assert.Error(t, err) 77 assert.Nil(t, result) 78 }) 79 80 t.Run("call with error 2", func(t *testing.T) { 81 fakeService := &fakeService{} 82 result, err := CallWithRetry(func() (any, error) { 83 return fakeService.fakeCall3() 84 }, 1, time.Second*1) 85 assert.Error(t, err) 86 assert.Nil(t, result) 87 }) 88 89 t.Run("call with no error and no response", func(t *testing.T) { 90 fakeService := &fakeService{} 91 result, err := CallWithRetry(func() (any, error) { 92 return fakeService.fakeCall4() 93 }, 1, time.Second*1) 94 assert.NoError(t, err) 95 assert.Nil(t, result) 96 }) 97 98 t.Run("service become reachable after some time", func(t *testing.T) { 99 //Service will be not reachable for 10s. 100 //The retry will try to connect 5 times * 5 seconds = 25 seconds. 25 > 10 so Result should be returned without error 101 fakeService := &fakeService{ticks: 10} 102 var wg sync.WaitGroup 103 wg.Add(1) 104 go func() { 105 defer wg.Done() 106 for range time.Tick(time.Second * 1) { 107 fakeService.ticks-- 108 if fakeService.ticks <= 0 { 109 fakeService.reachable = true 110 return 111 } 112 } 113 }() 114 result, err := CallWithRetry(func() (foo, error) { 115 return fakeService.fakeCall5() 116 }, 5, time.Second*5) 117 assert.NoError(t, err) 118 assert.NotNil(t, result) 119 assert.NotEmpty(t, result) 120 assert.Equal(t, result, foo{x: -1, y: -1999}) 121 wg.Wait() 122 }) 123 124 t.Run("service is not reachable for all time", func(t *testing.T) { 125 //Service will be not reachable for 10s. 126 //The retry will try to connect 2 times * 2 seconds = 4 seconds. 4 < 10 so Result should be returned with error 127 fakeService := &fakeService{ticks: 10} 128 var wg sync.WaitGroup 129 wg.Add(1) 130 go func() { 131 defer wg.Done() 132 for range time.Tick(time.Second * 1) { 133 fakeService.ticks-- 134 if fakeService.ticks <= 0 { 135 fakeService.reachable = true 136 return 137 } 138 } 139 }() 140 result, err := CallWithRetry(func() (foo, error) { 141 return fakeService.fakeCall5() 142 }, 2, time.Second*2) 143 assert.Error(t, err) 144 assert.Empty(t, result) 145 wg.Wait() 146 }) 147 }