@@ -8,7 +8,6 @@ package mimirpb
88import (
99 "testing"
1010 "time"
11- "unsafe"
1211
1312 "github.com/prometheus/prometheus/model/histogram"
1413 "github.com/stretchr/testify/assert"
@@ -17,6 +16,7 @@ import (
1716 "google.golang.org/grpc/encoding/proto"
1817 "google.golang.org/grpc/mem"
1918
19+ "github.com/grafana/mimir/pkg/mimirpb/internal"
2020 "github.com/grafana/mimir/pkg/util/test"
2121)
2222
@@ -208,7 +208,7 @@ func TestCodecV2_Unmarshal(t *testing.T) {
208208
209209 require .True (t , origReq .Equal (req ))
210210
211- require .NotNil (t , req .buffer )
211+ require .NotNil (t , req .Buffer )
212212 req .FreeBuffer ()
213213}
214214
@@ -258,44 +258,36 @@ func TestInstrumentRefLeaks(t *testing.T) {
258258 buf , err := src .Marshal ()
259259 require .NoError (t , err )
260260
261- var req WriteRequest
262- err = Unmarshal (buf , & req )
263- require .NoError (t , err )
264-
265- bufAddr := uintptr (unsafe .Pointer (unsafe .SliceData (req .buffer .ReadOnlyData ())))
266- // Label names are UnsafeMutableStrings pointing to buf. They shouldn't outlive
267- // the call to req.FreeBuffer.
268- leakingLabelName := req .Timeseries [0 ].Labels [0 ].Name
269-
270- leaks := NextRefLeakChannel (t .Context ())
261+ var leaks <- chan bool
262+ var leakingLabelName UnsafeMutableString
263+ func () {
264+ var req WriteRequest
265+ err = Unmarshal (buf , & req )
266+ require .NoError (t , err )
271267
272- recvLeak := func () (uintptr , bool ) {
273- select {
274- case detectedAddr := <- leaks :
275- return detectedAddr , true
276- case <- time .After (10 * time .Millisecond ):
277- return 0 , false
278- }
279- }
268+ // Label names are UnsafeMutableStrings pointing to buf. They shouldn't outlive
269+ // the call to req.FreeBuffer.
270+ leakingLabelName = req .Timeseries [0 ].Labels [0 ].Name
280271
281- req .FreeBuffer () // leakingLabelName becomes a leak here
272+ leaks = internal .NextRefLeakCheck (t .Context (), req .Buffer .ReadOnlyData ())
273+ req .FreeBuffer () // leakingLabelName becomes a leak here
274+ }()
282275
283276 // Expect to receive a leak detection.
284- detectedAddr , ok := recvLeak ()
285- require .True (t , ok , "expected a reference leak" )
286- require .Equal (t , bufAddr , detectedAddr )
277+ require .Eventually (t , func () bool { return <- leaks }, 10 * time .Millisecond , 1 * time .Second , "expected a reference leak" )
287278 // Expect the label name contents to have been replaced with a taint word.
288279 // Keep this check last, because we need to extend the lifespan of leakingLabelName
289280 // to avoid Go optimizing the leak away.
290281 require .Contains (t , leakingLabelName , "KAEL" )
291282
292283 // Now let's check a non-leak doesn't get falsely detected.
293- dataNoLeak , err := src .Marshal ()
294- require .NoError (t , err )
295- var reqNoLeak WriteRequest
296- err = Unmarshal (dataNoLeak , & reqNoLeak )
297- require .NoError (t , err )
298- leaks = NextRefLeakChannel (t .Context ())
299- detectedAddr , ok = recvLeak ()
300- require .False (t , ok , "unexpected a reference leak %x" , detectedAddr )
284+ func () {
285+ var reqNoLeak WriteRequest
286+ err = Unmarshal (buf , & reqNoLeak )
287+ require .NoError (t , err )
288+
289+ leaks = internal .NextRefLeakCheck (t .Context (), reqNoLeak .Buffer .ReadOnlyData ())
290+ reqNoLeak .FreeBuffer ()
291+ }()
292+ require .Eventually (t , func () bool { return ! <- leaks }, 10 * time .Millisecond , 1 * time .Second , "expected no reference leaks" )
301293}
0 commit comments