From aaca01a0faa5d3dd002f466412ff1469c4167296 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Thu, 3 May 2018 17:21:48 -0700 Subject: [PATCH] tests/e2e: separate coverage tests for exec commands Signed-off-by: Gyuho Lee --- e2e/ctl_v3_watch_test.go | 158 +----------------------- tests/e2e/ctl_v3_watch_cov_test.go | 134 +++++++++++++++++++++ tests/e2e/ctl_v3_watch_no_cov_test.go | 167 ++++++++++++++++++++++++++ 3 files changed, 303 insertions(+), 156 deletions(-) create mode 100644 tests/e2e/ctl_v3_watch_cov_test.go create mode 100644 tests/e2e/ctl_v3_watch_no_cov_test.go diff --git a/e2e/ctl_v3_watch_test.go b/e2e/ctl_v3_watch_test.go index dbc2f081c..fe25da1b7 100644 --- a/e2e/ctl_v3_watch_test.go +++ b/e2e/ctl_v3_watch_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 The etcd Authors +// 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. @@ -14,167 +14,13 @@ package e2e -import ( - "os" - "strings" - "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)) -} +import "strings" type kvExec struct { key, val string execOutput string } -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 "echo watch event received" - puts: []kv{{"sample", "value"}}, - args: []string{"sample", "--rev", "1", "--", "echo", "watch event received"}, - wkv: []kvExec{{key: "sample", val: "value", execOutput: "watch event received"}}, - }, - { // 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 - } -} - func setupWatchArgs(cx ctlCtx, args []string) []string { cmdArgs := append(cx.PrefixArgs(), "watch") if cx.interactive { diff --git a/tests/e2e/ctl_v3_watch_cov_test.go b/tests/e2e/ctl_v3_watch_cov_test.go new file mode 100644 index 000000000..77f045063 --- /dev/null +++ b/tests/e2e/ctl_v3_watch_cov_test.go @@ -0,0 +1,134 @@ +// 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"}}, + }, + + // coverage tests get extra arguments: + // ./bin/etcdctl_test -test.coverprofile=e2e.1525392462795198897.coverprofile -test.outputdir=../.. + // do not test watch exec commands + + { // 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 + } +} diff --git a/tests/e2e/ctl_v3_watch_no_cov_test.go b/tests/e2e/ctl_v3_watch_no_cov_test.go new file mode 100644 index 000000000..6dffeee3f --- /dev/null +++ b/tests/e2e/ctl_v3_watch_no_cov_test.go @@ -0,0 +1,167 @@ +// 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 + } +}