github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/store/store_test.go (about)

     1  package store
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/tilt-dev/tilt/pkg/logger"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestProcessActions(t *testing.T) {
    13  	f := newFixture(t)
    14  	f.Start()
    15  
    16  	f.store.Dispatch(CompletedBuildAction{})
    17  	f.store.Dispatch(CompletedBuildAction{})
    18  	f.store.Dispatch(DoneAction{})
    19  
    20  	f.WaitUntilDone()
    21  
    22  	assert.Equal(t, 2, f.store.state.CompletedBuildCount)
    23  }
    24  
    25  func TestBroadcastActions(t *testing.T) {
    26  	f := newFixture(t)
    27  
    28  	s := newFakeSubscriber()
    29  	_ = f.store.AddSubscriber(f.ctx, s)
    30  
    31  	f.Start()
    32  
    33  	f.store.Dispatch(CompletedBuildAction{})
    34  
    35  	s.assertOnChangeCount(t, 1)
    36  
    37  	f.store.Dispatch(DoneAction{})
    38  	f.WaitUntilDone()
    39  }
    40  
    41  func TestLogOnly(t *testing.T) {
    42  	f := newFixture(t)
    43  
    44  	s := newFakeSubscriber()
    45  	_ = f.store.AddSubscriber(f.ctx, s)
    46  
    47  	f.Start()
    48  
    49  	f.store.Dispatch(CompletedBuildAction{})
    50  	call := <-s.onChange
    51  	assert.False(t, call.summary.IsLogOnly())
    52  	assert.True(t, call.summary.Legacy)
    53  	close(call.done)
    54  
    55  	f.store.Dispatch(LogAction{})
    56  	call = <-s.onChange
    57  	assert.True(t, call.summary.IsLogOnly())
    58  	close(call.done)
    59  
    60  	f.store.Dispatch(DoneAction{})
    61  	f.WaitUntilDone()
    62  }
    63  
    64  func TestBroadcastActionsBatching(t *testing.T) {
    65  	f := newFixture(t)
    66  
    67  	s := newFakeSubscriber()
    68  	_ = f.store.AddSubscriber(f.ctx, s)
    69  
    70  	f.Start()
    71  
    72  	f.store.mu.Lock()
    73  	f.store.Dispatch(CompletedBuildAction{})
    74  	f.store.Dispatch(CompletedBuildAction{})
    75  	f.store.mu.Unlock()
    76  
    77  	s.assertOnChangeCount(t, 1)
    78  
    79  	f.store.Dispatch(DoneAction{})
    80  	f.WaitUntilDone()
    81  }
    82  
    83  // if the logstore checkpoint changes, the summary should say there's a log change
    84  // even if the action summarizer doesn't
    85  func TestInferredSummaryLog(t *testing.T) {
    86  	f := newFixture(t)
    87  
    88  	s := newFakeSubscriber()
    89  	_ = f.store.AddSubscriber(f.ctx, s)
    90  
    91  	f.Start()
    92  
    93  	f.store.Dispatch(CompletedBuildAction{})
    94  	call := <-s.onChange
    95  	assert.False(t, call.summary.IsLogOnly())
    96  	assert.True(t, call.summary.Legacy)
    97  	close(call.done)
    98  
    99  	f.store.Dispatch(SneakyLoggingAction{})
   100  	call = <-s.onChange
   101  	assert.True(t, call.summary.Log)
   102  	assert.True(t, call.summary.Legacy)
   103  	close(call.done)
   104  
   105  	f.store.Dispatch(DoneAction{})
   106  	f.WaitUntilDone()
   107  }
   108  
   109  type fixture struct {
   110  	t      *testing.T
   111  	store  *Store
   112  	ctx    context.Context
   113  	cancel func()
   114  	done   chan error
   115  }
   116  
   117  func newFixture(t *testing.T) fixture {
   118  	ctx, cancel := context.WithCancel(context.Background())
   119  	st := NewStore(TestReducer, LogActionsFlag(false))
   120  	return fixture{
   121  		t:      t,
   122  		store:  st,
   123  		ctx:    ctx,
   124  		cancel: cancel,
   125  		done:   make(chan error),
   126  	}
   127  }
   128  
   129  func (f fixture) Start() {
   130  	go func() {
   131  		err := f.store.Loop(f.ctx)
   132  		f.done <- err
   133  	}()
   134  }
   135  
   136  func (f fixture) WaitUntilDone() {
   137  	err := <-f.done
   138  	if err != nil && err != context.Canceled {
   139  		f.t.Fatalf("Loop failed unexpectedly: %v", err)
   140  	}
   141  }
   142  
   143  func (f fixture) TearDown() {
   144  	f.cancel()
   145  	f.WaitUntilDone()
   146  }
   147  
   148  type CompletedBuildAction struct {
   149  }
   150  
   151  func (CompletedBuildAction) Action() {}
   152  
   153  // An action that writes to the log but doesn't report it via
   154  // Summarize (or even implement Summarizer!)
   155  type SneakyLoggingAction struct {
   156  }
   157  
   158  func (SneakyLoggingAction) Action() {}
   159  
   160  type DoneAction struct {
   161  }
   162  
   163  func (DoneAction) Action() {}
   164  
   165  var TestReducer = Reducer(func(ctx context.Context, s *EngineState, action Action) {
   166  	switch action.(type) {
   167  	case CompletedBuildAction:
   168  		s.CompletedBuildCount++
   169  	case SneakyLoggingAction:
   170  		s.LogStore.Append(NewLogAction("foo", "foo", logger.ErrorLvl, nil, []byte("hi")), s.Secrets)
   171  	case DoneAction:
   172  		s.FatalError = context.Canceled
   173  	}
   174  })