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"}
```
This commit is contained in:
Piotr Tabor 2022-04-03 10:46:51 +02:00
parent d57f8dba62
commit 68f2cb8c77
5 changed files with 52 additions and 14 deletions

View File

@ -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) }
}

View File

@ -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 {

View File

@ -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)
}

View File

@ -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()

View File

@ -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]")
})
}