diff --git a/.circleci/config.yml b/.circleci/config.yml index 97400b6bd59..6bb94cf5493 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,38 +1,47 @@ version: 2.1 -references: - images: - go-1.13: &GOLANG_1_13_IMAGE docker.mirror.hashicorp.services/circleci/golang:1.13 - go-1.14: &GOLANG_1_14_IMAGE docker.mirror.hashicorp.services/circleci/golang:1.14 - go-1.15: &GOLANG_1_15_IMAGE docker.mirror.hashicorp.services/circleci/golang:1.15 - go-1.16: &GOLANG_1_16_IMAGE docker.mirror.hashicorp.services/circleci/golang:1.16 +workflows: + ci: + jobs: + - lint + - go-test: + name: test go1.15 + version: "1.15" + - go-test: + name: test go1.16 + version: "1.16" + - go-test: + name: test go1.16 32bit + version: "1.16" + goarch: "386" + args: "" # remove -race - environment: &ENVIRONMENT - TEST_RESULTS_DIR: &TEST_RESULTS_DIR /tmp/test-results # path to where test results are saved - GOTRACEBACK: "all" - GO111MODULE: "on" - GOMAXPROCS: 2 +executors: + golang: + parameters: + version: + type: string + goarch: + type: string + default: amd64 + docker: + - image: docker.mirror.hashicorp.services/circleci/golang:<> + environment: + TEST_RESULTS_DIR: /tmp/test-results + GOTRACEBACK: "all" + GO111MODULE: "on" + GOMAXPROCS: 2 + GOARCH: <> jobs: - go-fmt-and-vet: - docker: - - image: *GOLANG_1_14_IMAGE + lint: + executor: + name: golang + version: "1.16" steps: - checkout - - # Restore go module cache if there is one - - restore_cache: - keys: - - raft-modcache-v1-{{ checksum "go.mod" }} - - run: go mod download - # Save go module cache if the go.mod file has changed - - save_cache: - key: raft-modcache-v1-{{ checksum "go.mod" }} - paths: - - "/go/pkg/mod" - # check go fmt output because it does not report non-zero when there are fmt changes - run: name: check go fmt @@ -48,87 +57,33 @@ jobs: go vet $PACKAGE_NAMES go-test: - description: Runs go tests parameters: - go-version: - description: what go version to use + version: type: string - docker: - - image: << parameters.go-version >> - environment: *ENVIRONMENT - steps: - - checkout - - run: mkdir -p $TEST_RESULTS_DIR - - - restore_cache: # restore cache - keys: - - raft-modcache-v1-{{ checksum "go.mod" }} - - # run go tests with gotestsum - - run: make ci.integ - - store_test_results: - path: /tmp/test-results - - store_artifacts: - path: /tmp/test-results - - go-test-32bit: - description: Runs go tests - 32 bit - parameters: - go-version: - description: what go version to use + goarch: type: string - docker: - - image: << parameters.go-version >> - environment: - <<: *ENVIRONMENT - GOARCH: "386" + default: amd64 + args: + type: string + default: "-race" + executor: + name: golang + version: <> + goarch: <> steps: + - run: go env - checkout - run: mkdir -p $TEST_RESULTS_DIR + - run: + name: run tests + environment: + INTEG_TESTS: "yes" + GOTESTSUM_FORMAT: short-verbose + command: | + gotestsum --junitfile ${TEST_RESULTS_DIR}/junit.xml -- -timeout=240s <> . + gotestsum --junitfile ${TEST_RESULTS_DIR}/junit-batch.xml -- -timeout=240s <> -tags batchtest . - - restore_cache: # restore cache - keys: - - raft-modcache-v1-{{ checksum "go.mod" }} - - # run go tests with gotestsum - - run: make ci.test-norace - store_test_results: path: /tmp/test-results - store_artifacts: path: /tmp/test-results - -workflows: - version: 2 - test-and-build: - jobs: - - go-fmt-and-vet - - go-test: - name: test go1.13 - go-version: *GOLANG_1_13_IMAGE - requires: - - go-fmt-and-vet - - go-test: - name: test go1.14 - go-version: *GOLANG_1_14_IMAGE - requires: - - go-fmt-and-vet - - go-test: - name: test go1.15 - go-version: *GOLANG_1_15_IMAGE - requires: - - go-fmt-and-vet - - go-test: - name: test go1.16 - go-version: *GOLANG_1_16_IMAGE - requires: - - go-fmt-and-vet - - go-test-32bit: - name: test go1.13 - 32bit - go-version: *GOLANG_1_13_IMAGE - requires: - - go-fmt-and-vet - - go-test-32bit: - name: test go1.14 - 32bit - go-version: *GOLANG_1_14_IMAGE - requires: - - go-fmt-and-vet diff --git a/Makefile b/Makefile index e1f7bd49c13..c988f0ab2f4 100644 --- a/Makefile +++ b/Makefile @@ -23,18 +23,6 @@ integ: test INTEG_TESTS=yes go test $(TESTARGS) -timeout=60s -run=Integ . INTEG_TESTS=yes go test $(TESTARGS) -timeout=60s -tags batchtest -run=Integ . -ci.test-norace: - gotestsum --format=short-verbose --junitfile $(TEST_RESULTS_DIR)/gotestsum-report-test.xml -- -timeout=180s - gotestsum --format=short-verbose --junitfile $(TEST_RESULTS_DIR)/gotestsum-report-test.xml -- -timeout=180s -tags batchtest - -ci.test: - gotestsum --format=short-verbose --junitfile $(TEST_RESULTS_DIR)/gotestsum-report-test.xml -- -timeout=180s -race . - gotestsum --format=short-verbose --junitfile $(TEST_RESULTS_DIR)/gotestsum-report-test.xml -- -timeout=180s -race -tags batchtest . - -ci.integ: ci.test - INTEG_TESTS=yes gotestsum --format=short-verbose --junitfile $(TEST_RESULTS_DIR)/gotestsum-report-integ.xml -- -timeout=60s -run=Integ . - INTEG_TESTS=yes gotestsum --format=short-verbose --junitfile $(TEST_RESULTS_DIR)/gotestsum-report-integ.xml -- -timeout=60s -run=Integ -tags batchtest . - fuzz: cd ./fuzzy && go test $(TESTARGS) -timeout=20m . cd ./fuzzy && go test $(TESTARGS) -timeout=20m -tags batchtest . diff --git a/net_transport_test.go b/net_transport_test.go index 77b1825ff50..d42d469db78 100644 --- a/net_transport_test.go +++ b/net_transport_test.go @@ -3,8 +3,6 @@ package raft import ( "bytes" "fmt" - "github.com/hashicorp/go-hclog" - "github.com/stretchr/testify/require" "net" "reflect" "strings" @@ -12,6 +10,9 @@ import ( "sync/atomic" "testing" "time" + + "github.com/hashicorp/go-hclog" + "github.com/stretchr/testify/require" ) type testAddrProvider struct { @@ -60,7 +61,8 @@ func TestNetworkTransport_CloseStreams(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } rpc.Respond(&resp, nil) @@ -220,13 +222,14 @@ func TestNetworkTransport_AppendEntries(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() @@ -290,12 +293,14 @@ func TestNetworkTransport_AppendEntriesPipeline(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") + return } } }() @@ -376,7 +381,8 @@ func TestNetworkTransport_AppendEntriesPipeline_CloseStreams(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } rpc.Respond(&resp, nil) @@ -472,13 +478,15 @@ func TestNetworkTransport_RequestVote(t *testing.T) { // Verify the command req := rpc.Command.(*RequestVoteRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") + return } }() @@ -533,7 +541,8 @@ func TestNetworkTransport_InstallSnapshot(t *testing.T) { // Verify the command req := rpc.Command.(*InstallSnapshotRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } // Try to read the bytes @@ -542,13 +551,14 @@ func TestNetworkTransport_InstallSnapshot(t *testing.T) { // Compare if bytes.Compare(buf, []byte("0123456789")) != 0 { - t.Fatalf("bad buf %v", buf) + t.Errorf("bad buf %v", buf) + return } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() @@ -647,7 +657,8 @@ func TestNetworkTransport_PooledConn(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } rpc.Respond(&resp, nil) diff --git a/raft_test.go b/raft_test.go index 03837b31239..51db44a8219 100644 --- a/raft_test.go +++ b/raft_test.go @@ -120,13 +120,12 @@ func TestRaft_RecoverCluster_NoState(t *testing.T) { } func TestRaft_RecoverCluster(t *testing.T) { - // Run with different number of applies which will cover no snapshot and - // snapshot + log scenarios. By sweeping through the trailing logs value - // we will also hit the case where we have a snapshot only. - var err error + snapshotThreshold := 5 runRecover := func(t *testing.T, applies int) { + var err error conf := inmemConfig(t) conf.TrailingLogs = 10 + conf.SnapshotThreshold = uint64(snapshotThreshold) c := MakeCluster(3, t, conf) defer c.Close() @@ -212,11 +211,16 @@ func TestRaft_RecoverCluster(t *testing.T) { c.EnsureSame(t) c.EnsureSamePeers(t) } - for applies := 0; applies < 10; applies++ { - t.Run(fmt.Sprintf("%d applies", applies), func(t *testing.T) { - runRecover(t, applies) - }) - } + + t.Run("no snapshot, no trailing logs", func(t *testing.T) { + runRecover(t, 0) + }) + t.Run("no snapshot, some trailing logs", func(t *testing.T) { + runRecover(t, snapshotThreshold-1) + }) + t.Run("snapshot, with trailing logs", func(t *testing.T) { + runRecover(t, snapshotThreshold+20) + }) } func TestRaft_HasExistingState(t *testing.T) { diff --git a/transport_test.go b/transport_test.go index 91d51e95f3f..5a59253df50 100644 --- a/transport_test.go +++ b/transport_test.go @@ -66,12 +66,13 @@ func TestTransport_AppendEntries(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() @@ -129,12 +130,14 @@ func TestTransport_AppendEntriesPipeline(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") + return } } }() @@ -198,13 +201,14 @@ func TestTransport_RequestVote(t *testing.T) { // Verify the command req := rpc.Command.(*RequestVoteRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() @@ -254,7 +258,8 @@ func TestTransport_InstallSnapshot(t *testing.T) { // Verify the command req := rpc.Command.(*InstallSnapshotRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) + return } // Try to read the bytes @@ -263,13 +268,14 @@ func TestTransport_InstallSnapshot(t *testing.T) { // Compare if bytes.Compare(buf, []byte("0123456789")) != 0 { - t.Fatalf("bad buf %v", buf) + t.Errorf("bad buf %v", buf) + return } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }()