diff --git a/mockresponder.go b/mockresponder.go index 5168b78..c39ac74 100644 --- a/mockresponder.go +++ b/mockresponder.go @@ -25,6 +25,11 @@ type MockResp struct { served bool } +func (mr MockResp) String() string { + // return fmt.Sprintf("%s/%d/%v/%s", mr.URL, mr.Code, mr.Err, string(mr.Data)) + return fmt.Sprintf("%s/%d/%v/%v", mr.URL, mr.Code, mr.Err, mr.served) +} + // MockRespList is a list of mocked responses, these are the responses that the // MockResponder serves, either sequentially or because of a RegEx match. type MockRespList []MockResp @@ -99,9 +104,19 @@ func defaultDoFunc(req *http.Request) (*http.Response, error) { break } - if !found { + // default to 200/OK + statusCode := data.Code + if statusCode == 0 { + statusCode = http.StatusOK + } + + if found { + // log.Printf("%s <%v>, %d: %v\n", req.Method, req.URL, statusCode, string(data.Data)) + log.Printf("%s <%v>, %d: %s\n", req.Method, req.URL, statusCode, data) + } else { for k, v := range mc.mockData { - fmt.Printf("%d: %v/%v/%v/%v\n", k, v.served, v.URL, v.Code, string(v.Data)) + log.Printf("%d: %v %v %v\n%v\n%v\n", k, v.served, v.URL, v.Code, sanitizeURL(req.URL.String()), string(v.Data)) + log.Println("**********") } panic("ran out of data") } @@ -110,12 +125,6 @@ func defaultDoFunc(req *http.Request) (*http.Response, error) { return nil, data.Err } - // default to 200/OK - statusCode := data.Code - if statusCode == 0 { - statusCode = http.StatusOK - } - resp := &http.Response{ StatusCode: statusCode, Body: io.NopCloser(bytes.NewReader([]byte(data.Data))), @@ -169,6 +178,7 @@ func (m *MockResponder) LastData() []byte { func (m *MockResponder) Empty() bool { for _, d := range m.mockData { if !d.served { + log.Println(d) return false } } diff --git a/mockresponder_test.go b/mockresponder_test.go index 4df8803..d2d64f4 100644 --- a/mockresponder_test.go +++ b/mockresponder_test.go @@ -7,7 +7,9 @@ import ( "net/http" "reflect" "runtime" + "sync" "testing" + "time" "github.com/stretchr/testify/assert" ) @@ -183,3 +185,52 @@ func Test_sanitizeURL(t *testing.T) { }) } } + +func Test_Race(t *testing.T) { + + mrClient, ctx := NewMockResponder() + data := MockRespList{ + MockResp{Code: 200}, + MockResp{Code: 200}, + } + mrClient.SetData(data) + + done := false + wg := sync.WaitGroup{} + wg.Add(2) + + mu := sync.Mutex{} + + get := func() { + req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "/bla", nil) + resp, _ := mrClient.Do(req) + defer resp.Body.Close() + io.ReadAll(resp.Body) + } + + go func() { + get() + wg.Done() + }() + + go func() { + get() + wg.Done() + }() + + go func() { + wg.Wait() + mu.Lock() + done = true + mu.Unlock() + }() + + doneCheck := func() bool { + mu.Lock() + defer mu.Unlock() + return done + } + + assert.Eventually(t, doneCheck, time.Second*5, time.Microsecond*50) + assert.True(t, mrClient.Empty()) +}