-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathredis_feature.go
More file actions
116 lines (94 loc) · 3 KB
/
redis_feature.go
File metadata and controls
116 lines (94 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package componenttest
import (
"context"
"fmt"
"strings"
"time"
"github.com/redis/go-redis/v9"
"github.com/cucumber/godog"
testRedis "github.com/testcontainers/testcontainers-go/modules/redis"
)
// RedisFeature is a struct containing a testcontainer redis database
type RedisFeature struct {
Server *testRedis.RedisContainer
Client *redis.Client
}
type RedisOptions struct {
RedisVersion string
}
// NewRedisFeature creates a new testcontainer redis database using the supplied options
func NewRedisFeature(opts RedisOptions) *RedisFeature {
ctx := context.Background()
s, err := testRedis.Run(ctx, fmt.Sprintf("redis:%s", opts.RedisVersion))
if err != nil {
panic(err)
}
err = s.Start(ctx)
if err != nil {
panic(err)
}
connectionString, err := s.ConnectionString(ctx)
if err != nil {
panic(err)
}
client := redis.NewClient(&redis.Options{
Addr: strings.ReplaceAll(connectionString, "redis://", ""),
})
return &RedisFeature{
Server: s,
Client: client,
}
}
// Reset drops all keys from the testcontainer redis
func (r *RedisFeature) Reset() error {
return r.Client.FlushAll(context.Background()).Err()
}
// Close stops the testcontainer redis
func (r *RedisFeature) Close() error {
return r.Server.Terminate(context.Background())
}
func (r *RedisFeature) RegisterSteps(ctx *godog.ScenarioContext) {
ctx.Step(`^the key "([^"]*)" is already set to a value of "([^"]*)" in the Redis store$`, r.theKeyIsAlreadySetToAValueOfInTheRedisStore)
ctx.Step(`^the key "([^"]*)" has a value of "([^"]*)" in the Redis store$`, r.theKeyHasAValueOfInTheRedisStore)
ctx.Step(`^redis contains no value for key "([^"]*)"$`, r.redisContainsNoValueFor)
ctx.Step(`^redis is healthy$`, r.redisIsHealthy)
ctx.Step(`^redis stops running$`, r.redisStopsRunning)
}
func (r *RedisFeature) theKeyIsAlreadySetToAValueOfInTheRedisStore(key, value string) error {
return r.Client.Set(context.Background(), key, value, 0).Err()
}
func (r *RedisFeature) theKeyHasAValueOfInTheRedisStore(key, expected string) error {
actual, err := r.Client.Get(context.Background(), key).Result()
if err != nil {
return fmt.Errorf("failed to get key %q from Redis: %w", key, err)
}
if actual != expected {
return fmt.Errorf("unexpected value for key %q: got %q, want %q", key, actual, expected)
}
return nil
}
func (r *RedisFeature) redisContainsNoValueFor(key string) error {
ctx := context.Background()
exists, err := r.Client.Exists(ctx, key).Result()
if err != nil {
return fmt.Errorf("error checking existence of key %q", key)
}
if exists == 1 {
val, err := r.Client.Get(ctx, key).Result()
if err != nil {
return fmt.Errorf("error getting value of key %q", key)
}
return fmt.Errorf("expected no value for key %q, but found %q", key, val)
}
return nil
}
func (r *RedisFeature) redisIsHealthy() error {
return r.Client.Ping(context.Background()).Err()
}
func (r *RedisFeature) redisStopsRunning() error {
if r.Server != nil {
timeout := time.Second * 1
return r.Server.Stop(context.Background(), &timeout)
}
return nil
}