Open
Description
MockServer version
5.15.0
To Reproduce
- Declare 2 endpoints, with a XML body matcher, and two different bodies/responses
- Call these endpoints concurrently
- Sometimes, the correct response is returned for the call. Sometimes, the other response is returned, sometimes we get a 404
Expected behaviour
Always have the expected response.
Other info
It looks like the issue has already been encountered, but without enough info: #901
It only happens with XML body matcher. Other matchers seem OK with concurrency.
Reproduction test
package testing
import (
"bytes"
"fmt"
"net/http"
"sync"
"testing"
"time"
"github.com/go-resty/resty/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type RequestMatcher struct {
Method string `json:"method,omitempty"`
Path string `json:"path,omitempty"`
Body BodyMatcher `json:"body,omitempty"`
}
type BodyMatcher struct {
Type string `json:"type,omitempty"`
XML string `json:"xml,omitempty"`
}
type Expectation struct {
Request RequestMatcher `json:"httpRequest,omitempty"`
Response Response `json:"httpResponse,omitempty"`
Priority int32 `json:"priority,omitempty"`
}
type Response struct {
Body string `json:"body,omitempty"`
Headers map[string][]string `json:"headers,omitempty"`
StatusCode int32 `json:"statusCode,omitempty"`
}
func resetExpectations(t *testing.T) {
t.Helper()
c := resty.New().SetBaseURL(fmt.Sprintf("http://%s:%d", "mockserver", 46311))
resp, err := c.NewRequest().
Put("mockserver/reset")
assert.NoError(t, err, "")
assert.Equal(t, http.StatusOK, resp.StatusCode())
}
func createExpectations(t *testing.T) {
t.Helper()
c := resty.New().SetBaseURL(fmt.Sprintf("http://%s:%d", "mockserver", 46311))
c.NewRequest().
SetDoNotParseResponse(true).
SetBody(Expectation{
Request: RequestMatcher{
Method: "POST",
Path: "/Test",
Body: BodyMatcher{
Type: "XML",
XML: "<a>1</a>",
},
},
Response: Response{
Body: "<r>1</r>",
},
}).Put("/mockserver/expectation")
c.NewRequest().
SetDoNotParseResponse(true).
SetBody(Expectation{
Request: RequestMatcher{
Method: "POST",
Path: "/Test",
Body: BodyMatcher{
Type: "XML",
XML: "<a>2</a>",
},
},
Response: Response{
Body: "<r>2</r>",
},
}).Put("/mockserver/expectation")
}
func TestCall(t *testing.T) {
resetExpectations(t)
createExpectations(t)
c := resty.New().SetBaseURL(fmt.Sprintf("http://%s:%d", "mockserver", 46311)).SetDoNotParseResponse(true)
call := func(source string) {
resp, err := c.NewRequest().SetBody("<a>1</a>").Post("/Test")
require.NoError(t, err)
buf := new(bytes.Buffer)
buf.ReadFrom(resp.RawResponse.Body)
assert.Equal(t, "<r>1</r>", buf.String(), source)
// ===========
resp, err = c.NewRequest().SetBody("<a>2</a>").Post("/Test")
require.NoError(t, err)
buf = new(bytes.Buffer)
buf.ReadFrom(resp.RawResponse.Body)
assert.Equal(t, "<r>2</r>", buf.String(), source)
}
iterations := 10
// This loop won't fail
for i := 0; i < iterations; i++ {
call("sequential")
}
var wg sync.WaitGroup
wg.Add(iterations)
// This loop will fail
for i := 0; i < iterations; i++ {
time.Sleep(10 * time.Millisecond)
go func() {
call("parallel")
wg.Done()
}()
}
wg.Wait()
}
Result and log file
I joined the Go test output, and the mockserver logs for iterations := 5
(we have a 404 and a confusion)
Metadata
Metadata
Assignees
Labels
No labels