wal-g
165 строк · 4.3 Кб
1package functests
2
3import (
4"fmt"
5"time"
6
7"github.com/cucumber/godog"
8"github.com/pkg/errors"
9"github.com/wal-g/tracelog"
10"github.com/wal-g/wal-g/tests_func/helpers"
11"github.com/wal-g/wal-g/tests_func/utils"
12)
13
14func SetupRedisSteps(ctx *godog.ScenarioContext, tctx *TestContext) {
15ctx.Step(`^a working redis on ([^\s]*)$`, tctx.isWorkingRedis)
16ctx.Step(`^([^\s]*) has test redis data test(\d+)$`, tctx.redisHasTestRedisDataTest)
17ctx.Step(`^we create ([^\s]*) redis-backup$`, tctx.createRedisBackup)
18ctx.Step(`^we delete redis backups retain (\d+) via ([^\s]*)$`, tctx.weDeleteRedisBackupsRetainViaRedis)
19ctx.Step(`^we restart redis-server at ([^\s]*)$`, tctx.weRestartRedisServerAt)
20ctx.Step(`^we got same redis data at ([^\s]*) ([^\s]*)$`, tctx.testEqualRedisDataAtHosts)
21}
22
23func (tctx *TestContext) isWorkingRedis(hostName string) error {
24redisCtl, err := GetRedisCtlFromTestContext(tctx, hostName)
25if err != nil {
26return err
27}
28
29return helpers.Retry(tctx.Context, MAX_RETRIES_COUNT, func() error {
30tracelog.DebugLogger.Printf("Redis client connect to host '%s'", redisCtl.Addr())
31
32status := redisCtl.Ping()
33err = status.Err()
34if err != nil {
35return fmt.Errorf("Client on ping returned err: %v\n", err)
36}
37if status.Val() != "PONG" {
38return fmt.Errorf("Client on ping does not returned PONG: %v\n", err)
39}
40tracelog.DebugLogger.Printf("Redis: Got PONG on PING from %s", hostName)
41return nil
42})
43}
44
45func (tctx *TestContext) redisHasTestRedisDataTest(host string, testId int) error {
46rc, err := GetRedisCtlFromTestContext(tctx, host)
47if err != nil {
48return err
49}
50
51docsCount := 10
52err = rc.WriteTestData(fmt.Sprintf("test%02d", testId), docsCount)
53if err != nil {
54return err
55}
56return nil
57}
58
59func (tctx *TestContext) createRedisBackup(host string) error {
60rc, err := GetRedisCtlFromTestContext(tctx, host)
61if err != nil {
62return nil
63}
64
65beforeBackupTime, err := helpers.TimeInContainer(tctx.Context, rc.Host())
66if err != nil {
67return err
68}
69
70passed := beforeBackupTime.Sub(tctx.PreviousBackupTime)
71if passed < time.Second {
72cmd := []string{"sleep", "1"}
73if _, err := helpers.RunCommandStrict(tctx.Context, host, cmd); err != nil {
74return err
75}
76}
77
78tracelog.DebugLogger.Println("Push redis backup")
79backupId, err := rc.PushBackup()
80if err != nil {
81return err
82}
83time.Sleep(1 * time.Second)
84tracelog.DebugLogger.Println("Backup created: ", backupId)
85return nil
86}
87
88func (tctx *TestContext) weDeleteRedisBackupsRetainViaRedis(backupsRetain int, host string) error {
89rc, err := GetRedisCtlFromTestContext(tctx, host)
90if err != nil {
91return err
92}
93
94return rc.PurgeRetain(backupsRetain)
95}
96
97func (tctx *TestContext) weRestartRedisServerAt(host string) error {
98rc, err := GetRedisCtlFromTestContext(tctx, host)
99if err != nil {
100return err
101}
102cmd := rc.ShutdownNoSave()
103if cmd.Err() != nil {
104return cmd.Err()
105}
106return nil
107}
108
109func (tctx *TestContext) testEqualRedisDataAtHosts(host1, host2 string) error {
110rc1, err := GetRedisCtlFromTestContext(tctx, host1)
111if err != nil {
112return err
113}
114
115rc2, err := GetRedisCtlFromTestContext(tctx, host2)
116if err != nil {
117return err
118}
119
120dbsize1 := rc1.DBSize()
121if dbsize1.Err() != nil {
122return errors.Wrapf(dbsize1.Err(), "Host %s doesn't return 'dbsize'", host1)
123}
124dbsize2 := rc2.DBSize()
125if dbsize2.Err() != nil {
126return errors.Wrapf(dbsize1.Err(), "Host %s doesn't return 'dbsize'", host2)
127}
128if dbsize1.Val() != dbsize2.Val() {
129return fmt.Errorf("hosts %s and %s have not equal keys count %d != %d", host1, host2, dbsize1.Val(), dbsize2.Val())
130}
131
132keys1 := rc1.Keys("*")
133if keys1.Err() != nil {
134return keys1.Err()
135}
136
137keys2 := rc2.Keys("*")
138if keys2.Err() != nil {
139return keys2.Err()
140}
141
142if len(keys1.Val()) == 0 || len(keys2.Val()) == 0 {
143return fmt.Errorf("keys1 or keys2 is empty - broken backup")
144}
145
146if !utils.IsArraysEqual(keys1.Val(), keys2.Val()) {
147return fmt.Errorf("keys from redis1/redis2 aren't equal")
148}
149values1 := rc1.MGet(keys1.Val()...)
150values2 := rc1.MGet(keys2.Val()...)
151vals1 := make([]string, len(values1.Val()))
152vals2 := make([]string, len(values1.Val()))
153
154for i, val := range values1.Val() {
155vals1[i] = val.(string)
156}
157
158for i, val := range values2.Val() {
159vals2[i] = val.(string)
160}
161if !utils.IsArraysEqual(vals1, vals2) {
162return fmt.Errorf("values from redis1/redis2 aren't equal")
163}
164return nil
165}
166