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 "os" 20 "testing" 21 "time" 22 23 "golang.org/x/net/context" 24 25 "github.com/coreos/etcd/clientv3" 26 "github.com/coreos/etcd/pkg/testutil" 27) 28 29func TestCtlV3Migrate(t *testing.T) { 30 defer testutil.AfterTest(t) 31 32 epc := setupEtcdctlTest(t, &configNoTLS, false) 33 defer func() { 34 if errC := epc.Close(); errC != nil { 35 t.Fatalf("error closing etcd processes (%v)", errC) 36 } 37 }() 38 39 keys := make([]string, 3) 40 vals := make([]string, 3) 41 for i := range keys { 42 keys[i] = fmt.Sprintf("foo_%d", i) 43 vals[i] = fmt.Sprintf("bar_%d", i) 44 } 45 for i := range keys { 46 if err := etcdctlSet(epc, keys[i], vals[i]); err != nil { 47 t.Fatal(err) 48 } 49 } 50 51 dataDir := epc.procs[0].cfg.dataDirPath 52 if err := epc.StopAll(); err != nil { 53 t.Fatalf("error closing etcd processes (%v)", err) 54 } 55 56 os.Setenv("ETCDCTL_API", "3") 57 defer os.Unsetenv("ETCDCTL_API") 58 cx := ctlCtx{ 59 t: t, 60 cfg: configNoTLS, 61 dialTimeout: 7 * time.Second, 62 epc: epc, 63 } 64 if err := ctlV3Migrate(cx, dataDir, ""); err != nil { 65 t.Fatal(err) 66 } 67 68 epc.procs[0].cfg.keepDataDir = true 69 if err := epc.RestartAll(); err != nil { 70 t.Fatal(err) 71 } 72 73 // to ensure revision increment is continuous from migrated v2 data 74 if err := ctlV3Put(cx, "test", "value", ""); err != nil { 75 t.Fatal(err) 76 } 77 cli, err := clientv3.New(clientv3.Config{ 78 Endpoints: epc.grpcEndpoints(), 79 DialTimeout: 3 * time.Second, 80 }) 81 if err != nil { 82 t.Fatal(err) 83 } 84 defer cli.Close() 85 resp, err := cli.Get(context.TODO(), "test") 86 if err != nil { 87 t.Fatal(err) 88 } 89 if len(resp.Kvs) != 1 { 90 t.Fatalf("len(resp.Kvs) expected 1, got %+v", resp.Kvs) 91 } 92 if resp.Kvs[0].CreateRevision != 7 { 93 t.Fatalf("resp.Kvs[0].CreateRevision expected 7, got %d", resp.Kvs[0].CreateRevision) 94 } 95} 96 97func ctlV3Migrate(cx ctlCtx, dataDir, walDir string) error { 98 cmdArgs := append(cx.PrefixArgs(), "migrate", "--data-dir", dataDir, "--wal-dir", walDir) 99 return spawnWithExpects(cmdArgs, "finished transforming keys") 100} 101