mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
./integration: Fix flakes due to .setupLogging race.
The source of problem was the fact that multiple tests were creating their clusters (and some of them were setting global grpclog). If the test was running after some other test that created HttpServer (so accessed grpclog), this was reported as race. Tested with: go test ./clientv3/. -v "--run=(Example).*" --count=2 go test ./clientv3/. -v "--run=(Test).*" --count=2 go test ./integration/embed/. -v "--run=(Test).*" --count=2
This commit is contained in:
@@ -16,25 +16,12 @@ package clientv3_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"go.etcd.io/etcd/v3/clientv3"
|
||||
"go.etcd.io/etcd/v3/pkg/transport"
|
||||
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"log"
|
||||
)
|
||||
|
||||
var (
|
||||
dialTimeout = 5 * time.Second
|
||||
requestTimeout = 10 * time.Second
|
||||
endpoints = []string{"localhost:2379", "localhost:22379", "localhost:32379"}
|
||||
)
|
||||
|
||||
func Example() {
|
||||
clientv3.SetLogger(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr))
|
||||
|
||||
func ExampleConfig_insecure() {
|
||||
cli, err := clientv3.New(clientv3.Config{
|
||||
Endpoints: endpoints,
|
||||
DialTimeout: dialTimeout,
|
||||
@@ -48,6 +35,10 @@ func Example() {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Without the line below the test is not being executed
|
||||
|
||||
// Output:
|
||||
}
|
||||
|
||||
func ExampleConfig_withTLS() {
|
||||
@@ -74,4 +65,6 @@ func ExampleConfig_withTLS() {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Without the line below the test is not being executed
|
||||
// Output:
|
||||
}
|
||||
|
||||
@@ -16,14 +16,20 @@ package clientv3_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go.etcd.io/etcd/v3/clientv3"
|
||||
"go.etcd.io/etcd/v3/integration"
|
||||
"go.etcd.io/etcd/v3/pkg/testutil"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
"go.etcd.io/etcd/v3/integration"
|
||||
"go.etcd.io/etcd/v3/pkg/testutil"
|
||||
var (
|
||||
dialTimeout = 5 * time.Second
|
||||
requestTimeout = 10 * time.Second
|
||||
endpoints = []string{"localhost:2379", "localhost:22379", "localhost:32379"}
|
||||
)
|
||||
|
||||
// TestMain sets up an etcd cluster if running the examples.
|
||||
@@ -32,8 +38,7 @@ func TestMain(m *testing.M) {
|
||||
for _, arg := range os.Args {
|
||||
if strings.HasPrefix(arg, "-test.run=") {
|
||||
exp := strings.Split(arg, "=")[1]
|
||||
match, err := regexp.MatchString(exp, "Example")
|
||||
useCluster = (err == nil && match) || strings.Contains(exp, "Example")
|
||||
useCluster = strings.Contains(exp, "Example")
|
||||
hasRunArg = true
|
||||
break
|
||||
}
|
||||
@@ -46,6 +51,11 @@ func TestMain(m *testing.M) {
|
||||
|
||||
var v int
|
||||
if useCluster {
|
||||
// Redirecting outputs to Stderr, such that they not interleave with examples outputs.
|
||||
// Setting it once and before running any of the test such that it not data-races
|
||||
// between HTTP servers running in different tests.
|
||||
clientv3.SetLogger(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr))
|
||||
|
||||
cfg := integration.ClusterConfig{Size: 3}
|
||||
clus := integration.NewClusterV3(nil, &cfg)
|
||||
endpoints = make([]string, 3)
|
||||
@@ -61,7 +71,6 @@ func TestMain(m *testing.M) {
|
||||
} else {
|
||||
v = m.Run()
|
||||
}
|
||||
|
||||
if v == 0 && testutil.CheckLeakedGoroutine() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
|
||||
// +build !cluster_proxy
|
||||
|
||||
// TODO: fix race conditions with setupLogging
|
||||
// Keep the test in a separate package from other tests such that
|
||||
// .setupLogging method does not race with other (previously running) servers (grpclog is global).
|
||||
|
||||
package integration
|
||||
package embed_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go.etcd.io/etcd/c/v3/pkg/transport"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -32,6 +34,15 @@ import (
|
||||
"go.etcd.io/etcd/v3/embed"
|
||||
)
|
||||
|
||||
var (
|
||||
testTLSInfo = transport.TLSInfo{
|
||||
KeyFile: "../fixtures/server.key.insecure",
|
||||
CertFile: "../fixtures/server.crt",
|
||||
TrustedCAFile: "../fixtures/ca.crt",
|
||||
ClientCertAuth: true,
|
||||
}
|
||||
)
|
||||
|
||||
func TestEmbedEtcd(t *testing.T) {
|
||||
tests := []struct {
|
||||
cfg embed.Config
|
||||
@@ -55,7 +55,7 @@ func CheckLeakedGoroutine() bool {
|
||||
stackCount[normalized]++
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "Too many goroutines running after all test(s).\n")
|
||||
fmt.Fprintf(os.Stderr, "Unexpected goroutines running after all test(s).\n")
|
||||
for stack, count := range stackCount {
|
||||
fmt.Fprintf(os.Stderr, "%d instances of:\n%s\n", count, stack)
|
||||
}
|
||||
@@ -63,6 +63,7 @@ func CheckLeakedGoroutine() bool {
|
||||
}
|
||||
|
||||
// CheckAfterTest returns an error if AfterTest would fail with an error.
|
||||
// Waits for go-routines shutdown for 'd'.
|
||||
func CheckAfterTest(d time.Duration) error {
|
||||
http.DefaultTransport.(*http.Transport).CloseIdleConnections()
|
||||
if testing.Short() {
|
||||
|
||||
Reference in New Issue
Block a user