diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..8c651e05fe --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,104 @@ +version: 2 +jobs: + build: + # CircleCI by default sets the gopath to be ~/.go_workspace and /usr/local/go_workspace + # apparently. We cannot set the working directory or environment variables by using + # other environment variables (although the working directory can use the `~` character, + # but environment variables cannot), so to avoid having to override the GOPATH for every + # run command, just hard code in the directory to be CircleCI expects it to be. + working_directory: /home/circleci/.go_workspace/src/github.com/docker/swarmkit + environment: + # Needed to install go + OS: linux + ARCH: amd64 + GOVERSION: 1.10.3 + # Needed to install protoc + PROTOC: https://github.com/google/protobuf/releases/download/v3.2.0/protoc-3.2.0-linux-x86_64.zip + + # Note(cyli): We create a tmpfs mount to be used for temporary files created by tests + # to mitigate the excessive I/O latencies that sometimes cause the tests to fail. + # See https://github.com/docker/swarmkit/pull/2254. + + # There is no way to mount tmpfs volumes in the docker executor, so we are using + # the machine executor. However, this incur a performance overhead + # (https://discuss.circleci.com/t/using-docker-compose-in-2-0/9492/4) + # and in the future could incur additional pricing changes + # (https://circleci.com/docs/2.0/executor-types/#using-machine). + + # One possible hack is the following: + + # /dev/shm in the container is tmpfs although files in /dev/shm are not executable. + # If we specify TMPDIR=/dev/shm, /dev/shm will be used by our tests, which call + # ioutil.TempDir/ioutil.TempFile, to write temporary files. + # We can also specify GOTMPDIR=/tmp or some other non-tmpfs directory + # (see https://golang.org/doc/go1.10#goroot) - this is the directory in which the + # go tool itself will put temporarily compiled test executables, etc. + + # However, using this hack still resulted in occasional WAL test failures, + # so it seems like it does not work, or there may be some other failure. + # It may be something to explore again if the penalty for using the machine + # executor becomes unacceptable. + + machine: true + + steps: + - checkout + + # This would not be needed if we used a golang docker image + - run: + name: Install go + command: | + sudo rm -rf /usr/local/go + curl -fsSL -o "$HOME/go.tar.gz" "https://storage.googleapis.com/golang/go$GOVERSION.$OS-$ARCH.tar.gz" + sudo tar -C /usr/local -xzf "$HOME/go.tar.gz" + + - run: + name: Output debugging information + command: | + go version + env + + - run: + name: Install protoc + command: | + curl -fsSL -o "$HOME/$(basename $PROTOC)" "$PROTOC" + unzip -o "$HOME/$(basename $PROTOC)" -d "$HOME" + sudo cp -R "$HOME/include/google" /usr/local/include + sudo chmod 777 -R /usr/local/include/google + sudo cp -R "$HOME/bin/protoc" /usr/local/bin + sudo chmod 777 /usr/local/bin/protoc + + - run: + name: Install test/lint dependencies + command: make setup + + - run: + name: Validate dependency vendoring + command: | + git fetch origin + if test -n "`git diff --stat=1000 origin/master | grep -E \"^[[:space:]]*vendor\"`"; then + make dep-validate; + fi + + # The GOPATH setting would not be needed if we used the golang docker image + - run: + name: Compile/lint/vet/protobuf validation + command: make check binaries checkprotos + + - run: + name: Run unit tests + command: | + sudo mkdir /tmpfs + sudo mount -t tmpfs tmpfs /tmpfs + sudo chown 1000:1000 /tmpfs + TMPDIR=/tmpfs make coverage + + - run: + name: Run integration tests + command: | + # TMPFS has already been set up previously in the unit test step + TMPDIR=/tmpfs make coverage-integration + + - run: + name: Push coverage info to codecov.io + command: bash <(curl -fsSL https://codecov.io/bash) diff --git a/Makefile b/Makefile index 72509345e6..112cd3fd4e 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,6 @@ setup: ## install dependencies # TODO(stevvooe): Install these from the vendor directory @go get -u github.com/golang/lint/golint #@go get -u github.com/kisielk/errcheck - @go get -u github.com/golang/mock/mockgen @go get -u github.com/gordonklaus/ineffassign @go get -u github.com/client9/misspell/cmd/misspell @go get -u github.com/lk4d4/vndr @@ -81,15 +80,15 @@ fmt: ## run go fmt lint: ## run go lint @echo "🐳 $@" - @test -z "$$(golint ./... | grep -v vendor/ | grep -v ".pb.go:" | grep -v ".mock.go" | tee /dev/stderr)" + @test -z "$$(golint ./... | grep -v vendor/ | grep -v ".pb.go:" | tee /dev/stderr)" ineffassign: ## run ineffassign @echo "🐳 $@" - @test -z "$$(ineffassign . | grep -v vendor/ | grep -v ".pb.go:" | grep -v ".mock.go" | tee /dev/stderr)" + @test -z "$$(ineffassign . | grep -v vendor/ | grep -v ".pb.go:" | tee /dev/stderr)" #errcheck: ## run go errcheck # @echo "🐳 $@" -# @test -z "$$(errcheck ./... | grep -v vendor/ | grep -v ".pb.go:" | grep -v ".mock.go" | tee /dev/stderr)" +# @test -z "$$(errcheck ./... | grep -v vendor/ | grep -v ".pb.go:" | tee /dev/stderr)" build: ## build the go packages @echo "🐳 $@" diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 0298bf0369..0000000000 --- a/circle.yml +++ /dev/null @@ -1,66 +0,0 @@ -machine: - environment: - OS: "linux" - ARCH: "amd64" - - PROTOC: "https://github.com/google/protobuf/releases/download/v3.2.0/protoc-3.2.0-linux-x86_64.zip" - - GOVERSION: "1.8.1" - GOPATH: "$HOME/.go_workspace" - - WORKDIR: "$GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME" - -# Disable default dependency management. -# This prevents go dependencies to be automatically installed in order to -# ensure we are exclusively relying on vendored deps. -# -# https://discuss.circleci.com/t/overriding-go-inference-in-the-dependencies-phase/660 -# https://robots.thoughtbot.com/configure-circleci-for-go -dependencies: - pre: - # Wipe out the default go install. - - sudo rm -rf /usr/local/go - - # Force the wipe out of GOPATH to make sure we're not relying on - # external dependencies. - - rm -rf "$GOPATH" - - override: - # Install Go - - wget "https://storage.googleapis.com/golang/go$GOVERSION.$OS-$ARCH.tar.gz" - - sudo tar -C /usr/local -xzf "go$GOVERSION.$OS-$ARCH.tar.gz" - - # Install protoc - - wget "$PROTOC" - - unzip -o "$(basename $PROTOC)" -d "$HOME" - - # Setup the GOPATH - - mkdir -p "$(dirname $WORKDIR)" - - cp -R "$HOME/$CIRCLE_PROJECT_REPONAME" "$WORKDIR" - - # Install dependencies - - cd "$WORKDIR" && make setup - - post: - # Display debugging information in CI logs - - go version - - env - -test: - pre: - # Ensure validation of dependencies - - cd "$WORKDIR" && git fetch origin - - cd "$WORKDIR" && if test -n "`git diff --stat=1000 origin/master | grep -E \"^[[:space:]]*vendor\"`"; then make dep-validate; fi - - override: - # Run all tests in a single pass to ensure we don't move to the next - # step in case of failure. - # - `all`: Format, build and tests. - # - `checkprotos`: Build and check the proto files *only* once all - # tests pass with checked-in generated code. - # - `coverage`: Generate coverage reports. - - cd "$WORKDIR" && make ci - - post: - # Report to codecov.io - - cd "$WORKDIR" && bash <(curl -s https://codecov.io/bash) diff --git a/manager/state/store/memory_test.go b/manager/state/store/memory_test.go index b4df214b0f..cd7740e734 100644 --- a/manager/state/store/memory_test.go +++ b/manager/state/store/memory_test.go @@ -2035,7 +2035,7 @@ func BenchmarkNodeConcurrency(b *testing.B) { var wg sync.WaitGroup for c := 0; c != 5; c++ { wg.Add(1) - go func() { + go func(c int) { defer wg.Done() for i := 0; i < b.N; i++ { _ = s.Update(func(tx1 Tx) error { @@ -2050,7 +2050,7 @@ func BenchmarkNodeConcurrency(b *testing.B) { return nil }) } - }() + }(c) } for c := 0; c != 5; c++ {