github.com/web-platform-tests/wpt.fyi@v0.0.0-20240530210107-70cf978996f1/api/query/cache/backfill/backfill_medium_test.go (about)

     1  //go:build medium
     2  // +build medium
     3  
     4  // Copyright 2018 The WPT Dashboard Project. All rights reserved.
     5  // Use of this source code is governed by a BSD-style license that can be
     6  // found in the LICENSE file.
     7  
     8  package backfill
     9  
    10  import (
    11  	"errors"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/golang/mock/gomock"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/web-platform-tests/wpt.fyi/api/query"
    18  	"github.com/web-platform-tests/wpt.fyi/api/query/cache/index"
    19  	"github.com/web-platform-tests/wpt.fyi/api/query/cache/monitor"
    20  	"github.com/web-platform-tests/wpt.fyi/shared"
    21  	"github.com/web-platform-tests/wpt.fyi/shared/sharedtest"
    22  )
    23  
    24  type countingIndex struct {
    25  	index.ProxyIndex
    26  
    27  	count int
    28  }
    29  
    30  var errNotImplemented = errors.New("Not implemented")
    31  
    32  func (i *countingIndex) IngestRun(r shared.TestRun) error {
    33  	err := i.ProxyIndex.IngestRun(r)
    34  	if err != nil {
    35  		return err
    36  	}
    37  
    38  	i.count++
    39  	return nil
    40  }
    41  
    42  func (i *countingIndex) EvictRuns(percent float64) (int, error) {
    43  	n, err := i.ProxyIndex.EvictRuns(percent)
    44  	if err != nil {
    45  		return n, err
    46  	}
    47  
    48  	i.count -= n
    49  	return n, nil
    50  }
    51  
    52  func (*countingIndex) Bind([]shared.TestRun, query.ConcreteQuery) (query.Plan, error) {
    53  	return nil, errNotImplemented
    54  }
    55  
    56  func TestStopImmediately(t *testing.T) {
    57  	ctrl := gomock.NewController(t)
    58  	defer ctrl.Finish()
    59  	store := sharedtest.NewMockDatastore(ctrl)
    60  	query := sharedtest.NewMockTestRunQuery(ctrl)
    61  	product, _ := shared.ParseProductSpec("chrome")
    62  	store.EXPECT().TestRunQuery().Return(query)
    63  	query.EXPECT().LoadTestRuns(gomock.Any(), nil, nil, nil, nil, gomock.Any(), nil).Return(shared.TestRunsByProduct{
    64  		shared.ProductTestRuns{Product: product, TestRuns: shared.TestRuns{
    65  			shared.TestRun{ID: 1},
    66  			shared.TestRun{ID: 2},
    67  			shared.TestRun{ID: 3},
    68  			shared.TestRun{ID: 4},
    69  		}},
    70  	}, nil)
    71  	rt := monitor.NewMockRuntime(ctrl)
    72  	rt.EXPECT().GetHeapBytes().Return(uint64(0)).AnyTimes()
    73  	mockIdx := index.NewMockIndex(ctrl)
    74  	mockIdx.EXPECT().IngestRun(gomock.Any()).Return(nil).AnyTimes()
    75  	mockIdx.EXPECT().SetIngestChan(gomock.Any())
    76  	idx := countingIndex{index.NewProxyIndex(mockIdx), 0}
    77  	m, err := FillIndex(store, shared.NewNilLogger(), rt, time.Millisecond*10, 10, 1, 0.0, &idx)
    78  	assert.Nil(t, err)
    79  	m.Stop()
    80  	time.Sleep(time.Second)
    81  	assert.True(t, idx.count == 0 || idx.count == 1)
    82  }
    83  
    84  func TestIngestSomeRuns(t *testing.T) {
    85  	ctrl := gomock.NewController(t)
    86  	defer ctrl.Finish()
    87  
    88  	store := sharedtest.NewMockDatastore(ctrl)
    89  	query := sharedtest.NewMockTestRunQuery(ctrl)
    90  	product, _ := shared.ParseProductSpec("chrome")
    91  	store.EXPECT().TestRunQuery().Return(query)
    92  	query.EXPECT().LoadTestRuns(gomock.Any(), nil, nil, nil, nil, gomock.Any(), nil).Return(shared.TestRunsByProduct{
    93  		shared.ProductTestRuns{
    94  			Product: product,
    95  			TestRuns: shared.TestRuns{
    96  				shared.TestRun{ID: 1},
    97  				shared.TestRun{ID: 2},
    98  				shared.TestRun{ID: 3},
    99  				shared.TestRun{ID: 4},
   100  			},
   101  		},
   102  	}, nil)
   103  
   104  	freq := time.Millisecond * 10
   105  	maxIngestedRuns := uint(10)
   106  	maxBytes := uint64(1)
   107  	rt := monitor.NewMockRuntime(ctrl)
   108  
   109  	mockIdx := index.NewMockIndex(ctrl)
   110  	idx := countingIndex{index.NewProxyIndex(mockIdx), 0}
   111  
   112  	rt.EXPECT().GetHeapBytes().DoAndReturn(func() uint64 {
   113  		// Trigger monitor when 3 or more runs are loaded.
   114  		if idx.count >= 3 {
   115  			return maxBytes + 1
   116  		} else {
   117  			return uint64(0)
   118  		}
   119  	}).AnyTimes()
   120  
   121  	mockIdx.EXPECT().IngestRun(gomock.Any()).DoAndReturn(func(shared.TestRun) error {
   122  		// Wait 2x monitor frequency to allow monitor to halt ingesting runs,
   123  		// if necessary.
   124  		time.Sleep(freq * 2)
   125  		return nil
   126  	}).AnyTimes()
   127  
   128  	mockIdx.EXPECT().EvictRuns(gomock.Any()).Return(1, nil).AnyTimes()
   129  
   130  	mockIdx.EXPECT().SetIngestChan(gomock.Any())
   131  	m, err := FillIndex(store, shared.NewNilLogger(), rt, freq, maxIngestedRuns, maxBytes, 0.0, &idx)
   132  	assert.Nil(t, err)
   133  	defer m.Stop()
   134  
   135  	// Wait for runs to be ingested.
   136  	time.Sleep(time.Second)
   137  	assert.Equal(t, 2, idx.count)
   138  }