github.com/grahambrereton-form3/tilt@v0.10.18/internal/engine/version_checker_test.go (about) 1 package engine 2 3 import ( 4 "context" 5 "strings" 6 "testing" 7 "time" 8 9 "github.com/pkg/errors" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 13 "github.com/windmilleng/tilt/internal/engine/runtimelog" 14 "github.com/windmilleng/tilt/internal/github" 15 "github.com/windmilleng/tilt/internal/store" 16 "github.com/windmilleng/tilt/internal/testutils/bufsync" 17 "github.com/windmilleng/tilt/pkg/logger" 18 "github.com/windmilleng/tilt/pkg/model" 19 ) 20 21 func TestSleepAfterFailure(t *testing.T) { 22 f := newVersionCheckerFixture(t) 23 24 errorMsg := "github error!" 25 26 f.delay = infiniteDelay 27 f.ghc.LatestReleaseErr = errors.New(errorMsg) 28 29 f.vc.OnChange(f.ctx, f.store) 30 31 f.waitUntil(t, func(f *versionCheckerFixture) bool { 32 return strings.Contains(f.out.String(), errorMsg) 33 }) 34 35 // Hackily hope a sleep triggers the bug we want to test (immediate retry on error, leading to infinite 36 // retries). This at least currently repro'd the bug 100/100 times. Unclear if there's a less hacky option. 37 time.Sleep(5 * time.Millisecond) 38 39 f.cancel() 40 41 assert.Equal(t, 1, strings.Count(f.out.String(), errorMsg)) 42 } 43 44 func TestVersionCheckDisabledForDev(t *testing.T) { 45 f := newVersionCheckerFixture(t) 46 47 state := f.store.LockMutableStateForTesting() 48 state.TiltBuildInfo = model.TiltBuild{Dev: true} 49 f.store.UnlockMutableState() 50 51 f.vc.OnChange(f.ctx, f.store) 52 53 require.False(t, f.vc.started) 54 } 55 56 type versionCheckerFixture struct { 57 ctx context.Context 58 store *store.Store 59 vc *TiltVersionChecker 60 cancel context.CancelFunc 61 delay time.Duration 62 ghc *github.FakeClient 63 out *bufsync.ThreadSafeBuffer 64 } 65 66 const infiniteDelay = -1 67 68 func newVersionCheckerFixture(t *testing.T) *versionCheckerFixture { 69 out := bufsync.NewThreadSafeBuffer() 70 reducer := func(ctx context.Context, state *store.EngineState, action store.Action) { 71 podLog, ok := action.(runtimelog.PodLogAction) 72 if !ok { 73 t.Errorf("Expected action type PodLogAction. Actual: %T", action) 74 } 75 out.Write(podLog.LogEvent.Message()) 76 } 77 78 st := store.NewStore(store.Reducer(reducer), store.LogActionsFlag(false)) 79 80 ctx, cancel := context.WithCancel(context.Background()) 81 l := logger.NewLogger(logger.DebugLvl, out) 82 ctx = logger.WithLogger(ctx, l) 83 go st.Loop(ctx) 84 85 ret := &versionCheckerFixture{ 86 ctx: ctx, 87 store: st, 88 cancel: cancel, 89 out: out, 90 } 91 92 tiltVersionCheckTimerMaker := func(d time.Duration) <-chan time.Time { 93 if ret.delay == infiniteDelay { 94 return nil 95 } else { 96 return time.After(ret.delay) 97 } 98 99 } 100 ghc := &github.FakeClient{} 101 vc := NewTiltVersionChecker(func() github.Client { return ghc }, tiltVersionCheckTimerMaker) 102 103 ret.vc = vc 104 ret.ghc = ghc 105 return ret 106 } 107 108 func (vcf *versionCheckerFixture) waitUntil(t *testing.T, pred func(vcf *versionCheckerFixture) bool) { 109 start := time.Now() 110 for time.Since(start) < time.Second { 111 if pred(vcf) { 112 return 113 } 114 } 115 t.Fatal("timed out waiting for predicate to be true") 116 }