1// Copyright 2018 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// +build cov 16 17package e2e 18 19import ( 20 "os" 21 "testing" 22) 23 24func TestCtlV3Watch(t *testing.T) { testCtl(t, watchTest) } 25func TestCtlV3WatchNoTLS(t *testing.T) { testCtl(t, watchTest, withCfg(configNoTLS)) } 26func TestCtlV3WatchClientTLS(t *testing.T) { testCtl(t, watchTest, withCfg(configClientTLS)) } 27func TestCtlV3WatchPeerTLS(t *testing.T) { testCtl(t, watchTest, withCfg(configPeerTLS)) } 28func TestCtlV3WatchTimeout(t *testing.T) { testCtl(t, watchTest, withDialTimeout(0)) } 29 30func TestCtlV3WatchInteractive(t *testing.T) { 31 testCtl(t, watchTest, withInteractive()) 32} 33func TestCtlV3WatchInteractiveNoTLS(t *testing.T) { 34 testCtl(t, watchTest, withInteractive(), withCfg(configNoTLS)) 35} 36func TestCtlV3WatchInteractiveClientTLS(t *testing.T) { 37 testCtl(t, watchTest, withInteractive(), withCfg(configClientTLS)) 38} 39func TestCtlV3WatchInteractivePeerTLS(t *testing.T) { 40 testCtl(t, watchTest, withInteractive(), withCfg(configPeerTLS)) 41} 42 43func watchTest(cx ctlCtx) { 44 tests := []struct { 45 puts []kv 46 envKey string 47 envRange string 48 args []string 49 50 wkv []kvExec 51 }{ 52 { // watch 1 key 53 puts: []kv{{"sample", "value"}}, 54 args: []string{"sample", "--rev", "1"}, 55 wkv: []kvExec{{key: "sample", val: "value"}}, 56 }, 57 { // watch 1 key with env 58 puts: []kv{{"sample", "value"}}, 59 envKey: "sample", 60 args: []string{"--rev", "1"}, 61 wkv: []kvExec{{key: "sample", val: "value"}}, 62 }, 63 64 // coverage tests get extra arguments: 65 // ./bin/etcdctl_test -test.coverprofile=e2e.1525392462795198897.coverprofile -test.outputdir=../.. 66 // do not test watch exec commands 67 68 { // watch 3 keys by prefix 69 puts: []kv{{"key1", "val1"}, {"key2", "val2"}, {"key3", "val3"}}, 70 args: []string{"key", "--rev", "1", "--prefix"}, 71 wkv: []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}, {key: "key3", val: "val3"}}, 72 }, 73 { // watch 3 keys by prefix, with env 74 puts: []kv{{"key1", "val1"}, {"key2", "val2"}, {"key3", "val3"}}, 75 envKey: "key", 76 args: []string{"--rev", "1", "--prefix"}, 77 wkv: []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}, {key: "key3", val: "val3"}}, 78 }, 79 { // watch by revision 80 puts: []kv{{"etcd", "revision_1"}, {"etcd", "revision_2"}, {"etcd", "revision_3"}}, 81 args: []string{"etcd", "--rev", "2"}, 82 wkv: []kvExec{{key: "etcd", val: "revision_2"}, {key: "etcd", val: "revision_3"}}, 83 }, 84 { // watch 3 keys by range 85 puts: []kv{{"key1", "val1"}, {"key3", "val3"}, {"key2", "val2"}}, 86 args: []string{"key", "key3", "--rev", "1"}, 87 wkv: []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}}, 88 }, 89 { // watch 3 keys by range, with env 90 puts: []kv{{"key1", "val1"}, {"key3", "val3"}, {"key2", "val2"}}, 91 envKey: "key", 92 envRange: "key3", 93 args: []string{"--rev", "1"}, 94 wkv: []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}}, 95 }, 96 } 97 98 for i, tt := range tests { 99 donec := make(chan struct{}) 100 go func(i int, puts []kv) { 101 for j := range puts { 102 if err := ctlV3Put(cx, puts[j].key, puts[j].val, ""); err != nil { 103 cx.t.Fatalf("watchTest #%d-%d: ctlV3Put error (%v)", i, j, err) 104 } 105 } 106 close(donec) 107 }(i, tt.puts) 108 109 unsetEnv := func() {} 110 if tt.envKey != "" || tt.envRange != "" { 111 if tt.envKey != "" { 112 os.Setenv("ETCDCTL_WATCH_KEY", tt.envKey) 113 unsetEnv = func() { os.Unsetenv("ETCDCTL_WATCH_KEY") } 114 } 115 if tt.envRange != "" { 116 os.Setenv("ETCDCTL_WATCH_RANGE_END", tt.envRange) 117 unsetEnv = func() { os.Unsetenv("ETCDCTL_WATCH_RANGE_END") } 118 } 119 if tt.envKey != "" && tt.envRange != "" { 120 unsetEnv = func() { 121 os.Unsetenv("ETCDCTL_WATCH_KEY") 122 os.Unsetenv("ETCDCTL_WATCH_RANGE_END") 123 } 124 } 125 } 126 if err := ctlV3Watch(cx, tt.args, tt.wkv...); err != nil { 127 if cx.dialTimeout > 0 && !isGRPCTimedout(err) { 128 cx.t.Errorf("watchTest #%d: ctlV3Watch error (%v)", i, err) 129 } 130 } 131 unsetEnv() 132 <-donec 133 } 134} 135