h2non / gock

HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽
https://pkg.go.dev/github.com/h2non/gock
MIT License
2.04k stars 106 forks source link

Setting BodyString on a Request causes nil pointer dereference #70

Open mrcnski opened 4 years ago

mrcnski commented 4 years ago

Setting BodyString to anything causes the test to crash.

    gock.New(skynet.DefaultDownloadOptions.PortalURL).
        Get(urlpath).
        BodyString("form-data").
        Reply(200).
        BodyString("test\n")
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x10d3070]

goroutine 7 [running]:
testing.tRunner.func1(0xc000104100)
    /usr/local/Cellar/go/1.13.6/libexec/src/testing/testing.go:874 +0x3a3
panic(0x1318620, 0x15f7420)
    /usr/local/Cellar/go/1.13.6/libexec/src/runtime/panic.go:679 +0x1b2
io/ioutil.readAll.func1(0xc00012b600)
    /usr/local/Cellar/go/1.13.6/libexec/src/io/ioutil/ioutil.go:30 +0x101
panic(0x1318620, 0x15f7420)
    /usr/local/Cellar/go/1.13.6/libexec/src/runtime/panic.go:679 +0x1b2
bytes.(*Buffer).ReadFrom(0xc00012b598, 0x0, 0x0, 0x1620940, 0xc00012b5c0, 0x12c76b8)
    /usr/local/Cellar/go/1.13.6/libexec/src/bytes/buffer.go:204 +0x80
io/ioutil.readAll(0x0, 0x0, 0x200, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.13.6/libexec/src/io/ioutil/ioutil.go:36 +0x100
io/ioutil.ReadAll(...)
    /usr/local/Cellar/go/1.13.6/libexec/src/io/ioutil/ioutil.go:45
gopkg.in/h2non/gock%2ev1.MatchBody(0xc00017c000, 0xc000148270, 0xc00012b601, 0x0, 0x0)
    /Users/marcin/go/pkg/mod/gopkg.in/h2non/gock.v1@v1.0.15/matchers.go:169 +0x10c
gopkg.in/h2non/gock%2ev1.(*MockMatcher).Match(0xc00015a0c0, 0xc00017c000, 0xc000148270, 0x161fde0, 0x2, 0xa)
    /Users/marcin/go/pkg/mod/gopkg.in/h2non/gock.v1@v1.0.15/matcher.go:111 +0x77
gopkg.in/h2non/gock%2ev1.(*Mocker).Match(0xc00014a240, 0xc00017c000, 0x1, 0x8, 0xc00012b758)
    /Users/marcin/go/pkg/mod/gopkg.in/h2non/gock.v1@v1.0.15/mock.go:113 +0x143
gopkg.in/h2non/gock%2ev1.MatchMock(0xc00017c000, 0x30, 0x13616c0, 0xc00012b800, 0x4500000)
    /Users/marcin/go/pkg/mod/gopkg.in/h2non/gock.v1@v1.0.15/matcher.go:126 +0x7b
gopkg.in/h2non/gock%2ev1.(*Transport).RoundTrip(0xc00000e3a0, 0xc00017c000, 0x0, 0x0, 0x0)
    /Users/marcin/go/pkg/mod/gopkg.in/h2non/gock.v1@v1.0.15/transport.go:59 +0xae
net/http.send(0xc00017c000, 0x13ea1c0, 0xc00000e3a0, 0x0, 0x0, 0x0, 0xc00015c028, 0x203000, 0x1, 0x0)
    /usr/local/Cellar/go/1.13.6/libexec/src/net/http/client.go:250 +0x443
net/http.(*Client).send(0x1602fc0, 0xc00017c000, 0x0, 0x0, 0x0, 0xc00015c028, 0x0, 0x1, 0x136efc0)
    /usr/local/Cellar/go/1.13.6/libexec/src/net/http/client.go:174 +0xfa
net/http.(*Client).do(0x1602fc0, 0xc00017c000, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.13.6/libexec/src/net/http/client.go:641 +0x3ce
net/http.(*Client).Do(...)
    /usr/local/Cellar/go/1.13.6/libexec/src/net/http/client.go:509
net/http.(*Client).Get(0x1602fc0, 0xc00017a000, 0x1d, 0x2, 0x2, 0xc00017a000)
    /usr/local/Cellar/go/1.13.6/libexec/src/net/http/client.go:398 +0xbb
net/http.Get(...)
    /usr/local/Cellar/go/1.13.6/libexec/src/net/http/client.go:370
github.com/NebulousLabs/go-skynet.DownloadFile(0xc0001780c0, 0x53, 0x137e311, 0x10, 0x137a32c, 0x1, 0x137ec6b, 0x12, 0x0, 0x0)
    /Users/marcin/Dropbox/Repos/go-skynet/skynet.go:234 +0x1d8
github.com/NebulousLabs/go-skynet/tests.TestUploadAndDownloadFile(0xc000104100)
    /Users/marcin/Dropbox/Repos/go-skynet/tests/integration_test.go:65 +0x693
testing.tRunner(0xc000104100, 0x1393778)
    /usr/local/Cellar/go/1.13.6/libexec/src/testing/testing.go:909 +0xc9
created by testing.(*T).Run
    /usr/local/Cellar/go/1.13.6/libexec/src/testing/testing.go:960 +0x350
FAIL    github.com/NebulousLabs/go-skynet/tests 0.340s
h2non commented 4 years ago

This seems to be related to concurrent shared memory access. Serialized access might be needed at that level.

Could you provide a more representative code example of how you are running multiple goroutines that access the gock instance?

mrcnski commented 4 years ago

Sure, I reproduced it here (last commit ce814c8) by adding BodyString("test"). to line 75.