| // Copyright 2018 The etcd Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| // +build !cov |
| |
| package e2e |
| |
| import ( |
| "os" |
| "testing" |
| ) |
| |
| func TestCtlV3Watch(t *testing.T) { testCtl(t, watchTest) } |
| func TestCtlV3WatchNoTLS(t *testing.T) { testCtl(t, watchTest, withCfg(configNoTLS)) } |
| func TestCtlV3WatchClientTLS(t *testing.T) { testCtl(t, watchTest, withCfg(configClientTLS)) } |
| func TestCtlV3WatchPeerTLS(t *testing.T) { testCtl(t, watchTest, withCfg(configPeerTLS)) } |
| func TestCtlV3WatchTimeout(t *testing.T) { testCtl(t, watchTest, withDialTimeout(0)) } |
| |
| func TestCtlV3WatchInteractive(t *testing.T) { |
| testCtl(t, watchTest, withInteractive()) |
| } |
| func TestCtlV3WatchInteractiveNoTLS(t *testing.T) { |
| testCtl(t, watchTest, withInteractive(), withCfg(configNoTLS)) |
| } |
| func TestCtlV3WatchInteractiveClientTLS(t *testing.T) { |
| testCtl(t, watchTest, withInteractive(), withCfg(configClientTLS)) |
| } |
| func TestCtlV3WatchInteractivePeerTLS(t *testing.T) { |
| testCtl(t, watchTest, withInteractive(), withCfg(configPeerTLS)) |
| } |
| |
| func watchTest(cx ctlCtx) { |
| tests := []struct { |
| puts []kv |
| envKey string |
| envRange string |
| args []string |
| |
| wkv []kvExec |
| }{ |
| { // watch 1 key |
| puts: []kv{{"sample", "value"}}, |
| args: []string{"sample", "--rev", "1"}, |
| wkv: []kvExec{{key: "sample", val: "value"}}, |
| }, |
| { // watch 1 key with env |
| puts: []kv{{"sample", "value"}}, |
| envKey: "sample", |
| args: []string{"--rev", "1"}, |
| wkv: []kvExec{{key: "sample", val: "value"}}, |
| }, |
| { // watch 1 key with ${ETCD_WATCH_VALUE} |
| puts: []kv{{"sample", "value"}}, |
| args: []string{"sample", "--rev", "1", "--", "env"}, |
| wkv: []kvExec{{key: "sample", val: "value", execOutput: `ETCD_WATCH_VALUE="value"`}}, |
| }, |
| { // watch 1 key with "echo watch event received", with env |
| puts: []kv{{"sample", "value"}}, |
| envKey: "sample", |
| args: []string{"--rev", "1", "--", "echo", "watch event received"}, |
| wkv: []kvExec{{key: "sample", val: "value", execOutput: "watch event received"}}, |
| }, |
| { // watch 1 key with "echo watch event received" |
| puts: []kv{{"sample", "value"}}, |
| args: []string{"--rev", "1", "sample", "--", "echo", "watch event received"}, |
| wkv: []kvExec{{key: "sample", val: "value", execOutput: "watch event received"}}, |
| }, |
| { // watch 1 key with "echo \"Hello World!\"" |
| puts: []kv{{"sample", "value"}}, |
| args: []string{"--rev", "1", "sample", "--", "echo", "\"Hello World!\""}, |
| wkv: []kvExec{{key: "sample", val: "value", execOutput: "Hello World!"}}, |
| }, |
| { // watch 1 key with "echo watch event received" |
| puts: []kv{{"sample", "value"}}, |
| args: []string{"sample", "samplx", "--rev", "1", "--", "echo", "watch event received"}, |
| wkv: []kvExec{{key: "sample", val: "value", execOutput: "watch event received"}}, |
| }, |
| { // watch 1 key with "echo watch event received" |
| puts: []kv{{"sample", "value"}}, |
| envKey: "sample", |
| envRange: "samplx", |
| args: []string{"--rev", "1", "--", "echo", "watch event received"}, |
| wkv: []kvExec{{key: "sample", val: "value", execOutput: "watch event received"}}, |
| }, |
| { // watch 1 key with "echo watch event received" |
| puts: []kv{{"sample", "value"}}, |
| args: []string{"sample", "--rev", "1", "samplx", "--", "echo", "watch event received"}, |
| wkv: []kvExec{{key: "sample", val: "value", execOutput: "watch event received"}}, |
| }, |
| { // watch 3 keys by prefix |
| puts: []kv{{"key1", "val1"}, {"key2", "val2"}, {"key3", "val3"}}, |
| args: []string{"key", "--rev", "1", "--prefix"}, |
| wkv: []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}, {key: "key3", val: "val3"}}, |
| }, |
| { // watch 3 keys by prefix, with env |
| puts: []kv{{"key1", "val1"}, {"key2", "val2"}, {"key3", "val3"}}, |
| envKey: "key", |
| args: []string{"--rev", "1", "--prefix"}, |
| wkv: []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}, {key: "key3", val: "val3"}}, |
| }, |
| { // watch by revision |
| puts: []kv{{"etcd", "revision_1"}, {"etcd", "revision_2"}, {"etcd", "revision_3"}}, |
| args: []string{"etcd", "--rev", "2"}, |
| wkv: []kvExec{{key: "etcd", val: "revision_2"}, {key: "etcd", val: "revision_3"}}, |
| }, |
| { // watch 3 keys by range |
| puts: []kv{{"key1", "val1"}, {"key3", "val3"}, {"key2", "val2"}}, |
| args: []string{"key", "key3", "--rev", "1"}, |
| wkv: []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}}, |
| }, |
| { // watch 3 keys by range, with env |
| puts: []kv{{"key1", "val1"}, {"key3", "val3"}, {"key2", "val2"}}, |
| envKey: "key", |
| envRange: "key3", |
| args: []string{"--rev", "1"}, |
| wkv: []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}}, |
| }, |
| } |
| |
| for i, tt := range tests { |
| donec := make(chan struct{}) |
| go func(i int, puts []kv) { |
| for j := range puts { |
| if err := ctlV3Put(cx, puts[j].key, puts[j].val, ""); err != nil { |
| cx.t.Fatalf("watchTest #%d-%d: ctlV3Put error (%v)", i, j, err) |
| } |
| } |
| close(donec) |
| }(i, tt.puts) |
| |
| unsetEnv := func() {} |
| if tt.envKey != "" || tt.envRange != "" { |
| if tt.envKey != "" { |
| os.Setenv("ETCDCTL_WATCH_KEY", tt.envKey) |
| unsetEnv = func() { os.Unsetenv("ETCDCTL_WATCH_KEY") } |
| } |
| if tt.envRange != "" { |
| os.Setenv("ETCDCTL_WATCH_RANGE_END", tt.envRange) |
| unsetEnv = func() { os.Unsetenv("ETCDCTL_WATCH_RANGE_END") } |
| } |
| if tt.envKey != "" && tt.envRange != "" { |
| unsetEnv = func() { |
| os.Unsetenv("ETCDCTL_WATCH_KEY") |
| os.Unsetenv("ETCDCTL_WATCH_RANGE_END") |
| } |
| } |
| } |
| if err := ctlV3Watch(cx, tt.args, tt.wkv...); err != nil { |
| if cx.dialTimeout > 0 && !isGRPCTimedout(err) { |
| cx.t.Errorf("watchTest #%d: ctlV3Watch error (%v)", i, err) |
| } |
| } |
| unsetEnv() |
| <-donec |
| } |
| } |