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
15package e2e
16
17import (
18	"fmt"
19	"testing"
20	"time"
21)
22
23func TestCtlV3MakeMirror(t *testing.T)                 { testCtl(t, makeMirrorTest) }
24func TestCtlV3MakeMirrorModifyDestPrefix(t *testing.T) { testCtl(t, makeMirrorModifyDestPrefixTest) }
25func TestCtlV3MakeMirrorNoDestPrefix(t *testing.T)     { testCtl(t, makeMirrorNoDestPrefixTest) }
26
27func makeMirrorTest(cx ctlCtx) {
28	var (
29		flags  = []string{}
30		kvs    = []kv{{"key1", "val1"}, {"key2", "val2"}, {"key3", "val3"}}
31		kvs2   = []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}, {key: "key3", val: "val3"}}
32		prefix = "key"
33	)
34	testMirrorCommand(cx, flags, kvs, kvs2, prefix, prefix)
35}
36
37func makeMirrorModifyDestPrefixTest(cx ctlCtx) {
38	var (
39		flags      = []string{"--prefix", "o_", "--dest-prefix", "d_"}
40		kvs        = []kv{{"o_key1", "val1"}, {"o_key2", "val2"}, {"o_key3", "val3"}}
41		kvs2       = []kvExec{{key: "d_key1", val: "val1"}, {key: "d_key2", val: "val2"}, {key: "d_key3", val: "val3"}}
42		srcprefix  = "o_"
43		destprefix = "d_"
44	)
45	testMirrorCommand(cx, flags, kvs, kvs2, srcprefix, destprefix)
46}
47
48func makeMirrorNoDestPrefixTest(cx ctlCtx) {
49	var (
50		flags      = []string{"--prefix", "o_", "--no-dest-prefix"}
51		kvs        = []kv{{"o_key1", "val1"}, {"o_key2", "val2"}, {"o_key3", "val3"}}
52		kvs2       = []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}, {key: "key3", val: "val3"}}
53		srcprefix  = "o_"
54		destprefix = "key"
55	)
56
57	testMirrorCommand(cx, flags, kvs, kvs2, srcprefix, destprefix)
58}
59
60func testMirrorCommand(cx ctlCtx, flags []string, sourcekvs []kv, destkvs []kvExec, srcprefix, destprefix string) {
61	// set up another cluster to mirror with
62	mirrorcfg := configAutoTLS
63	mirrorcfg.clusterSize = 1
64	mirrorcfg.basePort = 10000
65	mirrorctx := ctlCtx{
66		t:           cx.t,
67		cfg:         mirrorcfg,
68		dialTimeout: 7 * time.Second,
69	}
70
71	mirrorepc, err := newEtcdProcessCluster(&mirrorctx.cfg)
72	if err != nil {
73		cx.t.Fatalf("could not start etcd process cluster (%v)", err)
74	}
75	mirrorctx.epc = mirrorepc
76
77	defer func() {
78		if err = mirrorctx.epc.Close(); err != nil {
79			cx.t.Fatalf("error closing etcd processes (%v)", err)
80		}
81	}()
82
83	cmdArgs := append(cx.PrefixArgs(), "make-mirror")
84	cmdArgs = append(cmdArgs, flags...)
85	cmdArgs = append(cmdArgs, fmt.Sprintf("localhost:%d", mirrorcfg.basePort))
86	proc, err := spawnCmd(cmdArgs)
87	if err != nil {
88		cx.t.Fatal(err)
89	}
90	defer func() {
91		err = proc.Stop()
92		if err != nil {
93			cx.t.Fatal(err)
94		}
95	}()
96
97	for i := range sourcekvs {
98		if err = ctlV3Put(cx, sourcekvs[i].key, sourcekvs[i].val, ""); err != nil {
99			cx.t.Fatal(err)
100		}
101	}
102	if err = ctlV3Get(cx, []string{srcprefix, "--prefix"}, sourcekvs...); err != nil {
103		cx.t.Fatal(err)
104	}
105
106	if err = ctlV3Watch(mirrorctx, []string{destprefix, "--rev", "1", "--prefix"}, destkvs...); err != nil {
107		cx.t.Fatal(err)
108	}
109}
110