pact-foundation / pact-go

Golang version of Pact. Pact is a contract testing framework for HTTP APIs and non-HTTP asynchronous messaging systems.
http://pact.io
MIT License
834 stars 104 forks source link

Running `make testrace` fails with `race detected during execution of test` #89

Closed rasmus-unity closed 5 years ago

rasmus-unity commented 5 years ago

We're running our unit tests with -race option, and when trying to introduce pact consumer tests, they fail with a race condition. Reproduced on latest master from https://github.com/pact-foundation/pact-go repo. We can probably find a way to run pact tests without race detection, but curious to know if this is an issue which should be fixed.

Software versions

Expected behaviour

Running pact tests with -race should pass

Actual behaviour

Fails with

==================
WARNING: DATA RACE
Read at 0x00c420148480 by main goroutine:
  runtime.mapaccess1_fast64()
      /usr/local/opt/go/libexec/src/runtime/hashmap_fast.go:110 +0x0
  github.com/pact-foundation/pact-go/client.(*ServiceManager).Stop()
      /Users/rasmuss/src/github.com/pact-foundation/pact-go/client/service_manager.go:65 +0x16d
  github.com/pact-foundation/pact-go/client.(*MockService).Stop()
      <autogenerated>:1 +0x51
  (...)

Previous write at 0x00c420148480 by goroutine 8:
  runtime.mapassign_fast64()
      /usr/local/opt/go/libexec/src/runtime/hashmap_fast.go:598 +0x0
  github.com/pact-foundation/pact-go/client.(*ServiceManager).addServiceMonitor()
      /Users/rasmuss/src/github.com/pact-foundation/pact-go/client/service_manager.go:41 +0x165

Goroutine 8 (running) created at:
  github.com/pact-foundation/pact-go/client.(*ServiceManager).Setup()
      /Users/rasmuss/src/github.com/pact-foundation/pact-go/client/service_manager.go:30 +0x1be
  github.com/pact-foundation/pact-go/client.(*MockService).Setup()
      <autogenerated>:1 +0x43
  github.com/pact-foundation/pact-go/dsl.newClient()
      /Users/rasmuss/src/github.com/pact-foundation/pact-go/dsl/client.go:43 +0x42
  (...)

Steps to reproduce

  1. git clone git@github.com:pact-foundation/pact-go.git
  2. cd pact-go
  3. make testrace

EDIT: Alternatively

  1. git clone git@github.com:pact-foundation/pact-go.git
  2. cd pact-go/examples/consumer/goconsumer
  3. go test -race -run TestPactConsumerLoginHandler_UserExists .

Result: Found 2 data race(s)

Relevent log files

Hope above is sufficient

mefellows commented 5 years ago

The mock server it starts is stateful, as it needs to confirm the the expected interactions for each test are actually made, so running the pact tests in parallel is not possible, unless you create multiple instances of the pact struct on different ports.

See https://github.com/pact-foundation/pact-go/blob/master/README.md#splitting-tests-across-multiple-files for some insight into how you might be able to achieve it

mefellows commented 5 years ago

Sorry, didn't mean to hit close. Will look into it and add some documentation for others

rasmus-unity commented 5 years ago

so running the pact tests in parallel is not possible

Probably a basic question, but even if I just run a single pact test, it still fails with race condition. Or do you mean something different?

rasmus-unity commented 5 years ago

Updated description above to include repro steps for issue when running single consumer pact test from pact-go/examples/consumer/goconsumer. Hope I understood correctly, that this should be possible?

mefellows commented 5 years ago

That's fantastic, thanks! It should be possible to run the test, so looks like a bug we can hunt down.

mefellows commented 5 years ago

Fix is now in master, but not in a tagged release. If you'd like to give this a go in your project @rasmus-unity that'd be great.

rasmus-unity commented 5 years ago

@mefellows, verified it works on our test suite also. thanks for the quick fix to this!

mefellows commented 5 years ago

Your welcome, thanks!