This commit is contained in:
Julie Tibshirani 2024-08-14 15:24:28 -04:00 committed by GitHub
commit 2f96496c8b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 233 additions and 197 deletions

View File

@ -110,5 +110,5 @@ func NewDiagnosticsHandler(baseLogger log.Logger, next http.Handler, redisCache
}
func healthz(ctx context.Context, cache redispool.KeyValue) error {
return cache.WithContext(ctx).Ping()
return cache.Ping(ctx)
}

View File

@ -51,7 +51,7 @@ func (r *RepositoryResolver) RecordedCommands(ctx context.Context, args *Recorde
return gqlutil.NewSliceConnectionResolver([]RecordedCommandResolver{}, 0, currentEnd), nil
}
store := rcache.NewFIFOList(redispool.Cache, wrexec.GetFIFOListKey(r.Name()), recordingConf.Size)
empty, err := store.IsEmpty()
empty, err := store.IsEmpty(ctx)
if err != nil {
return nil, err
}
@ -67,7 +67,7 @@ func (r *RepositoryResolver) RecordedCommands(ctx context.Context, args *Recorde
return nil, err
}
size, err := store.Size()
size, err := store.Size(ctx)
if err != nil {
return nil, err
}

View File

@ -111,7 +111,7 @@ func (r *slowRequestConnectionResolver) fetch(ctx context.Context) ([]*types.Slo
r.err = err
}
r.reqs, r.err = getSlowRequestsAfter(ctx, slowRequestRedisFIFOList, n, r.perPage)
size, err := slowRequestRedisFIFOList.Size()
size, err := slowRequestRedisFIFOList.Size(ctx)
if err != nil {
r.err = errors.Append(r.err, err)
} else {

View File

@ -460,7 +460,7 @@ func waitForRedis(logger sglog.Logger, kv redispool.KeyValue) {
var err error
for {
time.Sleep(150 * time.Millisecond)
err = kv.Ping()
err = kv.Ping(context.Background())
if err == nil {
return
}

View File

@ -173,7 +173,8 @@ func (m *Recorder) saveRun(jobName string, routineName string, hostName string,
}
// Save run
err = getRecentRuns(m.rcache, jobName, routineName, hostName).Insert(runJson)
// TODO(multi-tenant): Remove context.Background()
err = getRecentRuns(m.rcache, jobName, routineName, hostName).Insert(context.Background(), runJson)
if err != nil {
return errors.Wrap(err, "save run")
}

View File

@ -118,7 +118,7 @@ func redisLoggerMiddleware() Middleware {
go func() {
// Save new item
if err := outboundRequestsRedisFIFOList.Insert(logItemJson); err != nil {
if err := outboundRequestsRedisFIFOList.Insert(req.Context(), logItemJson); err != nil {
// Log would get upset if we created a logger at init time → create logger on the fly
log.Scoped("redisLoggerMiddleware").Error("insert log item", log.Error(err))
}

View File

@ -19,6 +19,7 @@ go_library(
deps = [
"//internal/conf",
"//internal/redispool",
"//internal/tenant",
"//internal/timeutil",
"//lib/errors",
"@com_github_gomodule_redigo//redis",

View File

@ -18,6 +18,7 @@ import (
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/redispool"
"github.com/sourcegraph/sourcegraph/internal/tenant"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
@ -498,11 +499,12 @@ type TB interface {
func SetupForTest(t TB) {
t.Helper()
ctx := tenant.TestContext()
testStore = redispool.NewTestKeyValue()
// If we are not on CI, skip the test if our redis connection fails.
if os.Getenv("CI") == "" {
if err := testStore.Ping(); err != nil {
if err := testStore.Ping(ctx); err != nil {
t.Skip("could not connect to redis", err)
}
}

View File

@ -11,6 +11,7 @@ go_library(
visibility = ["//:__subpackages__"],
deps = [
"//internal/redispool",
"//internal/tenant",
"//lib/errors",
"@com_github_gomodule_redigo//redis",
"@com_github_inconshreveable_log15//:log15",
@ -30,6 +31,7 @@ go_test(
"requires-network",
],
deps = [
"//internal/tenant",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],

View File

@ -37,7 +37,7 @@ func NewFIFOListDynamic(kv redispool.KeyValue, key string, size func() int) *FIF
}
// Insert b in the cache and drops the oldest inserted item if the size exceeds the configured limit.
func (l *FIFOList) Insert(b []byte) error {
func (l *FIFOList) Insert(ctx context.Context, b []byte) error {
if !utf8.Valid(b) {
return errors.Newf("rcache: keys must be valid utf8", "key", b)
}
@ -47,28 +47,28 @@ func (l *FIFOList) Insert(b []byte) error {
// disabling.
maxSize := l.MaxSize()
if maxSize == 0 {
if err := l.kv().LTrim(key, 0, 0); err != nil {
if err := l.kv().LTrim(ctx, key, 0, 0); err != nil {
return errors.Wrap(err, "failed to execute redis command LTRIM")
}
return nil
}
// O(1) because we're just adding a single element.
if err := l.kv().LPush(key, b); err != nil {
if err := l.kv().LPush(ctx, key, b); err != nil {
return errors.Wrap(err, "failed to execute redis command LPUSH")
}
// O(1) because the average case if just about dropping the last element.
if err := l.kv().LTrim(key, 0, maxSize-1); err != nil {
if err := l.kv().LTrim(ctx, key, 0, maxSize-1); err != nil {
return errors.Wrap(err, "failed to execute redis command LTRIM")
}
return nil
}
// Size returns the number of elements in the list.
func (l *FIFOList) Size() (int, error) {
func (l *FIFOList) Size(ctx context.Context) (int, error) {
key := l.globalPrefixKey()
n, err := l.kv().LLen(key)
n, err := l.kv().LLen(ctx, key)
if err != nil {
return 0, errors.Wrap(err, "failed to execute redis command LLEN")
}
@ -76,8 +76,8 @@ func (l *FIFOList) Size() (int, error) {
}
// IsEmpty returns true if the number of elements in the list is 0.
func (l *FIFOList) IsEmpty() (bool, error) {
size, err := l.Size()
func (l *FIFOList) IsEmpty(ctx context.Context) (bool, error) {
size, err := l.Size(ctx)
if err != nil {
return false, err
}
@ -110,7 +110,7 @@ func (l *FIFOList) Slice(ctx context.Context, from, to int) ([][]byte, error) {
}
key := l.globalPrefixKey()
bs, err := l.kv().WithContext(ctx).LRange(key, from, to).ByteSlices()
bs, err := l.kv().LRange(ctx, key, from, to).ByteSlices()
if err != nil {
// Return ctx error if it expired
if ctx.Err() != nil {

View File

@ -8,9 +8,12 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/sourcegraph/sourcegraph/internal/tenant"
)
func Test_FIFOList_All_OK(t *testing.T) {
ctx := tenant.TestContext()
kv := SetupForTest(t)
type testcase struct {
@ -57,7 +60,7 @@ func Test_FIFOList_All_OK(t *testing.T) {
r := NewFIFOList(kv, c.key, c.size)
t.Run(fmt.Sprintf("size %d with %d entries", c.size, len(c.inserts)), func(t *testing.T) {
for _, b := range c.inserts {
if err := r.Insert(b); err != nil {
if err := r.Insert(ctx, b); err != nil {
t.Errorf("expected no error, got %q", err)
}
}
@ -65,7 +68,7 @@ func Test_FIFOList_All_OK(t *testing.T) {
if err != nil {
t.Errorf("expected no error, got %q", err)
}
s, err := r.Size()
s, err := r.Size(ctx)
if err != nil {
t.Errorf("expected no error, got %q", err)
}
@ -80,6 +83,7 @@ func Test_FIFOList_All_OK(t *testing.T) {
}
func Test_FIFOList_Slice_OK(t *testing.T) {
ctx := tenant.TestContext()
kv := SetupForTest(t)
type testcase struct {
@ -146,7 +150,7 @@ func Test_FIFOList_Slice_OK(t *testing.T) {
r := NewFIFOList(kv, c.key, c.size)
t.Run(fmt.Sprintf("size %d with %d entries, [%d,%d]", c.size, len(c.inserts), c.from, c.to), func(t *testing.T) {
for _, b := range c.inserts {
if err := r.Insert(b); err != nil {
if err := r.Insert(ctx, b); err != nil {
t.Errorf("expected no error, got %q", err)
}
}
@ -162,11 +166,12 @@ func Test_FIFOList_Slice_OK(t *testing.T) {
}
func Test_NewFIFOListDynamic(t *testing.T) {
ctx := tenant.TestContext()
kv := SetupForTest(t)
maxSize := 3
r := NewFIFOListDynamic(kv, "a", func() int { return maxSize })
for range 10 {
err := r.Insert([]byte("a"))
err := r.Insert(ctx, []byte("a"))
if err != nil {
t.Errorf("expected no error, got %q", err)
}
@ -182,7 +187,7 @@ func Test_NewFIFOListDynamic(t *testing.T) {
maxSize = 2
for range 10 {
err := r.Insert([]byte("b"))
err := r.Insert(ctx, []byte("b"))
if err != nil {
t.Errorf("expected no error, got %q", err)
}
@ -198,9 +203,10 @@ func Test_NewFIFOListDynamic(t *testing.T) {
}
func Test_FIFOListContextCancellation(t *testing.T) {
ctx := tenant.TestContext()
kv := SetupForTest(t)
r := NewFIFOList(kv, "a", 3)
err := r.Insert([]byte("a"))
err := r.Insert(ctx, []byte("a"))
if err != nil {
t.Errorf("expected no error, got %q", err)
}
@ -213,14 +219,15 @@ func Test_FIFOListContextCancellation(t *testing.T) {
}
func Test_FIFOListIsEmpty(t *testing.T) {
ctx := tenant.TestContext()
kv := SetupForTest(t)
r := NewFIFOList(kv, "a", 3)
empty, err := r.IsEmpty()
empty, err := r.IsEmpty(ctx)
require.NoError(t, err)
assert.True(t, empty)
err = r.Insert([]byte("a"))
err = r.Insert(ctx, []byte("a"))
require.NoError(t, err)
empty, err = r.IsEmpty()
empty, err = r.IsEmpty(ctx)
require.NoError(t, err)
assert.False(t, empty)
}

View File

@ -12,6 +12,7 @@ import (
"github.com/inconshreveable/log15" //nolint:logging // TODO move all logging to sourcegraph/log
"github.com/sourcegraph/sourcegraph/internal/redispool"
"github.com/sourcegraph/sourcegraph/internal/tenant"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
@ -243,6 +244,7 @@ const testAddr = "127.0.0.1:6379"
func SetupForTest(t testing.TB) redispool.KeyValue {
t.Helper()
ctx := tenant.TestContext()
testStore = redispool.NewTestKeyValue()
t.Cleanup(func() {
testStore.Pool().Close()
@ -251,7 +253,7 @@ func SetupForTest(t testing.TB) redispool.KeyValue {
// If we are not on CI, skip the test if our redis connection fails.
if os.Getenv("CI") == "" {
if err := testStore.Ping(); err != nil {
if err := testStore.Ping(ctx); err != nil {
t.Skip("could not connect to redis", err)
}
}

View File

@ -35,6 +35,7 @@ go_test(
"requires-network",
],
deps = [
"//internal/tenant",
"//lib/errors",
"@com_github_gomodule_redigo//redis",
"@com_github_sourcegraph_log//logtest",

View File

@ -39,20 +39,22 @@ type KeyValue interface {
HSet(key, field string, value any) error
HDel(key, field string) Value
LPush(key string, value any) error
LTrim(key string, start, stop int) error
LLen(key string) (int, error)
LRange(key string, start, stop int) Values
LPush(ctx context.Context, key string, value any) error
LTrim(ctx context.Context, key string, start, stop int) error
LLen(ctx context.Context, key string) (int, error)
LRange(ctx context.Context, key string, start, stop int) Values
// Ping checks the connection to the redis server.
Ping() error
Ping(ctx context.Context) error
// Keys returns all keys matching the glob pattern. NOTE: this command takes time
// linear in the number of keys, and should not be run over large keyspaces.
Keys(pattern string) ([]string, error)
// WithContext will return a KeyValue that should respect ctx for all
// blocking operations.
// WithContext will return a KeyValue that should respect ctx for all blocking operations.
//
// DEPRECATED: We are in the process of adding context to each individual operation (Get, Set, etc.)
// Once that is complete, this method will be removed.
WithContext(ctx context.Context) KeyValue
WithLatencyRecorder(r LatencyRecorder) KeyValue
@ -169,33 +171,33 @@ type redisKeyValue struct {
recorder *LatencyRecorder
}
func (r *redisKeyValue) Ping() error {
func (r *redisKeyValue) Ping(ctx context.Context) error {
// The 'ping' command takes no arguments
return r.do("PING", []string{}, []any{}).err
return r.do(ctx, "PING", []string{}, []any{}).err
}
func (r *redisKeyValue) Get(key string) Value {
return r.doSimple("GET", key)
return r.doWithoutContext("GET", []string{key}, []any{})
}
func (r *redisKeyValue) GetSet(key string, val any) Value {
return r.doSimple("GETSET", key, val)
return r.doWithoutContext("GETSET", []string{key}, []any{val})
}
func (r *redisKeyValue) MGet(keys []string) Values {
return Values(r.do("MGET", keys, []any{}))
return Values(r.doWithoutContext("MGET", keys, []any{}))
}
func (r *redisKeyValue) Set(key string, val any) error {
return r.doSimple("SET", key, val).err
return r.doWithoutContext("SET", []string{key}, []any{val}).err
}
func (r *redisKeyValue) SetEx(key string, ttlSeconds int, val any) error {
return r.doSimple("SETEX", key, ttlSeconds, val).err
return r.doWithoutContext("SETEX", []string{key}, []any{ttlSeconds, val}).err
}
func (r *redisKeyValue) SetNx(key string, val any) (bool, error) {
_, err := r.doSimple("SET", key, val, "NX").String()
_, err := r.doWithoutContext("SET", []string{key}, []any{val, "NX"}).String()
if err == redis.ErrNil {
return false, nil
}
@ -203,61 +205,62 @@ func (r *redisKeyValue) SetNx(key string, val any) (bool, error) {
}
func (r *redisKeyValue) Incr(key string) (int, error) {
return r.doSimple("INCR", key).Int()
return r.doWithoutContext("INCR", []string{key}, []any{}).Int()
}
func (r *redisKeyValue) Incrby(key string, value int) (int, error) {
return r.doSimple("INCRBY", key, value).Int()
return r.doWithoutContext("INCRBY", []string{key}, []any{value}).Int()
}
func (r *redisKeyValue) IncrByInt64(key string, value int64) (int64, error) {
return r.doSimple("INCRBY", key, value).Int64()
return r.doWithoutContext("INCRBY", []string{key}, []any{value}).Int64()
}
func (r *redisKeyValue) DecrByInt64(key string, value int64) (int64, error) {
return r.doSimple("DECRBY", key, value).Int64()
return r.doWithoutContext("DECRBY", []string{key}, []any{value}).Int64()
}
func (r *redisKeyValue) Del(key string) error {
return r.doSimple("DEL", key).err
return r.doWithoutContext("DEL", []string{key}, []any{}).err
}
func (r *redisKeyValue) TTL(key string) (int, error) {
return r.doSimple("TTL", key).Int()
return r.doWithoutContext("TTL", []string{key}, []any{}).Int()
}
func (r *redisKeyValue) Expire(key string, ttlSeconds int) error {
return r.doSimple("EXPIRE", key, ttlSeconds).err
return r.doWithoutContext("EXPIRE", []string{key}, []any{ttlSeconds}).err
}
func (r *redisKeyValue) HGet(key, field string) Value {
return r.doSimple("HGET", key, field)
return r.doWithoutContext("HGET", []string{key}, []any{field})
}
func (r *redisKeyValue) HGetAll(key string) Values {
return Values(r.doSimple("HGETALL", key))
return Values(r.doWithoutContext("HGETALL", []string{key}, []any{}))
}
func (r *redisKeyValue) HSet(key, field string, val any) error {
return r.doSimple("HSET", key, field, val).err
return r.doWithoutContext("HSET", []string{key}, []any{field, val}).err
}
func (r *redisKeyValue) HDel(key, field string) Value {
return r.doSimple("HDEL", key, field)
return r.doWithoutContext("HDEL", []string{key}, []any{field})
}
func (r *redisKeyValue) LPush(key string, value any) error {
return r.doSimple("LPUSH", key, value).err
func (r *redisKeyValue) LPush(ctx context.Context, key string, value any) error {
return r.do(ctx, "LPUSH", []string{key}, []any{value}).err
}
func (r *redisKeyValue) LTrim(key string, start, stop int) error {
return r.doSimple("LTRIM", key, start, stop).err
func (r *redisKeyValue) LTrim(ctx context.Context, key string, start, stop int) error {
return r.do(ctx, "LTRIM", []string{key}, []any{start, stop}).err
}
func (r *redisKeyValue) LLen(key string) (int, error) {
raw := r.doSimple("LLEN", key)
func (r *redisKeyValue) LLen(ctx context.Context, key string) (int, error) {
raw := r.do(ctx, "LLEN", []string{key}, []any{})
return redis.Int(raw.reply, raw.err)
}
func (r *redisKeyValue) LRange(key string, start, stop int) Values {
return Values(r.doSimple("LRANGE", key, start, stop))
func (r *redisKeyValue) LRange(ctx context.Context, key string, start, stop int) Values {
return Values(r.do(ctx, "LRANGE", []string{key}, []any{start, stop}))
}
func (r *redisKeyValue) WithContext(ctx context.Context) KeyValue {
@ -286,27 +289,21 @@ func (r *redisKeyValue) WithPrefix(prefix string) KeyValue {
}
func (r *redisKeyValue) Keys(pattern string) ([]string, error) {
return Values(r.doSimple("KEYS", pattern)).Strings()
return Values(r.doWithoutContext("KEYS", []string{pattern}, []any{})).Strings()
}
func (r *redisKeyValue) Pool() *redis.Pool {
return r.pool
}
func (r *redisKeyValue) doSimple(commandName string, key string, args ...any) Value {
return r.do(commandName, []string{key}, args)
func (r *redisKeyValue) doWithoutContext(commandName string, keys []string, args []any) Value {
return r.do(context.Background(), commandName, keys, args)
}
func (r *redisKeyValue) do(commandName string, keys []string, args []any) Value {
var c redis.Conn
if r.ctx != nil {
var err error
c, err = r.pool.GetContext(r.ctx)
if err != nil {
return Value{err: err}
}
} else {
c = r.pool.Get()
func (r *redisKeyValue) do(ctx context.Context, commandName string, keys []string, args []any) Value {
c, err := r.pool.GetContext(ctx)
if err != nil {
return Value{err: err}
}
defer c.Close()

View File

@ -11,11 +11,13 @@ import (
"github.com/stretchr/testify/assert"
"github.com/sourcegraph/sourcegraph/internal/redispool"
"github.com/sourcegraph/sourcegraph/internal/tenant"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
func TestKeyValue(t *testing.T) {
kv := redisKeyValueForTest(t)
ctx := tenant.TestContext()
errWrongType := errors.New("WRONGTYPE")
// "strings" is the name of the classic group of commands in redis (get, set, ttl, etc). We call it classic since that is less confusing.
@ -127,53 +129,53 @@ func TestKeyValue(t *testing.T) {
// Redis behaviour on unset lists
require.ListLen(kv, "list-unset-0", 0)
require.AllEqual(kv.LRange("list-unset-1", 0, 10), bytes())
require.Works(kv.LTrim("list-unset-2", 0, 10))
require.AllEqual(kv.LRange(ctx, "list-unset-1", 0, 10), bytes())
require.Works(kv.LTrim(ctx, "list-unset-2", 0, 10))
require.Works(kv.LPush("list", "4"))
require.Works(kv.LPush("list", "3"))
require.Works(kv.LPush("list", "2"))
require.Works(kv.LPush("list", "1"))
require.Works(kv.LPush("list", "0"))
require.Works(kv.LPush(ctx, "list", "4"))
require.Works(kv.LPush(ctx, "list", "3"))
require.Works(kv.LPush(ctx, "list", "2"))
require.Works(kv.LPush(ctx, "list", "1"))
require.Works(kv.LPush(ctx, "list", "0"))
// Different ways we get the full list back
require.AllEqual(kv.LRange("list", 0, 10), []string{"0", "1", "2", "3", "4"})
require.AllEqual(kv.LRange("list", 0, 10), bytes("0", "1", "2", "3", "4"))
require.AllEqual(kv.LRange("list", 0, -1), bytes("0", "1", "2", "3", "4"))
require.AllEqual(kv.LRange("list", -5, -1), bytes("0", "1", "2", "3", "4"))
require.AllEqual(kv.LRange("list", 0, 4), bytes("0", "1", "2", "3", "4"))
require.AllEqual(kv.LRange(ctx, "list", 0, 10), []string{"0", "1", "2", "3", "4"})
require.AllEqual(kv.LRange(ctx, "list", 0, 10), bytes("0", "1", "2", "3", "4"))
require.AllEqual(kv.LRange(ctx, "list", 0, -1), bytes("0", "1", "2", "3", "4"))
require.AllEqual(kv.LRange(ctx, "list", -5, -1), bytes("0", "1", "2", "3", "4"))
require.AllEqual(kv.LRange(ctx, "list", 0, 4), bytes("0", "1", "2", "3", "4"))
// If stop < start we return nothing
require.AllEqual(kv.LRange("list", -1, 0), bytes())
require.AllEqual(kv.LRange(ctx, "list", -1, 0), bytes())
// Subsets
require.AllEqual(kv.LRange("list", 1, 3), bytes("1", "2", "3"))
require.AllEqual(kv.LRange("list", 1, -2), bytes("1", "2", "3"))
require.AllEqual(kv.LRange("list", -4, 3), bytes("1", "2", "3"))
require.AllEqual(kv.LRange("list", -4, -2), bytes("1", "2", "3"))
require.AllEqual(kv.LRange(ctx, "list", 1, 3), bytes("1", "2", "3"))
require.AllEqual(kv.LRange(ctx, "list", 1, -2), bytes("1", "2", "3"))
require.AllEqual(kv.LRange(ctx, "list", -4, 3), bytes("1", "2", "3"))
require.AllEqual(kv.LRange(ctx, "list", -4, -2), bytes("1", "2", "3"))
// Trim noop
require.Works(kv.LTrim("list", 0, 10))
require.AllEqual(kv.LRange("list", 0, 4), bytes("0", "1", "2", "3", "4"))
require.Works(kv.LTrim(ctx, "list", 0, 10))
require.AllEqual(kv.LRange(ctx, "list", 0, 4), bytes("0", "1", "2", "3", "4"))
// Trim popback
require.Works(kv.LTrim("list", 0, -2))
require.AllEqual(kv.LRange("list", 0, 4), bytes("0", "1", "2", "3"))
require.Works(kv.LTrim(ctx, "list", 0, -2))
require.AllEqual(kv.LRange(ctx, "list", 0, 4), bytes("0", "1", "2", "3"))
require.ListLen(kv, "list", 4)
// Trim popfront
require.Works(kv.LTrim("list", 1, 10))
require.AllEqual(kv.LRange("list", 0, 4), bytes("1", "2", "3"))
require.Works(kv.LTrim(ctx, "list", 1, 10))
require.AllEqual(kv.LRange(ctx, "list", 0, 4), bytes("1", "2", "3"))
require.ListLen(kv, "list", 3)
// Trim all
require.Works(kv.LTrim("list", -1, -2))
require.AllEqual(kv.LRange("list", 0, 4), bytes())
require.Works(kv.LTrim(ctx, "list", -1, -2))
require.AllEqual(kv.LRange(ctx, "list", 0, 4), bytes())
require.ListLen(kv, "list", 0)
require.Works(kv.LPush("funky2D", []byte{100, 255}))
require.Works(kv.LPush("funky2D", []byte{0, 10}))
require.AllEqual(kv.LRange("funky2D", 0, -1), [][]byte{{0, 10}, {100, 255}})
require.Works(kv.LPush(ctx, "funky2D", []byte{100, 255}))
require.Works(kv.LPush(ctx, "funky2D", []byte{0, 10}))
require.AllEqual(kv.LRange(ctx, "funky2D", 0, -1), [][]byte{{0, 10}, {100, 255}})
})
t.Run("empty", func(t *testing.T) {
@ -191,9 +193,9 @@ func TestKeyValue(t *testing.T) {
// List group. Once empty we should be able to doSimple a Get without a
// wrongtype error.
require.Works(kv.LPush("empty-list", "here today gone tomorrow"))
require.Works(kv.LPush(ctx, "empty-list", "here today gone tomorrow"))
require.Equal(kv.Get("empty-list"), errWrongType)
require.Works(kv.LTrim("empty-list", -1, -2))
require.Works(kv.LTrim(ctx, "empty-list", -1, -2))
require.Equal(kv.Get("empty-list"), nil)
})
@ -285,20 +287,20 @@ func TestKeyValue(t *testing.T) {
require := require{TB: t}
// Hash mutations keep expire
require.Works(kv.LPush("expires-unset-list", "1"))
require.Works(kv.LPush("expires-set-list", "1"))
require.Works(kv.LPush(ctx, "expires-unset-list", "1"))
require.Works(kv.LPush(ctx, "expires-set-list", "1"))
require.Works(kv.Expire("expires-set-list", 60))
require.TTL(kv, "expires-unset-list", -1)
require.TTL(kv, "expires-set-list", 60)
require.AllEqual(kv.LRange("expires-unset-list", 0, -1), []string{"1"})
require.AllEqual(kv.LRange("expires-set-list", 0, -1), []string{"1"})
require.AllEqual(kv.LRange(ctx, "expires-unset-list", 0, -1), []string{"1"})
require.AllEqual(kv.LRange(ctx, "expires-set-list", 0, -1), []string{"1"})
require.Works(kv.LPush("expires-unset-list", "2"))
require.Works(kv.LPush("expires-set-list", "2"))
require.Works(kv.LPush(ctx, "expires-unset-list", "2"))
require.Works(kv.LPush(ctx, "expires-set-list", "2"))
require.TTL(kv, "expires-unset-list", -1)
require.TTL(kv, "expires-set-list", 60)
require.AllEqual(kv.LRange("expires-unset-list", 0, -1), []string{"2", "1"})
require.AllEqual(kv.LRange("expires-set-list", 0, -1), []string{"2", "1"})
require.AllEqual(kv.LRange(ctx, "expires-unset-list", 0, -1), []string{"2", "1"})
require.AllEqual(kv.LRange(ctx, "expires-set-list", 0, -1), []string{"2", "1"})
// Check expiration happens on hashes
require.Works(kv.Expire("expires-set-list", 1))
@ -320,7 +322,7 @@ func TestKeyValue(t *testing.T) {
require.Works(kv.Set("wrongtype-string", "1"))
require.Works(kv.HSet("wrongtype-hash", "1", "1"))
require.Works(kv.LPush("wrongtype-list", "1"))
require.Works(kv.LPush(ctx, "wrongtype-list", "1"))
for _, k := range []string{"wrongtype-string", "wrongtype-hash", "wrongtype-list"} {
// Ensure we fail Get when used against non string group
@ -341,11 +343,11 @@ func TestKeyValue(t *testing.T) {
// Ensure we fail lists when used against non lists.
if k != "wrongtype-list" {
_, err := kv.LLen(k)
_, err := kv.LLen(ctx, k)
requireWrongType(err)
requireWrongType(kv.LPush(k, "1"))
requireWrongType(kv.LTrim(k, 1, 2))
require.Equal(redispool.Value(kv.LRange(k, 1, 2)), errWrongType)
requireWrongType(kv.LPush(ctx, k, "1"))
requireWrongType(kv.LTrim(ctx, k, 1, 2))
require.Equal(redispool.Value(kv.LRange(ctx, k, 1, 2)), errWrongType)
}
// Ensure we can always override values with set
@ -357,13 +359,13 @@ func TestKeyValue(t *testing.T) {
t.Run("ping", func(t *testing.T) {
t.Parallel()
require := require{TB: t}
require.Works(kv.Ping())
require.Works(kv.Ping(ctx))
brokenKv := redispool.NewKeyValue("nonexistent-redis-server:6379", &redis.Pool{
MaxIdle: 3,
IdleTimeout: 5 * time.Second,
})
if brokenKv.Ping() == nil {
if brokenKv.Ping(ctx) == nil {
t.Fatalf("ping: expected error, but did not receive one")
}
})
@ -416,12 +418,13 @@ func TestKeyValueWithPrefix(t *testing.T) {
func redisKeyValueForTest(t *testing.T) redispool.KeyValue {
t.Helper()
ctx := tenant.TestContext()
kv := redispool.NewTestKeyValue()
prefix := "__test__" + t.Name()
// If we are not on CI, skip the test if our redis connection fails.
if os.Getenv("CI") == "" {
if err := kv.Ping(); err != nil {
if err := kv.Ping(ctx); err != nil {
t.Skip("could not connect to redis", err)
}
}
@ -526,7 +529,7 @@ func (t require) AllEqual(got redispool.Values, want any) {
}
func (t require) ListLen(kv redispool.KeyValue, key string, want int) {
t.Helper()
got, err := kv.LLen(key)
got, err := kv.LLen(tenant.TestContext(), key)
if err != nil {
t.Fatal("LLen returned error", err)
}

View File

@ -170,22 +170,22 @@ func NewMockKeyValue() *MockKeyValue {
},
},
LLenFunc: &KeyValueLLenFunc{
defaultHook: func(string) (r0 int, r1 error) {
defaultHook: func(context.Context, string) (r0 int, r1 error) {
return
},
},
LPushFunc: &KeyValueLPushFunc{
defaultHook: func(string, interface{}) (r0 error) {
defaultHook: func(context.Context, string, interface{}) (r0 error) {
return
},
},
LRangeFunc: &KeyValueLRangeFunc{
defaultHook: func(string, int, int) (r0 Values) {
defaultHook: func(context.Context, string, int, int) (r0 Values) {
return
},
},
LTrimFunc: &KeyValueLTrimFunc{
defaultHook: func(string, int, int) (r0 error) {
defaultHook: func(context.Context, string, int, int) (r0 error) {
return
},
},
@ -195,7 +195,7 @@ func NewMockKeyValue() *MockKeyValue {
},
},
PingFunc: &KeyValuePingFunc{
defaultHook: func() (r0 error) {
defaultHook: func(context.Context) (r0 error) {
return
},
},
@ -312,22 +312,22 @@ func NewStrictMockKeyValue() *MockKeyValue {
},
},
LLenFunc: &KeyValueLLenFunc{
defaultHook: func(string) (int, error) {
defaultHook: func(context.Context, string) (int, error) {
panic("unexpected invocation of MockKeyValue.LLen")
},
},
LPushFunc: &KeyValueLPushFunc{
defaultHook: func(string, interface{}) error {
defaultHook: func(context.Context, string, interface{}) error {
panic("unexpected invocation of MockKeyValue.LPush")
},
},
LRangeFunc: &KeyValueLRangeFunc{
defaultHook: func(string, int, int) Values {
defaultHook: func(context.Context, string, int, int) Values {
panic("unexpected invocation of MockKeyValue.LRange")
},
},
LTrimFunc: &KeyValueLTrimFunc{
defaultHook: func(string, int, int) error {
defaultHook: func(context.Context, string, int, int) error {
panic("unexpected invocation of MockKeyValue.LTrim")
},
},
@ -337,7 +337,7 @@ func NewStrictMockKeyValue() *MockKeyValue {
},
},
PingFunc: &KeyValuePingFunc{
defaultHook: func() error {
defaultHook: func(context.Context) error {
panic("unexpected invocation of MockKeyValue.Ping")
},
},
@ -1832,23 +1832,23 @@ func (c KeyValueKeysFuncCall) Results() []interface{} {
// KeyValueLLenFunc describes the behavior when the LLen method of the
// parent MockKeyValue instance is invoked.
type KeyValueLLenFunc struct {
defaultHook func(string) (int, error)
hooks []func(string) (int, error)
defaultHook func(context.Context, string) (int, error)
hooks []func(context.Context, string) (int, error)
history []KeyValueLLenFuncCall
mutex sync.Mutex
}
// LLen delegates to the next hook function in the queue and stores the
// parameter and result values of this invocation.
func (m *MockKeyValue) LLen(v0 string) (int, error) {
r0, r1 := m.LLenFunc.nextHook()(v0)
m.LLenFunc.appendCall(KeyValueLLenFuncCall{v0, r0, r1})
func (m *MockKeyValue) LLen(v0 context.Context, v1 string) (int, error) {
r0, r1 := m.LLenFunc.nextHook()(v0, v1)
m.LLenFunc.appendCall(KeyValueLLenFuncCall{v0, v1, r0, r1})
return r0, r1
}
// SetDefaultHook sets function that is called when the LLen method of the
// parent MockKeyValue instance is invoked and the hook queue is empty.
func (f *KeyValueLLenFunc) SetDefaultHook(hook func(string) (int, error)) {
func (f *KeyValueLLenFunc) SetDefaultHook(hook func(context.Context, string) (int, error)) {
f.defaultHook = hook
}
@ -1856,7 +1856,7 @@ func (f *KeyValueLLenFunc) SetDefaultHook(hook func(string) (int, error)) {
// LLen method of the parent MockKeyValue instance invokes the hook at the
// front of the queue and discards it. After the queue is empty, the default
// hook function is invoked for any future action.
func (f *KeyValueLLenFunc) PushHook(hook func(string) (int, error)) {
func (f *KeyValueLLenFunc) PushHook(hook func(context.Context, string) (int, error)) {
f.mutex.Lock()
f.hooks = append(f.hooks, hook)
f.mutex.Unlock()
@ -1865,19 +1865,19 @@ func (f *KeyValueLLenFunc) PushHook(hook func(string) (int, error)) {
// SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values.
func (f *KeyValueLLenFunc) SetDefaultReturn(r0 int, r1 error) {
f.SetDefaultHook(func(string) (int, error) {
f.SetDefaultHook(func(context.Context, string) (int, error) {
return r0, r1
})
}
// PushReturn calls PushHook with a function that returns the given values.
func (f *KeyValueLLenFunc) PushReturn(r0 int, r1 error) {
f.PushHook(func(string) (int, error) {
f.PushHook(func(context.Context, string) (int, error) {
return r0, r1
})
}
func (f *KeyValueLLenFunc) nextHook() func(string) (int, error) {
func (f *KeyValueLLenFunc) nextHook() func(context.Context, string) (int, error) {
f.mutex.Lock()
defer f.mutex.Unlock()
@ -1912,7 +1912,10 @@ func (f *KeyValueLLenFunc) History() []KeyValueLLenFuncCall {
type KeyValueLLenFuncCall struct {
// Arg0 is the value of the 1st argument passed to this method
// invocation.
Arg0 string
Arg0 context.Context
// Arg1 is the value of the 2nd argument passed to this method
// invocation.
Arg1 string
// Result0 is the value of the 1st result returned from this method
// invocation.
Result0 int
@ -1924,7 +1927,7 @@ type KeyValueLLenFuncCall struct {
// Args returns an interface slice containing the arguments of this
// invocation.
func (c KeyValueLLenFuncCall) Args() []interface{} {
return []interface{}{c.Arg0}
return []interface{}{c.Arg0, c.Arg1}
}
// Results returns an interface slice containing the results of this
@ -1936,23 +1939,23 @@ func (c KeyValueLLenFuncCall) Results() []interface{} {
// KeyValueLPushFunc describes the behavior when the LPush method of the
// parent MockKeyValue instance is invoked.
type KeyValueLPushFunc struct {
defaultHook func(string, interface{}) error
hooks []func(string, interface{}) error
defaultHook func(context.Context, string, interface{}) error
hooks []func(context.Context, string, interface{}) error
history []KeyValueLPushFuncCall
mutex sync.Mutex
}
// LPush delegates to the next hook function in the queue and stores the
// parameter and result values of this invocation.
func (m *MockKeyValue) LPush(v0 string, v1 interface{}) error {
r0 := m.LPushFunc.nextHook()(v0, v1)
m.LPushFunc.appendCall(KeyValueLPushFuncCall{v0, v1, r0})
func (m *MockKeyValue) LPush(v0 context.Context, v1 string, v2 interface{}) error {
r0 := m.LPushFunc.nextHook()(v0, v1, v2)
m.LPushFunc.appendCall(KeyValueLPushFuncCall{v0, v1, v2, r0})
return r0
}
// SetDefaultHook sets function that is called when the LPush method of the
// parent MockKeyValue instance is invoked and the hook queue is empty.
func (f *KeyValueLPushFunc) SetDefaultHook(hook func(string, interface{}) error) {
func (f *KeyValueLPushFunc) SetDefaultHook(hook func(context.Context, string, interface{}) error) {
f.defaultHook = hook
}
@ -1960,7 +1963,7 @@ func (f *KeyValueLPushFunc) SetDefaultHook(hook func(string, interface{}) error)
// LPush method of the parent MockKeyValue instance invokes the hook at the
// front of the queue and discards it. After the queue is empty, the default
// hook function is invoked for any future action.
func (f *KeyValueLPushFunc) PushHook(hook func(string, interface{}) error) {
func (f *KeyValueLPushFunc) PushHook(hook func(context.Context, string, interface{}) error) {
f.mutex.Lock()
f.hooks = append(f.hooks, hook)
f.mutex.Unlock()
@ -1969,19 +1972,19 @@ func (f *KeyValueLPushFunc) PushHook(hook func(string, interface{}) error) {
// SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values.
func (f *KeyValueLPushFunc) SetDefaultReturn(r0 error) {
f.SetDefaultHook(func(string, interface{}) error {
f.SetDefaultHook(func(context.Context, string, interface{}) error {
return r0
})
}
// PushReturn calls PushHook with a function that returns the given values.
func (f *KeyValueLPushFunc) PushReturn(r0 error) {
f.PushHook(func(string, interface{}) error {
f.PushHook(func(context.Context, string, interface{}) error {
return r0
})
}
func (f *KeyValueLPushFunc) nextHook() func(string, interface{}) error {
func (f *KeyValueLPushFunc) nextHook() func(context.Context, string, interface{}) error {
f.mutex.Lock()
defer f.mutex.Unlock()
@ -2016,10 +2019,13 @@ func (f *KeyValueLPushFunc) History() []KeyValueLPushFuncCall {
type KeyValueLPushFuncCall struct {
// Arg0 is the value of the 1st argument passed to this method
// invocation.
Arg0 string
Arg0 context.Context
// Arg1 is the value of the 2nd argument passed to this method
// invocation.
Arg1 interface{}
Arg1 string
// Arg2 is the value of the 3rd argument passed to this method
// invocation.
Arg2 interface{}
// Result0 is the value of the 1st result returned from this method
// invocation.
Result0 error
@ -2028,7 +2034,7 @@ type KeyValueLPushFuncCall struct {
// Args returns an interface slice containing the arguments of this
// invocation.
func (c KeyValueLPushFuncCall) Args() []interface{} {
return []interface{}{c.Arg0, c.Arg1}
return []interface{}{c.Arg0, c.Arg1, c.Arg2}
}
// Results returns an interface slice containing the results of this
@ -2040,23 +2046,23 @@ func (c KeyValueLPushFuncCall) Results() []interface{} {
// KeyValueLRangeFunc describes the behavior when the LRange method of the
// parent MockKeyValue instance is invoked.
type KeyValueLRangeFunc struct {
defaultHook func(string, int, int) Values
hooks []func(string, int, int) Values
defaultHook func(context.Context, string, int, int) Values
hooks []func(context.Context, string, int, int) Values
history []KeyValueLRangeFuncCall
mutex sync.Mutex
}
// LRange delegates to the next hook function in the queue and stores the
// parameter and result values of this invocation.
func (m *MockKeyValue) LRange(v0 string, v1 int, v2 int) Values {
r0 := m.LRangeFunc.nextHook()(v0, v1, v2)
m.LRangeFunc.appendCall(KeyValueLRangeFuncCall{v0, v1, v2, r0})
func (m *MockKeyValue) LRange(v0 context.Context, v1 string, v2 int, v3 int) Values {
r0 := m.LRangeFunc.nextHook()(v0, v1, v2, v3)
m.LRangeFunc.appendCall(KeyValueLRangeFuncCall{v0, v1, v2, v3, r0})
return r0
}
// SetDefaultHook sets function that is called when the LRange method of the
// parent MockKeyValue instance is invoked and the hook queue is empty.
func (f *KeyValueLRangeFunc) SetDefaultHook(hook func(string, int, int) Values) {
func (f *KeyValueLRangeFunc) SetDefaultHook(hook func(context.Context, string, int, int) Values) {
f.defaultHook = hook
}
@ -2064,7 +2070,7 @@ func (f *KeyValueLRangeFunc) SetDefaultHook(hook func(string, int, int) Values)
// LRange method of the parent MockKeyValue instance invokes the hook at the
// front of the queue and discards it. After the queue is empty, the default
// hook function is invoked for any future action.
func (f *KeyValueLRangeFunc) PushHook(hook func(string, int, int) Values) {
func (f *KeyValueLRangeFunc) PushHook(hook func(context.Context, string, int, int) Values) {
f.mutex.Lock()
f.hooks = append(f.hooks, hook)
f.mutex.Unlock()
@ -2073,19 +2079,19 @@ func (f *KeyValueLRangeFunc) PushHook(hook func(string, int, int) Values) {
// SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values.
func (f *KeyValueLRangeFunc) SetDefaultReturn(r0 Values) {
f.SetDefaultHook(func(string, int, int) Values {
f.SetDefaultHook(func(context.Context, string, int, int) Values {
return r0
})
}
// PushReturn calls PushHook with a function that returns the given values.
func (f *KeyValueLRangeFunc) PushReturn(r0 Values) {
f.PushHook(func(string, int, int) Values {
f.PushHook(func(context.Context, string, int, int) Values {
return r0
})
}
func (f *KeyValueLRangeFunc) nextHook() func(string, int, int) Values {
func (f *KeyValueLRangeFunc) nextHook() func(context.Context, string, int, int) Values {
f.mutex.Lock()
defer f.mutex.Unlock()
@ -2120,13 +2126,16 @@ func (f *KeyValueLRangeFunc) History() []KeyValueLRangeFuncCall {
type KeyValueLRangeFuncCall struct {
// Arg0 is the value of the 1st argument passed to this method
// invocation.
Arg0 string
Arg0 context.Context
// Arg1 is the value of the 2nd argument passed to this method
// invocation.
Arg1 int
Arg1 string
// Arg2 is the value of the 3rd argument passed to this method
// invocation.
Arg2 int
// Arg3 is the value of the 4th argument passed to this method
// invocation.
Arg3 int
// Result0 is the value of the 1st result returned from this method
// invocation.
Result0 Values
@ -2135,7 +2144,7 @@ type KeyValueLRangeFuncCall struct {
// Args returns an interface slice containing the arguments of this
// invocation.
func (c KeyValueLRangeFuncCall) Args() []interface{} {
return []interface{}{c.Arg0, c.Arg1, c.Arg2}
return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3}
}
// Results returns an interface slice containing the results of this
@ -2147,23 +2156,23 @@ func (c KeyValueLRangeFuncCall) Results() []interface{} {
// KeyValueLTrimFunc describes the behavior when the LTrim method of the
// parent MockKeyValue instance is invoked.
type KeyValueLTrimFunc struct {
defaultHook func(string, int, int) error
hooks []func(string, int, int) error
defaultHook func(context.Context, string, int, int) error
hooks []func(context.Context, string, int, int) error
history []KeyValueLTrimFuncCall
mutex sync.Mutex
}
// LTrim delegates to the next hook function in the queue and stores the
// parameter and result values of this invocation.
func (m *MockKeyValue) LTrim(v0 string, v1 int, v2 int) error {
r0 := m.LTrimFunc.nextHook()(v0, v1, v2)
m.LTrimFunc.appendCall(KeyValueLTrimFuncCall{v0, v1, v2, r0})
func (m *MockKeyValue) LTrim(v0 context.Context, v1 string, v2 int, v3 int) error {
r0 := m.LTrimFunc.nextHook()(v0, v1, v2, v3)
m.LTrimFunc.appendCall(KeyValueLTrimFuncCall{v0, v1, v2, v3, r0})
return r0
}
// SetDefaultHook sets function that is called when the LTrim method of the
// parent MockKeyValue instance is invoked and the hook queue is empty.
func (f *KeyValueLTrimFunc) SetDefaultHook(hook func(string, int, int) error) {
func (f *KeyValueLTrimFunc) SetDefaultHook(hook func(context.Context, string, int, int) error) {
f.defaultHook = hook
}
@ -2171,7 +2180,7 @@ func (f *KeyValueLTrimFunc) SetDefaultHook(hook func(string, int, int) error) {
// LTrim method of the parent MockKeyValue instance invokes the hook at the
// front of the queue and discards it. After the queue is empty, the default
// hook function is invoked for any future action.
func (f *KeyValueLTrimFunc) PushHook(hook func(string, int, int) error) {
func (f *KeyValueLTrimFunc) PushHook(hook func(context.Context, string, int, int) error) {
f.mutex.Lock()
f.hooks = append(f.hooks, hook)
f.mutex.Unlock()
@ -2180,19 +2189,19 @@ func (f *KeyValueLTrimFunc) PushHook(hook func(string, int, int) error) {
// SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values.
func (f *KeyValueLTrimFunc) SetDefaultReturn(r0 error) {
f.SetDefaultHook(func(string, int, int) error {
f.SetDefaultHook(func(context.Context, string, int, int) error {
return r0
})
}
// PushReturn calls PushHook with a function that returns the given values.
func (f *KeyValueLTrimFunc) PushReturn(r0 error) {
f.PushHook(func(string, int, int) error {
f.PushHook(func(context.Context, string, int, int) error {
return r0
})
}
func (f *KeyValueLTrimFunc) nextHook() func(string, int, int) error {
func (f *KeyValueLTrimFunc) nextHook() func(context.Context, string, int, int) error {
f.mutex.Lock()
defer f.mutex.Unlock()
@ -2227,13 +2236,16 @@ func (f *KeyValueLTrimFunc) History() []KeyValueLTrimFuncCall {
type KeyValueLTrimFuncCall struct {
// Arg0 is the value of the 1st argument passed to this method
// invocation.
Arg0 string
Arg0 context.Context
// Arg1 is the value of the 2nd argument passed to this method
// invocation.
Arg1 int
Arg1 string
// Arg2 is the value of the 3rd argument passed to this method
// invocation.
Arg2 int
// Arg3 is the value of the 4th argument passed to this method
// invocation.
Arg3 int
// Result0 is the value of the 1st result returned from this method
// invocation.
Result0 error
@ -2242,7 +2254,7 @@ type KeyValueLTrimFuncCall struct {
// Args returns an interface slice containing the arguments of this
// invocation.
func (c KeyValueLTrimFuncCall) Args() []interface{} {
return []interface{}{c.Arg0, c.Arg1, c.Arg2}
return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3}
}
// Results returns an interface slice containing the results of this
@ -2355,23 +2367,23 @@ func (c KeyValueMGetFuncCall) Results() []interface{} {
// KeyValuePingFunc describes the behavior when the Ping method of the
// parent MockKeyValue instance is invoked.
type KeyValuePingFunc struct {
defaultHook func() error
hooks []func() error
defaultHook func(context.Context) error
hooks []func(context.Context) error
history []KeyValuePingFuncCall
mutex sync.Mutex
}
// Ping delegates to the next hook function in the queue and stores the
// parameter and result values of this invocation.
func (m *MockKeyValue) Ping() error {
r0 := m.PingFunc.nextHook()()
m.PingFunc.appendCall(KeyValuePingFuncCall{r0})
func (m *MockKeyValue) Ping(v0 context.Context) error {
r0 := m.PingFunc.nextHook()(v0)
m.PingFunc.appendCall(KeyValuePingFuncCall{v0, r0})
return r0
}
// SetDefaultHook sets function that is called when the Ping method of the
// parent MockKeyValue instance is invoked and the hook queue is empty.
func (f *KeyValuePingFunc) SetDefaultHook(hook func() error) {
func (f *KeyValuePingFunc) SetDefaultHook(hook func(context.Context) error) {
f.defaultHook = hook
}
@ -2379,7 +2391,7 @@ func (f *KeyValuePingFunc) SetDefaultHook(hook func() error) {
// Ping method of the parent MockKeyValue instance invokes the hook at the
// front of the queue and discards it. After the queue is empty, the default
// hook function is invoked for any future action.
func (f *KeyValuePingFunc) PushHook(hook func() error) {
func (f *KeyValuePingFunc) PushHook(hook func(context.Context) error) {
f.mutex.Lock()
f.hooks = append(f.hooks, hook)
f.mutex.Unlock()
@ -2388,19 +2400,19 @@ func (f *KeyValuePingFunc) PushHook(hook func() error) {
// SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values.
func (f *KeyValuePingFunc) SetDefaultReturn(r0 error) {
f.SetDefaultHook(func() error {
f.SetDefaultHook(func(context.Context) error {
return r0
})
}
// PushReturn calls PushHook with a function that returns the given values.
func (f *KeyValuePingFunc) PushReturn(r0 error) {
f.PushHook(func() error {
f.PushHook(func(context.Context) error {
return r0
})
}
func (f *KeyValuePingFunc) nextHook() func() error {
func (f *KeyValuePingFunc) nextHook() func(context.Context) error {
f.mutex.Lock()
defer f.mutex.Unlock()
@ -2433,6 +2445,9 @@ func (f *KeyValuePingFunc) History() []KeyValuePingFuncCall {
// KeyValuePingFuncCall is an object that describes an invocation of method
// Ping on an instance of MockKeyValue.
type KeyValuePingFuncCall struct {
// Arg0 is the value of the 1st argument passed to this method
// invocation.
Arg0 context.Context
// Result0 is the value of the 1st result returned from this method
// invocation.
Result0 error
@ -2441,7 +2456,7 @@ type KeyValuePingFuncCall struct {
// Args returns an interface slice containing the arguments of this
// invocation.
func (c KeyValuePingFuncCall) Args() []interface{} {
return []interface{}{}
return []interface{}{c.Arg0}
}
// Results returns an interface slice containing the results of this

View File

@ -8,6 +8,8 @@ import (
"testing"
"github.com/sourcegraph/log/logtest"
"github.com/sourcegraph/sourcegraph/internal/tenant"
)
func TestSchemeMatcher(t *testing.T) {
@ -38,11 +40,12 @@ func TestMain(m *testing.M) {
func TestDeleteAllKeysWithPrefix(t *testing.T) {
t.Helper()
ctx := tenant.TestContext()
kv := NewTestKeyValue()
// If we are not on CI, skip the test if our redis connection fails.
if os.Getenv("CI") == "" {
if err := kv.Ping(); err != nil {
if err := kv.Ping(ctx); err != nil {
t.Skip("could not connect to redis", err)
}
}

View File

@ -31,6 +31,7 @@ go_test(
deps = [
":wrexec",
"//internal/rcache",
"//internal/tenant",
"//lib/errors",
"@com_github_google_go_cmp//cmp",
"@com_github_sourcegraph_log//:log",

View File

@ -113,7 +113,7 @@ func (rc *RecordingCmd) WithRedactorFunc(f RedactorFunc) *RecordingCmd {
return rc
}
func (rc *RecordingCmd) after(_ context.Context, logger log.Logger, cmd *exec.Cmd) {
func (rc *RecordingCmd) after(ctx context.Context, logger log.Logger, cmd *exec.Cmd) {
// ensure we don't record ourselves twice if the caller calls Wait() twice for example.
defer func() { rc.done = true }()
if rc.done {
@ -163,7 +163,7 @@ func (rc *RecordingCmd) after(_ context.Context, logger log.Logger, cmd *exec.Cm
return
}
_ = rc.store.Insert(data)
_ = rc.store.Insert(ctx, data)
}
// RecordingCommandFactory stores a ShouldRecord that will be used to create a new RecordingCommand

View File

@ -11,13 +11,14 @@ import (
"github.com/sourcegraph/log/logtest"
"github.com/sourcegraph/sourcegraph/internal/rcache"
"github.com/sourcegraph/sourcegraph/internal/tenant"
"github.com/sourcegraph/sourcegraph/internal/wrexec"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
func listSize(t *testing.T, store *rcache.FIFOList) int {
t.Helper()
size, err := store.Size()
size, err := store.Size(tenant.TestContext())
if err != nil {
t.Fatalf("failed to get size of FIFOList: %s", err)
}