From 68f2cb8c7736e2b80fb9aceef6127563884d9ea4 Mon Sep 17 00:00:00 2001 From: Piotr Tabor Date: Sun, 3 Apr 2022 10:46:51 +0200 Subject: [PATCH] Fix ExampleAuth from integration/clientv3/examples (on OsX) The code now ensures that each of the test is running in its own directory as opposed to shared os.tempdir. ``` $ (cd tests && env go test -timeout=15m --race go.etcd.io/etcd/tests/v3/integration/clientv3/examples -run ExampleAuth) 2022/04/03 10:24:59 Running tests (examples): ... 2022/04/03 10:24:59 the function can be called only in the test context. Was integration.BeforeTest() called ? 2022/04/03 10:24:59 2022-04-03T10:24:59.462+0200 INFO m0 LISTEN GRPC {"member": "m0", "grpcAddr": "localhost:m0", "m.Name": "m0"} ``` --- client/pkg/testutil/before.go | 20 +++++++++++++ tests/framework/integration/cluster.go | 28 +++++++++++++------ .../clientv3/concurrency/main_test.go | 3 +- .../clientv3/examples/main_test.go | 13 ++++++--- tests/integration/lazy_cluster.go | 2 ++ 5 files changed, 52 insertions(+), 14 deletions(-) diff --git a/client/pkg/testutil/before.go b/client/pkg/testutil/before.go index 801aa042d..c3a01b1e6 100644 --- a/client/pkg/testutil/before.go +++ b/client/pkg/testutil/before.go @@ -15,6 +15,8 @@ package testutil import ( + "io/ioutil" + "log" "os" "testing" @@ -38,3 +40,21 @@ func BeforeTest(t testing.TB) { t.Cleanup(func() { assert.NoError(t, os.Chdir(path)) }) } + +func BeforeIntegrationExamples(*testing.M) func() { + ExitInShortMode("Skipping: the tests require real cluster") + + tempDir, err := ioutil.TempDir(os.TempDir(), "etcd-integration") + if err != nil { + log.Printf("Failed to obtain tempDir: %v", tempDir) + os.Exit(1) + } + + err = os.Chdir(tempDir) + if err != nil { + log.Printf("Failed to change working dir to: %s: %v", tempDir, err) + os.Exit(1) + } + log.Printf("Running tests (examples) in dir(%v): ...", tempDir) + return func() { os.RemoveAll(tempDir) } +} diff --git a/tests/framework/integration/cluster.go b/tests/framework/integration/cluster.go index b09d05470..089a0d29a 100644 --- a/tests/framework/integration/cluster.go +++ b/tests/framework/integration/cluster.go @@ -214,6 +214,7 @@ func (c *Cluster) fillClusterForMembers() error { } func (c *Cluster) Launch(t testutil.TB) { + t.Logf("Launching new cluster...") errc := make(chan error) for _, m := range c.Members { // Members are launched in separate goroutines because if they boot @@ -411,7 +412,7 @@ func (c *Cluster) WaitMembersForLeader(t testutil.TB, membs []*Member) int { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() l := 0 - for l = c.waitMembersForLeader(t, ctx, membs); l < 0; { + for l = c.waitMembersForLeader(ctx, t, membs); l < 0; { if ctx.Err() != nil { t.Fatal("WaitLeader FAILED: %v", ctx.Err()) } @@ -427,14 +428,12 @@ func (c *Cluster) WaitMembersForLeader(t testutil.TB, membs []*Member) int { // - 9903a56eaf96afac became follower at term 3 {"member": "m0"} // - 9903a56eaf96afac lost leader 9903a56eaf96afac at term 3 {"member": "m0"} - return l } // WaitMembersForLeader waits until given members agree on the same leader, // and returns its 'index' in the 'membs' list -func (c *Cluster) waitMembersForLeader(t testutil.TB, ctx context.Context, membs []*Member) int { - t.Logf("WaitMembersForLeader...") +func (c *Cluster) waitMembersForLeader(ctx context.Context, t testutil.TB, membs []*Member) int { possibleLead := make(map[uint64]bool) var lead uint64 for _, m := range membs { @@ -473,12 +472,12 @@ func (c *Cluster) waitMembersForLeader(t testutil.TB, ctx context.Context, membs for i, m := range membs { if uint64(m.Server.ID()) == lead { - t.Logf("WaitMembersForLeader found leader. Member: %v lead: %x", i, lead) + t.Logf("waitMembersForLeader found leader. Member: %v lead: %x", i, lead) return i } } - t.Logf("WaitMembersForLeader FAILED (-1)") + t.Logf("waitMembersForLeader failed (-1)") return -1 } @@ -531,6 +530,7 @@ func newLocalListener(t testutil.TB) net.Listener { } func NewListenerWithAddr(t testutil.TB, addr string) net.Listener { + t.Logf("Creating listener with addr: %v", addr) l, err := transport.NewUnixListener(addr) if err != nil { t.Fatal(err) @@ -722,7 +722,7 @@ func MustNewMember(t testutil.TB, mcfg MemberConfig) *Member { m.Logger = memberLogger(t, mcfg.Name) m.StrictReconfigCheck = mcfg.StrictReconfigCheck if err := m.listenGRPC(); err != nil { - t.Fatal(err) + t.Fatalf("listenGRPC FAILED: %v", err) } t.Cleanup(func() { // if we didn't cleanup the logger, the consecutive test @@ -747,7 +747,11 @@ func (m *Member) listenGRPC() error { // prefix with localhost so cert has right domain network, host, port := m.grpcAddr() grpcAddr := host + ":" + port - m.Logger.Info("LISTEN GRPC", zap.String("grpcAddr", grpcAddr), zap.String("m.Name", m.Name)) + wd, err := os.Getwd() + if err != nil { + return err + } + m.Logger.Info("LISTEN GRPC", zap.String("grpcAddr", grpcAddr), zap.String("m.Name", m.Name), zap.String("workdir", wd)) grpcListener, err := net.Listen(network, grpcAddr) if err != nil { return fmt.Errorf("listen failed on grpc socket %s (%v)", grpcAddr, err) @@ -1346,7 +1350,7 @@ func NewCluster(t testutil.TB, cfg *ClusterConfig) *Cluster { } c.Members = ms if err := c.fillClusterForMembers(); err != nil { - t.Fatal(err) + t.Fatalf("fillClusterForMembers failed: %v", err) } c.Launch(t) @@ -1360,6 +1364,9 @@ func (c *Cluster) TakeClient(idx int) { } func (c *Cluster) Terminate(t testutil.TB) { + if t != nil { + t.Logf("========= Cluster termination started =====================") + } c.mu.Lock() if c.clusterClient != nil { if err := c.clusterClient.Close(); err != nil { @@ -1381,6 +1388,9 @@ func (c *Cluster) Terminate(t testutil.TB) { }(m) } wg.Wait() + if t != nil { + t.Logf("========= Cluster termination succeeded ===================") + } } func (c *Cluster) RandClient() *clientv3.Client { diff --git a/tests/integration/clientv3/concurrency/main_test.go b/tests/integration/clientv3/concurrency/main_test.go index c54df6b4b..62a6e73a0 100644 --- a/tests/integration/clientv3/concurrency/main_test.go +++ b/tests/integration/clientv3/concurrency/main_test.go @@ -33,12 +33,13 @@ func forUnitTestsRunInMockedContext(mocking func(), example func()) { // TestMain sets up an etcd cluster if running the examples. func TestMain(m *testing.M) { - testutil.ExitInShortMode("Skipping: the tests require real cluster") + cleanup := testutil.BeforeIntegrationExamples(m) v := m.Run() lazyCluster.Terminate() if v == 0 { testutil.MustCheckLeakedGoroutine() } + cleanup() os.Exit(v) } diff --git a/tests/integration/clientv3/examples/main_test.go b/tests/integration/clientv3/examples/main_test.go index 223ec2cdb..5803739f0 100644 --- a/tests/integration/clientv3/examples/main_test.go +++ b/tests/integration/clientv3/examples/main_test.go @@ -15,6 +15,7 @@ package clientv3_test import ( + "io/ioutil" "log" "os" "testing" @@ -37,7 +38,7 @@ var lazyCluster = integration.NewLazyClusterWithConfig( func exampleEndpoints() []string { return lazyCluster.EndpointsV3() } -func forUnitTestsRunInMockedContext(mocking func(), example func()) { +func forUnitTestsRunInMockedContext(_ func(), example func()) { // For integration tests runs in the provided environment example() } @@ -46,15 +47,19 @@ func forUnitTestsRunInMockedContext(mocking func(), example func()) { func TestMain(m *testing.M) { testutil.ExitInShortMode("Skipping: the tests require real cluster") - tempDir := os.TempDir() + tempDir, err := ioutil.TempDir(os.TempDir(), "etcd-integration") + if err != nil { + log.Printf("Failed to obtain tempDir: %v", tempDir) + os.Exit(1) + } defer os.RemoveAll(tempDir) - err := os.Chdir(tempDir) + err = os.Chdir(tempDir) if err != nil { log.Printf("Failed to change working dir to: %s: %v", tempDir, err) os.Exit(1) } - + log.Printf("Running tests (examples) in dir(%v): ...", tempDir) v := m.Run() lazyCluster.Terminate() diff --git a/tests/integration/lazy_cluster.go b/tests/integration/lazy_cluster.go index 02fc759dc..1d16d2d38 100644 --- a/tests/integration/lazy_cluster.go +++ b/tests/integration/lazy_cluster.go @@ -77,12 +77,14 @@ func NewLazyClusterWithConfig(cfg integration.ClusterConfig) LazyCluster { func (lc *lazyCluster) mustLazyInit() { lc.once.Do(func() { + lc.tb.Logf("LazyIniting ...") var err error lc.transport, err = transport.NewTransport(transport.TLSInfo{}, time.Second) if err != nil { log.Fatal(err) } lc.cluster = integration.NewCluster(lc.tb, &lc.cfg) + lc.tb.Logf("LazyIniting [Done]") }) }