Skip to content

Commit 87ec3f0

Browse files
committed
Add mirror test implementation
- Implement mirror test structure - Add test/common functionality - Create ctl_v3_make_mirror_test Signed-off-by: Ronald Ngounou <ronald.ngounou@yahoo.com> Signed-off-by: ronaldngounou <ronald.ngounou@yahoo.com>
1 parent 1b2ed5a commit 87ec3f0

File tree

11 files changed

+265
-118
lines changed

11 files changed

+265
-118
lines changed

tests/common/e2e_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,19 @@ func WithUnixClient() config.ClusterOption {
122122
func WithTCPClient() config.ClusterOption {
123123
return e2e.WithTCPClient()
124124
}
125+
126+
func WithBasePort(port int) config.ClusterOption {
127+
return e2e.WithBasePort()
128+
}
129+
130+
func configureMirrorDestTLS(mm *config.MakeMirrorOptions, tls config.TLSConfig) {
131+
switch tls {
132+
case config.ManualTLS:
133+
mm.DestCert = e2e.CertPath
134+
mm.DestKey = e2e.PrivateKeyPath
135+
mm.DestCACert = e2e.CaPath
136+
mm.DestInsecureTransport = false
137+
default:
138+
mm.DestInsecureTransport = true
139+
}
140+
}

tests/common/integration_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,17 @@ func WithUnixClient() config.ClusterOption {
6767
func WithTCPClient() config.ClusterOption {
6868
return integration.WithTCPClient()
6969
}
70+
71+
func WithBasePort(port int) config.ClusterOption {
72+
return func(c *config.ClusterConfig) {}
73+
}
74+
75+
func ensureIntegrationClusterContext(c *config.ClusterConfig) *integration.ClusterContext {
76+
ctx, _ := c.ClusterContext.(*integration.ClusterContext)
77+
if ctx == nil {
78+
ctx = &integration.ClusterContext{}
79+
}
80+
return ctx
81+
}
82+
83+
func configureMirrorDestTLS(mm *config.MakeMirrorOptions, _ config.TLSConfig) {}

tests/common/make_mirror_test.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// Copyright 2016 The etcd Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package common
16+
17+
import (
18+
"context"
19+
"fmt"
20+
"testing"
21+
"time"
22+
23+
"github.com/stretchr/testify/require"
24+
25+
"go.etcd.io/etcd/tests/v3/framework/config"
26+
"go.etcd.io/etcd/tests/v3/framework/testutils"
27+
)
28+
29+
func TestMakeMirrorModifyDestPrefix(t *testing.T) {
30+
testRunner.BeforeTest(t)
31+
for _, srcTC := range clusterTestCases() {
32+
for _, destTC := range clusterTestCases() {
33+
t.Run(fmt.Sprintf("Source=%s/Destination=%s", srcTC.name, destTC.name), func(t *testing.T) {
34+
var (
35+
mmOpts = config.MakeMirrorOptions{Prefix: "o_", DestPrefix: "d_"}
36+
sourcekvs = []testutils.KV{{Key: "o_key1", Val: "val1"}, {Key: "o_key2", Val: "val2"}, {Key: "o_key3", Val: "val3"}}
37+
destkvs = []testutils.KV{{Key: "d_key1", Val: "val1"}, {Key: "d_key2", Val: "val2"}, {Key: "d_key3", Val: "val3"}}
38+
srcprefix = "o_"
39+
destprefix = "d_"
40+
)
41+
42+
testMirror(t, srcTC, destTC, mmOpts, sourcekvs, destkvs, srcprefix, destprefix)
43+
})
44+
}
45+
}
46+
}
47+
48+
func TestMakeMirrorNoDestPrefix(t *testing.T) {
49+
testRunner.BeforeTest(t)
50+
for _, srcTC := range clusterTestCases() {
51+
for _, destTC := range clusterTestCases() {
52+
t.Run(fmt.Sprintf("Source=%s/Destination=%s", srcTC.name, destTC.name), func(t *testing.T) {
53+
var (
54+
mmOpts = config.MakeMirrorOptions{Prefix: "o_", NoDestPrefix: true}
55+
sourcekvs = []testutils.KV{{Key: "o_key1", Val: "val1"}, {Key: "o_key2", Val: "val2"}, {Key: "o_key3", Val: "val3"}}
56+
destkvs = []testutils.KV{{Key: "key1", Val: "val1"}, {Key: "key2", Val: "val2"}, {Key: "key3", Val: "val3"}}
57+
srcprefix = "o_"
58+
destprefix = "key"
59+
)
60+
61+
testMirror(t, srcTC, destTC, mmOpts, sourcekvs, destkvs, srcprefix, destprefix)
62+
})
63+
}
64+
}
65+
}
66+
67+
func TestMakeMirror(t *testing.T) {
68+
testRunner.BeforeTest(t)
69+
for _, srcTC := range clusterTestCases() {
70+
for _, destTC := range clusterTestCases() {
71+
t.Run(fmt.Sprintf("Source=%s/Destination=%s", srcTC.name, destTC.name), func(t *testing.T) {
72+
var (
73+
mmOpts config.MakeMirrorOptions
74+
sourcekvs = []testutils.KV{{Key: "key1", Val: "val1"}, {Key: "key2", Val: "val2"}, {Key: "key3", Val: "val3"}}
75+
destkvs = []testutils.KV{{Key: "key1", Val: "val1"}, {Key: "key2", Val: "val2"}, {Key: "key3", Val: "val3"}}
76+
prefix = "key"
77+
)
78+
79+
testMirror(t, srcTC, destTC, mmOpts, sourcekvs, destkvs, prefix, prefix)
80+
})
81+
}
82+
}
83+
}
84+
85+
func TestMakeMirrorWithWatchRev(t *testing.T) {
86+
testRunner.BeforeTest(t)
87+
for _, srcTC := range clusterTestCases() {
88+
for _, destTC := range clusterTestCases() {
89+
t.Run(fmt.Sprintf("Source=%s/Destination=%s", srcTC.name, destTC.name), func(t *testing.T) {
90+
var (
91+
mmOpts = config.MakeMirrorOptions{Prefix: "o_", NoDestPrefix: true, Rev: 4}
92+
sourcekvs = []testutils.KV{{Key: "o_key1", Val: "val1"}, {Key: "o_key2", Val: "val2"}, {Key: "o_key3", Val: "val3"}, {Key: "o_key4", Val: "val4"}}
93+
destkvs = []testutils.KV{{Key: "key3", Val: "val3"}, {Key: "key4", Val: "val4"}}
94+
srcprefix = "o_"
95+
destprefix = "key"
96+
)
97+
98+
testMirror(t, srcTC, destTC, mmOpts, sourcekvs, destkvs, srcprefix, destprefix)
99+
})
100+
}
101+
}
102+
}
103+
104+
func testMirror(t *testing.T, srcTC, destTC testCase, mmOpts config.MakeMirrorOptions, sourcekvs, destkvs []testutils.KV, srcprefix, destprefix string) {
105+
t.Helper()
106+
107+
if destTC.config.ClientTLS == config.AutoTLS {
108+
t.Skip("Skipping: destingation uses Client AutoTLS, but the test cannot expose the dest CA for etcdctl (--dest-cacert); tLS verification would fail.")
109+
}
110+
111+
ctx, cancel := context.WithTimeout(t.Context(), 30*time.Second)
112+
defer cancel()
113+
// Source cluster
114+
src := testRunner.NewCluster(ctx, t, config.WithClusterConfig(srcTC.config))
115+
defer src.Close()
116+
srcClient := testutils.MustClient(src.Client())
117+
118+
// Destination cluster
119+
destCfg := destTC.config
120+
dest := testRunner.NewCluster(ctx, t, config.WithClusterConfig(destTC.config), WithBasePort(10000)) // destTC.BasePort
121+
defer dest.Close()
122+
destClient := testutils.MustClient(dest.Client())
123+
124+
// Configure TLS for destination before starting make-mirror
125+
configureMirrorDestTLS(&mmOpts, destCfg.ClientTLS)
126+
127+
// Start make mirror
128+
errCh := make(chan error)
129+
go func(opts config.MakeMirrorOptions) {
130+
errCh <- srcClient.MakeMirror(ctx, dest.Endpoints()[0], opts)
131+
}(mmOpts)
132+
defer func() {
133+
// Need to cancel the context to ensure the MakeMirror goroutine is cancelled before catching the error.
134+
cancel()
135+
require.NoError(t, <-errCh)
136+
}()
137+
138+
// Write to source
139+
for i := range sourcekvs {
140+
require.NoError(t, srcClient.Put(ctx, sourcekvs[i].Key, sourcekvs[i].Val, config.PutOptions{}))
141+
}
142+
143+
// Source assertion
144+
srcResp, err := srcClient.Get(ctx, srcprefix, config.GetOptions{Prefix: true})
145+
require.NoError(t, err)
146+
require.Equal(t, sourcekvs, testutils.KeyValuesFromGetResponse(srcResp))
147+
148+
// Destination assertion
149+
wCtx, wCancel := context.WithCancel(ctx)
150+
defer wCancel()
151+
152+
watchChan := destClient.Watch(wCtx, destprefix, config.WatchOptions{Prefix: true, Revision: 1})
153+
154+
// Compare the result of what we obtained using the make-mirror command versus what we had using
155+
// the Watch command
156+
destResp, err := testutils.KeyValuesFromWatchChan(watchChan, len(destkvs), 10*time.Second)
157+
require.NoError(t, err)
158+
require.Equal(t, destkvs, destResp)
159+
}

tests/common/unit_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,9 @@ func WithTCPClient() config.ClusterOption {
5656
func WithUnixClient() config.ClusterOption {
5757
return func(c *config.ClusterConfig) {}
5858
}
59+
60+
func WithBasePort(port int) config.ClusterOption {
61+
return func(c *config.ClusterConfig) {}
62+
}
63+
64+
func configureMirrorDestTLS(mm *config.MakeMirrorOptions, _ config.TLSConfig) {}

tests/e2e/ctl_v3_make_mirror_test.go

Lines changed: 0 additions & 115 deletions
This file was deleted.

tests/framework/config/client.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,14 @@ type WatchOptions struct {
7777
Revision int64
7878
RangeEnd string
7979
}
80+
81+
type MakeMirrorOptions struct {
82+
Prefix string
83+
Rev int64
84+
DestPrefix string
85+
NoDestPrefix bool
86+
DestCACert string
87+
DestCert string
88+
DestKey string
89+
DestInsecureTransport bool
90+
}

tests/framework/e2e/config.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ func (cv ClusterVersion) String() string {
4141
}
4242

4343
type ClusterContext struct {
44-
Version ClusterVersion
45-
EnvVars map[string]string
46-
UseUnix bool
44+
Version ClusterVersion
45+
EnvVars map[string]string
46+
UseUnix bool
47+
BasePort int
4748
}
4849

4950
func WithHTTP2Debug() config.ClusterOption {

tests/framework/e2e/e2e.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ func (e e2eRunner) NewCluster(ctx context.Context, tb testing.TB, opts ...config
6666
if ctx.UseUnix {
6767
e2eConfig.BaseClientScheme = "unix"
6868
}
69+
if ctx.BasePort != 0 {
70+
e2eConfig.BasePort = ctx.BasePort
71+
}
6972
}
7073

7174
switch cfg.ClientTLS {

0 commit comments

Comments
 (0)