Open artmoskvin opened 3 weeks ago
If you run go test -race ./... you'll see something like:
go test -race ./...
=== RUN TestDockerImageManager_BuildImage/Build_image {"level":"debug","buildContextPath":"/workdir","time":"2024-08-29T15:41:30+02:00","message":"Building image"} ================== WARNING: DATA RACE Write at 0x00c00012e300 by goroutine 9: ??() -:0 +0x1026c7688 sync/atomic.CompareAndSwapInt32() <autogenerated>:1 +0x18 io.(*pipe).write() /opt/homebrew/Cellar/go/1.23.0/libexec/src/io/pipe.go:81 +0x70 io.(*PipeWriter).Write() /opt/homebrew/Cellar/go/1.23.0/libexec/src/io/pipe.go:161 +0x44 bufio.(*Writer).Flush() /opt/homebrew/Cellar/go/1.23.0/libexec/src/bufio/bufio.go:639 +0xc0 github.com/docker/docker/pkg/archive.CompressStream.(*BufioWriterPool).NewWriteCloserWrapper.func1() /Users/artemm/go/pkg/mod/github.com/docker/docker@v26.1.3+incompatible/pkg/pools/pools.go:130 +0x44 github.com/docker/docker/pkg/ioutils.(*writeCloserWrapper).Close() /Users/artemm/go/pkg/mod/github.com/docker/docker@v26.1.3+incompatible/pkg/ioutils/writers.go:43 +0x58 github.com/docker/docker/pkg/archive.(*Tarballer).Do.func1() /Users/artemm/go/pkg/mod/github.com/docker/docker@v26.1.3+incompatible/pkg/archive/archive.go:919 +0x108 runtime.deferreturn() /opt/homebrew/Cellar/go/1.23.0/libexec/src/runtime/panic.go:605 +0x5c github.com/docker/docker/pkg/archive.TarWithOptions.gowrap1() /Users/artemm/go/pkg/mod/github.com/docker/docker@v26.1.3+incompatible/pkg/archive/archive.go:849 +0x34 Previous read at 0x00c00012e300 by goroutine 8: reflect.typedmemmove() /opt/homebrew/Cellar/go/1.23.0/libexec/src/runtime/mbarrier.go:225 +0x0 reflect.packEface() /opt/homebrew/Cellar/go/1.23.0/libexec/src/reflect/value.go:133 +0xa4 reflect.valueInterface() /opt/homebrew/Cellar/go/1.23.0/libexec/src/reflect/value.go:1510 +0x148 reflect.Value.Interface() /opt/homebrew/Cellar/go/1.23.0/libexec/src/reflect/value.go:1481 +0x74 fmt.(*pp).printValue() /opt/homebrew/Cellar/go/1.23.0/libexec/src/fmt/print.go:769 +0x80 fmt.(*pp).printValue() /opt/homebrew/Cellar/go/1.23.0/libexec/src/fmt/print.go:921 +0xf70 fmt.(*pp).printArg() /opt/homebrew/Cellar/go/1.23.0/libexec/src/fmt/print.go:759 +0x8a0 fmt.(*pp).doPrintf() /opt/homebrew/Cellar/go/1.23.0/libexec/src/fmt/print.go:1173 +0xc58 fmt.Sprintf() /opt/homebrew/Cellar/go/1.23.0/libexec/src/fmt/print.go:239 +0x50 github.com/stretchr/testify/mock.Arguments.Diff() /Users/artemm/go/pkg/mod/github.com/stretchr/testify@v1.9.0/mock/mock.go:939 +0x13c github.com/stretchr/testify/mock.(*Mock).findExpectedCall() /Users/artemm/go/pkg/mod/github.com/stretchr/testify@v1.9.0/mock/mock.go:368 +0x118 github.com/stretchr/testify/mock.(*Mock).MethodCalled() /Users/artemm/go/pkg/mod/github.com/stretchr/testify@v1.9.0/mock/mock.go:476 +0x6c github.com/stretchr/testify/mock.(*Mock).Called() /Users/artemm/go/pkg/mod/github.com/stretchr/testify@v1.9.0/mock/mock.go:466 +0x150 github.com/artmoskvin/hide/pkg/devcontainer/mocks.(*MockDockerImageClient).ImageBuild() /Users/artemm/Code/hide/pkg/devcontainer/mocks/mock_docker_image_client.go:22 +0x180 github.com/artmoskvin/hide/pkg/devcontainer.(*DockerImageManager).BuildImage() /Users/artemm/Code/hide/pkg/devcontainer/image_manager.go:117 +0x8b8 github.com/artmoskvin/hide/pkg/devcontainer_test.TestDockerImageManager_BuildImage.func10() /Users/artemm/Code/hide/pkg/devcontainer/image_manager_test.go:247 +0x2b8 testing.tRunner() /opt/homebrew/Cellar/go/1.23.0/libexec/src/testing/testing.go:1690 +0x184 testing.(*T).Run.gowrap1() /opt/homebrew/Cellar/go/1.23.0/libexec/src/testing/testing.go:1743 +0x40 Goroutine 9 (running) created at: github.com/docker/docker/pkg/archive.TarWithOptions() /Users/artemm/go/pkg/mod/github.com/docker/docker@v26.1.3+incompatible/pkg/archive/archive.go:849 +0xa4 github.com/artmoskvin/hide/pkg/devcontainer.(*DockerImageManager).BuildImage() /Users/artemm/Code/hide/pkg/devcontainer/image_manager.go:90 +0x3b4 github.com/artmoskvin/hide/pkg/devcontainer_test.TestDockerImageManager_BuildImage.func10() /Users/artemm/Code/hide/pkg/devcontainer/image_manager_test.go:247 +0x2b8 testing.tRunner() /opt/homebrew/Cellar/go/1.23.0/libexec/src/testing/testing.go:1690 +0x184 testing.(*T).Run.gowrap1() /opt/homebrew/Cellar/go/1.23.0/libexec/src/testing/testing.go:1743 +0x40 Goroutine 8 (running) created at: testing.(*T).Run() /opt/homebrew/Cellar/go/1.23.0/libexec/src/testing/testing.go:1743 +0x5e0 github.com/artmoskvin/hide/pkg/devcontainer_test.TestDockerImageManager_BuildImage() /Users/artemm/Code/hide/pkg/devcontainer/image_manager_test.go:241 +0x5ec testing.tRunner() /opt/homebrew/Cellar/go/1.23.0/libexec/src/testing/testing.go:1690 +0x184 testing.(*T).Run.gowrap1() /opt/homebrew/Cellar/go/1.23.0/libexec/src/testing/testing.go:1743 +0x40 ================== {"level":"debug","tag":"test:latest","time":"2024-08-29T15:41:30+02:00","message":"Built image"} testing.go:1399: race detected during execution of test --- FAIL: TestDockerImageManager_BuildImage/Build_image (0.00s)
I suspect the problem is in the io.Reader returned by the archive.TarWithOptions() call. The archive is created asynchronously by go tb.Do():
io.Reader
archive.TarWithOptions()
go tb.Do()
func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { tb, err := NewTarballer(srcPath, options) if err != nil { return nil, err } go tb.Do() return tb.Reader(), nil }
At the same time the mock library tries to get a string representation of the args, one of which is the aforementioned io.Reader, at which point the race condition occurs.
If you run
go test -race ./...
you'll see something like:I suspect the problem is in the
io.Reader
returned by thearchive.TarWithOptions()
call. The archive is created asynchronously bygo tb.Do()
:At the same time the mock library tries to get a string representation of the args, one of which is the aforementioned
io.Reader
, at which point the race condition occurs.