mirror of
https://github.com/pgsty/minio.git
synced 2026-08-08 23:33:30 +03:00
test(s3select): stop racing minio-go's parser for the response body
SelectResults spawns a parser goroutine that drains and closes the response body when the stream ends; deferring res.Close() had the test drain and close the same bytes.Reader concurrently, which the race detector catches reliably. Give the test body a close signal and wait for the parser to finish instead of competing with it. The double-close lives in minio-go's client parser, which no server code path uses; it remains worth an upstream report. Co-authored-by: ChatGPT <noreply@openai.com> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ import (
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/klauspost/cpuid/v2"
|
||||
@@ -70,6 +71,17 @@ func (w *testResponseWriter) WriteHeader(statusCode int) {
|
||||
func (w *testResponseWriter) Flush() {
|
||||
}
|
||||
|
||||
type testResponseBody struct {
|
||||
io.Reader
|
||||
closed chan struct{}
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func (b *testResponseBody) Close() error {
|
||||
b.closeOnce.Do(func() { close(b.closed) })
|
||||
return nil
|
||||
}
|
||||
|
||||
func evaluateSelectForTest(t *testing.T, requestXML, input []byte) ([]byte, error) {
|
||||
t.Helper()
|
||||
|
||||
@@ -85,18 +97,24 @@ func evaluateSelectForTest(t *testing.T, requestXML, input []byte) ([]byte, erro
|
||||
s3Select.Evaluate(w)
|
||||
s3Select.Close()
|
||||
|
||||
body := &testResponseBody{
|
||||
Reader: bytes.NewReader(w.response),
|
||||
closed: make(chan struct{}),
|
||||
}
|
||||
resp := http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(bytes.NewReader(w.response)),
|
||||
Body: body,
|
||||
ContentLength: int64(len(w.response)),
|
||||
}
|
||||
res, err := minio.NewSelectResults(&resp, "testbucket")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer res.Close()
|
||||
|
||||
return io.ReadAll(res)
|
||||
result, readErr := io.ReadAll(res)
|
||||
// minio-go's parser closes the response after signaling EOF or an event
|
||||
// error. Wait for that owner instead of racing it with SelectResults.Close.
|
||||
<-body.closed
|
||||
return result, readErr
|
||||
}
|
||||
|
||||
func TestJSONLinesRejectsOversizedRecord(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user