blob: be79e2361227924971285c5d9ae0b46aba6e1456 [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package internal
import (
"sync"
"testing"
"time"
"google.golang.org/cloud/bigtable"
"v.io/x/ref/test/timekeeper"
)
func TestRowCache(t *testing.T) {
clock := timekeeper.NewManualTime()
clock.AdvanceTime(2 * cacheTimeout)
SetClock(clock)
rowCache := &rowCache{}
testcases := []struct {
key string
returnedVersion string
expectedVersion string
expectedCalls int
skip time.Duration
}{
// Time 0
{"one", "100", "100", 1, 0},
{"two", "200", "200", 1, cacheTimeout/2 + 1},
// Time 0.5 sec
{"one", "XXX", "100", 0, 0},
{"two", "XXX", "200", 0, cacheTimeout/2 + 1},
// Time 1 sec
{"one", "101", "101", 1, 0},
{"two", "201", "201", 1, cacheTimeout/2 + 1},
// Time 1.5 sec
{"one", "XXX", "101", 0, 0},
{"two", "XXX", "201", 0, cacheTimeout/2 + 1},
// Time 2 sec
{"one", "102", "102", 1, 0},
{"two", "202", "202", 1, cacheTimeout/2 + 1},
}
for i, tc := range testcases {
calls := 0
getRow := func() (bigtable.Row, error) {
calls++
row := bigtable.Row{
metadataFamily: []bigtable.ReadItem{
{
Row: tc.key,
Column: versionColumn,
Value: []byte(tc.returnedVersion),
},
},
}
return row, nil
}
const N = 5
var wg sync.WaitGroup
wg.Add(N)
for x := 0; x < N; x++ {
go func() {
defer wg.Done()
row, err := rowCache.getRefresh(tc.key, getRow)
if err != nil {
t.Errorf("Unexpected error for #%d: %v", i, err)
return
}
if got := row.Key(); got != tc.key {
t.Errorf("Unexpected key for #%d. Got %q, expected %q", i, got, tc.key)
}
meta := row[metadataFamily]
if meta == nil {
t.Errorf("Missing metadata family for #%d", i)
return
}
if len(meta) != 1 {
t.Errorf("Unexpected number of cells for #%d: %v", i, meta)
return
}
if got := string(meta[0].Value); got != tc.expectedVersion {
t.Errorf("Unexpected version for #%d. Got %q, expected %q", i, got, tc.expectedVersion)
}
}()
}
wg.Wait()
if got := calls; got != tc.expectedCalls {
t.Errorf("Unexpected function call count for #%d. Got %d, expected %d", i, got, tc.expectedCalls)
}
clock.AdvanceTime(tc.skip)
}
}