github.com/sacloud/iaas-api-go@v1.12.0/helper/query/wait_test.go (about) 1 // Copyright 2016-2022 The sacloud/iaas-api-go Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package query 16 17 import ( 18 "context" 19 "errors" 20 "sync" 21 "testing" 22 "time" 23 24 "github.com/stretchr/testify/require" 25 ) 26 27 type testChecker struct { 28 _called int 29 f func(called int) (bool, error) 30 mu sync.Mutex 31 } 32 33 func (c *testChecker) isExists() (bool, error) { 34 c.mu.Lock() 35 defer c.mu.Unlock() 36 37 c._called++ 38 return c.f(c._called) 39 } 40 41 func (c *testChecker) called() int { 42 c.mu.Lock() 43 defer c.mu.Unlock() 44 return c._called 45 } 46 47 func TestWaitWhileReferenced_called(t *testing.T) { 48 checker := &testChecker{ 49 f: func(called int) (bool, error) { 50 if called == 2 { 51 return false, nil 52 } 53 return true, nil 54 }, 55 } 56 err := waitWhileReferenced(context.Background(), CheckReferencedOption{Tick: time.Millisecond, Timeout: time.Second}, checker.isExists) 57 if err != nil { 58 t.Error(err) 59 } 60 61 require.Equal(t, 2, checker.called()) 62 } 63 64 func TestWaitWhileReferenced_contextCanceled(t *testing.T) { 65 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) 66 defer cancel() 67 68 checker := &testChecker{ 69 f: func(c int) (bool, error) { 70 return true, nil 71 }, 72 } 73 74 err := waitWhileReferenced(ctx, CheckReferencedOption{Tick: time.Millisecond, Timeout: time.Second}, checker.isExists) 75 if err.Error() != "context deadline exceeded" { 76 t.Errorf("unexpected error: expected: %s, actual: %s", "context deadline exceeded", err) 77 } 78 79 if checker.called() < 2 { 80 t.Error("check func was not called when retry") 81 } 82 } 83 84 func TestWaitWhileReferenced_checkFuncReturnsError(t *testing.T) { 85 checker := &testChecker{ 86 f: func(called int) (bool, error) { 87 if called == 2 { 88 return false, errors.New("dummy") 89 } 90 return true, nil 91 }, 92 } 93 94 err := waitWhileReferenced(context.Background(), CheckReferencedOption{Tick: time.Millisecond, Timeout: time.Second}, checker.isExists) 95 require.Equal(t, errors.New("dummy"), err) 96 require.Equal(t, 2, checker.called()) 97 } 98 99 func TestWaitWhileReferenced_optionTimeout(t *testing.T) { 100 checker := &testChecker{ 101 f: func(called int) (bool, error) { 102 return true, nil 103 }, 104 } 105 106 err := waitWhileReferenced(context.Background(), CheckReferencedOption{Tick: time.Millisecond, Timeout: 10 * time.Millisecond}, checker.isExists) 107 if err.Error() != "context deadline exceeded" { 108 t.Errorf("unexpected error: expected: %s, actual: %s", "context deadline exceeded", err) 109 } 110 111 if checker.called() < 2 { 112 t.Error("check func was not called when retry") 113 } 114 }