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  }