From 5ddabfdb2498af0c98bb5cdfbae696e93a77924d Mon Sep 17 00:00:00 2001 From: Piotr Tabor Date: Sun, 7 Mar 2021 14:16:37 +0100 Subject: [PATCH] tests: Make tests operate in /tmp director instead of src. Thanks to this, unix sockets should be not longer created by integration tests in the the source code directory, so potentially trigger IDE reloads and unnecessery load (and mess). --- pkg/testutil/leak.go | 4 ++ .../clientv3/connectivity/dial_test.go | 12 +++--- .../clientv3/snapshot/v3_snapshot_test.go | 6 +-- tests/integration/cluster.go | 37 ++++++++++--------- tests/integration/embed/embed_test.go | 15 +++----- tests/integration/member_test.go | 3 +- tests/integration/snapshot/member_test.go | 2 +- .../integration/snapshot/v3_snapshot_test.go | 19 +++++----- tests/integration/testing.go | 20 ++++++++++ tests/integration/v2store/store_v2v3_test.go | 2 +- tests/integration/v3_election_test.go | 6 +++ tests/integration/v3_grpc_test.go | 10 ++--- tests/integration/v3_kv_test.go | 31 ++-------------- 13 files changed, 84 insertions(+), 83 deletions(-) diff --git a/pkg/testutil/leak.go b/pkg/testutil/leak.go index 828717072..524e8b25f 100644 --- a/pkg/testutil/leak.go +++ b/pkg/testutil/leak.go @@ -97,6 +97,10 @@ func CheckAfterTest(d time.Duration) error { // BeforeTest is a convenient way to register before-and-after code to a test. // If you execute BeforeTest, you don't need to explicitly register AfterTest. func BeforeTest(t testing.TB) { + if err := CheckAfterTest(10 * time.Millisecond); err != nil { + t.Skipf("Found leaked goroutined BEFORE test", err) + return + } t.Cleanup(func() { AfterTest(t) }) diff --git a/tests/integration/clientv3/connectivity/dial_test.go b/tests/integration/clientv3/connectivity/dial_test.go index 483b97709..6a645aba0 100644 --- a/tests/integration/clientv3/connectivity/dial_test.go +++ b/tests/integration/clientv3/connectivity/dial_test.go @@ -31,16 +31,16 @@ import ( var ( testTLSInfo = transport.TLSInfo{ - KeyFile: "../../../fixtures/server.key.insecure", - CertFile: "../../../fixtures/server.crt", - TrustedCAFile: "../../../fixtures/ca.crt", + KeyFile: integration.MustAbsPath("../../../fixtures/server.key.insecure"), + CertFile: integration.MustAbsPath("../../../fixtures/server.crt"), + TrustedCAFile: integration.MustAbsPath("../../../fixtures/ca.crt"), ClientCertAuth: true, } testTLSInfoExpired = transport.TLSInfo{ - KeyFile: "../../fixtures-expired/server.key.insecure", - CertFile: "../../fixtures-expired/server.crt", - TrustedCAFile: "../../fixtures-expired/ca.crt", + KeyFile: integration.MustAbsPath("../../fixtures-expired/server.key.insecure"), + CertFile: integration.MustAbsPath("../../fixtures-expired/server.crt"), + TrustedCAFile: integration.MustAbsPath("../../fixtures-expired/ca.crt"), ClientCertAuth: true, } ) diff --git a/tests/integration/clientv3/snapshot/v3_snapshot_test.go b/tests/integration/clientv3/snapshot/v3_snapshot_test.go index 1d141cab3..87da75683 100644 --- a/tests/integration/clientv3/snapshot/v3_snapshot_test.go +++ b/tests/integration/clientv3/snapshot/v3_snapshot_test.go @@ -72,13 +72,12 @@ func createSnapshotFile(t *testing.T, kvs []kv) string { cfg.LCUrls, cfg.ACUrls = cURLs, cURLs cfg.LPUrls, cfg.APUrls = pURLs, pURLs cfg.InitialCluster = fmt.Sprintf("%s=%s", cfg.Name, pURLs[0].String()) - cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond())) + cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond())) srv, err := embed.StartEtcd(cfg) if err != nil { t.Fatal(err) } defer func() { - os.RemoveAll(cfg.Dir) srv.Close() }() select { @@ -102,12 +101,11 @@ func createSnapshotFile(t *testing.T, kvs []kv) string { } } - dpPath := filepath.Join(os.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond())) + dpPath := filepath.Join(t.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond())) if err = snapshot.Save(context.Background(), zap.NewExample(), ccfg, dpPath); err != nil { t.Fatal(err) } - os.RemoveAll(cfg.Dir) srv.Close() return dpPath } diff --git a/tests/integration/cluster.go b/tests/integration/cluster.go index a4713da80..1222ee665 100644 --- a/tests/integration/cluster.go +++ b/tests/integration/cluster.go @@ -83,43 +83,44 @@ var ( localListenCount = int64(0) testTLSInfo = transport.TLSInfo{ - KeyFile: "../fixtures/server.key.insecure", - CertFile: "../fixtures/server.crt", - TrustedCAFile: "../fixtures/ca.crt", + KeyFile: MustAbsPath("../fixtures/server.key.insecure"), + CertFile: MustAbsPath("../fixtures/server.crt"), + TrustedCAFile: MustAbsPath("../fixtures/ca.crt"), ClientCertAuth: true, } testTLSInfoWithSpecificUsage = transport.TLSInfo{ - KeyFile: "../fixtures/server-serverusage.key.insecure", - CertFile: "../fixtures/server-serverusage.crt", - ClientKeyFile: "../fixtures/client-clientusage.key.insecure", - ClientCertFile: "../fixtures/client-clientusage.crt", - TrustedCAFile: "../fixtures/ca.crt", + KeyFile: MustAbsPath("../fixtures/server-serverusage.key.insecure"), + CertFile: MustAbsPath("../fixtures/server-serverusage.crt"), + ClientKeyFile: MustAbsPath("../fixtures/client-clientusage.key.insecure"), + ClientCertFile: MustAbsPath("../fixtures/client-clientusage.crt"), + TrustedCAFile: MustAbsPath("../fixtures/ca.crt"), ClientCertAuth: true, } testTLSInfoIP = transport.TLSInfo{ - KeyFile: "../fixtures/server-ip.key.insecure", - CertFile: "../fixtures/server-ip.crt", - TrustedCAFile: "../fixtures/ca.crt", + KeyFile: MustAbsPath("../fixtures/server-ip.key.insecure"), + CertFile: MustAbsPath("../fixtures/server-ip.crt"), + TrustedCAFile: MustAbsPath("../fixtures/ca.crt"), ClientCertAuth: true, } testTLSInfoExpired = transport.TLSInfo{ - KeyFile: "./fixtures-expired/server.key.insecure", - CertFile: "./fixtures-expired/server.crt", - TrustedCAFile: "./fixtures-expired/ca.crt", + KeyFile: MustAbsPath("./fixtures-expired/server.key.insecure"), + CertFile: MustAbsPath("./fixtures-expired/server.crt"), + TrustedCAFile: MustAbsPath("./fixtures-expired/ca.crt"), ClientCertAuth: true, } testTLSInfoExpiredIP = transport.TLSInfo{ - KeyFile: "./fixtures-expired/server-ip.key.insecure", - CertFile: "./fixtures-expired/server-ip.crt", - TrustedCAFile: "./fixtures-expired/ca.crt", + KeyFile: MustAbsPath("./fixtures-expired/server-ip.key.insecure"), + CertFile: MustAbsPath("./fixtures-expired/server-ip.crt"), + TrustedCAFile: MustAbsPath("./fixtures-expired/ca.crt"), ClientCertAuth: true, } - defaultTokenJWT = "jwt,pub-key=../fixtures/server.crt,priv-key=../fixtures/server.key.insecure,sign-method=RS256,ttl=1s" + defaultTokenJWT = fmt.Sprintf("jwt,pub-key=%s,priv-key=%s,sign-method=RS256,ttl=1s", + MustAbsPath("../fixtures/server.crt"), MustAbsPath("../fixtures/server.key.insecure")) ) type ClusterConfig struct { diff --git a/tests/integration/embed/embed_test.go b/tests/integration/embed/embed_test.go index 4459a1e02..ac8c9291b 100644 --- a/tests/integration/embed/embed_test.go +++ b/tests/integration/embed/embed_test.go @@ -34,13 +34,14 @@ import ( "go.etcd.io/etcd/pkg/v3/testutil" "go.etcd.io/etcd/pkg/v3/transport" "go.etcd.io/etcd/server/v3/embed" + "go.etcd.io/etcd/tests/v3/integration" ) var ( testTLSInfo = transport.TLSInfo{ - KeyFile: "../../fixtures/server.key.insecure", - CertFile: "../../fixtures/server.crt", - TrustedCAFile: "../../fixtures/ca.crt", + KeyFile: integration.MustAbsPath("../../fixtures/server.key.insecure"), + CertFile: integration.MustAbsPath("../../fixtures/server.crt"), + TrustedCAFile: integration.MustAbsPath("../../fixtures/ca.crt"), ClientCertAuth: true, } ) @@ -88,9 +89,7 @@ func TestEmbedEtcd(t *testing.T) { tests[7].cfg.LCUrls = []url.URL{*dnsURL} tests[8].cfg.LPUrls = []url.URL{*dnsURL} - dir := filepath.Join(os.TempDir(), fmt.Sprintf("embed-etcd")) - os.RemoveAll(dir) - defer os.RemoveAll(dir) + dir := filepath.Join(t.TempDir(), fmt.Sprintf("embed-etcd")) for i, tt := range tests { tests[i].cfg.Dir = dir @@ -143,9 +142,7 @@ func testEmbedEtcdGracefulStop(t *testing.T, secure bool) { urls := newEmbedURLs(secure, 2) setupEmbedCfg(cfg, []url.URL{urls[0]}, []url.URL{urls[1]}) - cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprintf("embed-etcd")) - os.RemoveAll(cfg.Dir) - defer os.RemoveAll(cfg.Dir) + cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprintf("embed-etcd")) e, err := embed.StartEtcd(cfg) if err != nil { diff --git a/tests/integration/member_test.go b/tests/integration/member_test.go index 54d3dbedc..62520bbe6 100644 --- a/tests/integration/member_test.go +++ b/tests/integration/member_test.go @@ -18,7 +18,6 @@ import ( "context" "fmt" "io/ioutil" - "os" "reflect" "testing" @@ -70,7 +69,7 @@ func TestLaunchDuplicateMemberShouldFail(t *testing.T) { c := NewCluster(t, size) m := c.Members[0].Clone(t) var err error - m.DataDir, err = ioutil.TempDir(os.TempDir(), "etcd") + m.DataDir, err = ioutil.TempDir(t.TempDir(), "etcd") if err != nil { t.Fatal(err) } diff --git a/tests/integration/snapshot/member_test.go b/tests/integration/snapshot/member_test.go index 1a6cecfa6..22997272d 100644 --- a/tests/integration/snapshot/member_test.go +++ b/tests/integration/snapshot/member_test.go @@ -76,7 +76,7 @@ func TestSnapshotV3RestoreMultiMemberAdd(t *testing.T) { } cfg.InitialCluster = cfg.InitialCluster[1:] cfg.InitialCluster += fmt.Sprintf(",%s=%s", cfg.Name, newPURLs[0].String()) - cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond())) + cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond())) srv, err := embed.StartEtcd(cfg) if err != nil { diff --git a/tests/integration/snapshot/v3_snapshot_test.go b/tests/integration/snapshot/v3_snapshot_test.go index 4c10f4292..0b7fcc52c 100644 --- a/tests/integration/snapshot/v3_snapshot_test.go +++ b/tests/integration/snapshot/v3_snapshot_test.go @@ -29,8 +29,7 @@ import ( "go.etcd.io/etcd/etcdctl/v3/snapshot" "go.etcd.io/etcd/pkg/v3/testutil" "go.etcd.io/etcd/server/v3/embed" - - "go.uber.org/zap" + "go.uber.org/zap/zaptest" ) // TestSnapshotV3RestoreSingle tests single node cluster restoring @@ -53,9 +52,9 @@ func TestSnapshotV3RestoreSingle(t *testing.T) { cfg.LCUrls, cfg.ACUrls = cURLs, cURLs cfg.LPUrls, cfg.APUrls = pURLs, pURLs cfg.InitialCluster = fmt.Sprintf("%s=%s", cfg.Name, pURLs[0].String()) - cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond())) + cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond())) - sp := snapshot.NewV3(zap.NewExample()) + sp := snapshot.NewV3(zaptest.NewLogger(t)) pss := make([]string, 0, len(pURLs)) for _, p := range pURLs { pss = append(pss, p.String()) @@ -149,7 +148,7 @@ func TestCorruptedBackupFileCheck(t *testing.T) { t.Fatalf("test file [%s] does not exist: %v", dbPath, err) } - sp := snapshot.NewV3(zap.NewExample()) + sp := snapshot.NewV3(zaptest.NewLogger(t)) _, err := sp.Status(dbPath) expectedErrKeywords := "snapshot file integrity check failed" /* example error message: @@ -187,7 +186,7 @@ func createSnapshotFile(t *testing.T, kvs []kv) string { cfg.LCUrls, cfg.ACUrls = cURLs, cURLs cfg.LPUrls, cfg.APUrls = pURLs, pURLs cfg.InitialCluster = fmt.Sprintf("%s=%s", cfg.Name, pURLs[0].String()) - cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond())) + cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond())) srv, err := embed.StartEtcd(cfg) if err != nil { t.Fatal(err) @@ -217,8 +216,8 @@ func createSnapshotFile(t *testing.T, kvs []kv) string { } } - sp := snapshot.NewV3(zap.NewExample()) - dpPath := filepath.Join(os.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond())) + sp := snapshot.NewV3(zaptest.NewLogger(t)) + dpPath := filepath.Join(t.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond())) if err = sp.Save(context.Background(), ccfg, dpPath); err != nil { t.Fatal(err) } @@ -254,9 +253,9 @@ func restoreCluster(t *testing.T, clusterN int, dbPath string) ( cfg.LCUrls, cfg.ACUrls = []url.URL{cURLs[i]}, []url.URL{cURLs[i]} cfg.LPUrls, cfg.APUrls = []url.URL{pURLs[i]}, []url.URL{pURLs[i]} cfg.InitialCluster = ics - cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()+i)) + cfg.Dir = filepath.Join(t.TempDir(), fmt.Sprint(time.Now().Nanosecond()+i)) - sp := snapshot.NewV3(zap.NewExample()) + sp := snapshot.NewV3(zaptest.NewLogger(t)) if err := sp.Restore(snapshot.RestoreConfig{ SnapshotPath: dbPath, Name: cfg.Name, diff --git a/tests/integration/testing.go b/tests/integration/testing.go index a525bb9a4..e52c882ad 100644 --- a/tests/integration/testing.go +++ b/tests/integration/testing.go @@ -15,6 +15,8 @@ package integration import ( + "os" + "path/filepath" "testing" "go.etcd.io/etcd/pkg/v3/testutil" @@ -22,4 +24,22 @@ import ( func BeforeTest(t testing.TB) { testutil.BeforeTest(t) + + previousWD, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + os.Chdir(t.TempDir()) + t.Cleanup(func() { + os.Chdir(previousWD) + }) + } + +func MustAbsPath(path string) string { + abs, err := filepath.Abs(path) + if err != nil { + panic(err) + } + return abs +} \ No newline at end of file diff --git a/tests/integration/v2store/store_v2v3_test.go b/tests/integration/v2store/store_v2v3_test.go index d734f284d..5a186389b 100644 --- a/tests/integration/v2store/store_v2v3_test.go +++ b/tests/integration/v2store/store_v2v3_test.go @@ -30,7 +30,7 @@ import ( func runWithCluster(t testing.TB, runner func(testing.TB, []string)) { testutil.BeforeTest(t) cfg := integration.ClusterConfig{Size: 1} - clus := integration.NewClusterV3(nil, &cfg) + clus := integration.NewClusterV3(t, &cfg) defer clus.Terminate(t) endpoints := []string{clus.Client(0).Endpoints()[0]} runner(t, endpoints) diff --git a/tests/integration/v3_election_test.go b/tests/integration/v3_election_test.go index 8ef54d23e..a3aed9ba6 100644 --- a/tests/integration/v3_election_test.go +++ b/tests/integration/v3_election_test.go @@ -26,6 +26,7 @@ import ( // TestElectionWait tests if followers can correctly wait for elections. func TestElectionWait(t *testing.T) { + BeforeTest(t) clus := NewClusterV3(t, &ClusterConfig{Size: 3}) defer clus.Terminate(t) @@ -107,6 +108,7 @@ func TestElectionWait(t *testing.T) { // TestElectionFailover tests that an election will func TestElectionFailover(t *testing.T) { + BeforeTest(t) clus := NewClusterV3(t, &ClusterConfig{Size: 3}) defer clus.Terminate(t) @@ -174,6 +176,7 @@ func TestElectionFailover(t *testing.T) { // TestElectionSessionRelock ensures that campaigning twice on the same election // with the same lock will Proclaim instead of deadlocking. func TestElectionSessionRecampaign(t *testing.T) { + BeforeTest(t) clus := NewClusterV3(t, &ClusterConfig{Size: 1}) defer clus.Terminate(t) cli := clus.RandClient() @@ -206,6 +209,7 @@ func TestElectionSessionRecampaign(t *testing.T) { // of bug #6278. https://github.com/etcd-io/etcd/issues/6278 // func TestElectionOnPrefixOfExistingKey(t *testing.T) { + BeforeTest(t) clus := NewClusterV3(t, &ClusterConfig{Size: 1}) defer clus.Terminate(t) @@ -232,6 +236,7 @@ func TestElectionOnPrefixOfExistingKey(t *testing.T) { // in a new session with the same lease id) does not result in loss of // leadership. func TestElectionOnSessionRestart(t *testing.T) { + BeforeTest(t) clus := NewClusterV3(t, &ClusterConfig{Size: 1}) defer clus.Terminate(t) cli := clus.RandClient() @@ -278,6 +283,7 @@ func TestElectionOnSessionRestart(t *testing.T) { // TestElectionObserveCompacted checks that observe can tolerate // a leader key with a modrev less than the compaction revision. func TestElectionObserveCompacted(t *testing.T) { + BeforeTest(t) clus := NewClusterV3(t, &ClusterConfig{Size: 1}) defer clus.Terminate(t) diff --git a/tests/integration/v3_grpc_test.go b/tests/integration/v3_grpc_test.go index 5c29b6319..8354aa374 100644 --- a/tests/integration/v3_grpc_test.go +++ b/tests/integration/v3_grpc_test.go @@ -1609,20 +1609,20 @@ func TestTLSGRPCAcceptSecureAll(t *testing.T) { // when all certs are atomically replaced by directory renaming. // And expects server to reject client requests, and vice versa. func TestTLSReloadAtomicReplace(t *testing.T) { - tmpDir, err := ioutil.TempDir(os.TempDir(), "fixtures-tmp") + tmpDir, err := ioutil.TempDir(t.TempDir(), "fixtures-tmp") if err != nil { t.Fatal(err) } os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir) - certsDir, err := ioutil.TempDir(os.TempDir(), "fixtures-to-load") + certsDir, err := ioutil.TempDir(t.TempDir(), "fixtures-to-load") if err != nil { t.Fatal(err) } defer os.RemoveAll(certsDir) - certsDirExp, err := ioutil.TempDir(os.TempDir(), "fixtures-expired") + certsDirExp, err := ioutil.TempDir(t.TempDir(), "fixtures-expired") if err != nil { t.Fatal(err) } @@ -1668,7 +1668,7 @@ func TestTLSReloadAtomicReplace(t *testing.T) { // when new certs are copied over, one by one. And expects server // to reject client requests, and vice versa. func TestTLSReloadCopy(t *testing.T) { - certsDir, err := ioutil.TempDir(os.TempDir(), "fixtures-to-load") + certsDir, err := ioutil.TempDir(t.TempDir(), "fixtures-to-load") if err != nil { t.Fatal(err) } @@ -1698,7 +1698,7 @@ func TestTLSReloadCopy(t *testing.T) { // when new certs are copied over, one by one. And expects server // to reject client requests, and vice versa. func TestTLSReloadCopyIPOnly(t *testing.T) { - certsDir, err := ioutil.TempDir(os.TempDir(), "fixtures-to-load") + certsDir, err := ioutil.TempDir(t.TempDir(), "fixtures-to-load") if err != nil { t.Fatal(err) } diff --git a/tests/integration/v3_kv_test.go b/tests/integration/v3_kv_test.go index db26c3a45..cbd4e0acd 100644 --- a/tests/integration/v3_kv_test.go +++ b/tests/integration/v3_kv_test.go @@ -2,45 +2,22 @@ package integration import ( "context" - "io/ioutil" - "os" "testing" "go.etcd.io/etcd/client/v3" "go.etcd.io/etcd/client/v3/namespace" - "go.etcd.io/etcd/server/v3/embed" - "go.etcd.io/etcd/server/v3/etcdserver/api/v3client" ) // TestKVWithEmptyValue ensures that a get/delete with an empty value, and with WithFromKey/WithPrefix function will return an empty error. func TestKVWithEmptyValue(t *testing.T) { BeforeTest(t) - cfg := embed.NewConfig() + clus := NewClusterV3(t, &ClusterConfig{Size: 1}) + defer clus.Terminate(t) - // Use temporary data directory. - dir, err := ioutil.TempDir("", "etcd-") - if err != nil { - panic(err) - } - defer os.RemoveAll(dir) - cfg.Dir = dir + client := clus.RandClient() - // Suppress server log to keep output clean. - //cfg.Logger = "zap" - //cfg.LogLevel = "error" - - etcd, err := embed.StartEtcd(cfg) - if err != nil { - panic(err) - } - defer etcd.Close() - <-etcd.Server.ReadyNotify() - - client := v3client.New(etcd.Server) - defer client.Close() - - _, err = client.Put(context.Background(), "my-namespace/foobar", "data") + _, err := client.Put(context.Background(), "my-namespace/foobar", "data") if err != nil { t.Fatal(err) }