mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-19 09:40:12 +00:00
66 lines
1.8 KiB
Go
66 lines
1.8 KiB
Go
package fixture
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/nezhahq/nezha/integration/agentcompat/internal/contract"
|
|
)
|
|
|
|
type retainedHeapReader struct {
|
|
reader io.Reader
|
|
baseline uint64
|
|
peak uint64
|
|
}
|
|
|
|
func verifyPayloadPeakRetainedHeap(reader io.Reader, expectedBytes uint64) (PayloadDigest, uint64, error) {
|
|
runtime.GC()
|
|
var baseline runtime.MemStats
|
|
runtime.ReadMemStats(&baseline)
|
|
measuredReader := &retainedHeapReader{reader: reader, baseline: baseline.HeapAlloc}
|
|
digest, err := VerifyPayload(measuredReader, expectedBytes)
|
|
return digest, measuredReader.peak, err
|
|
}
|
|
|
|
func (reader *retainedHeapReader) Read(destination []byte) (int, error) {
|
|
readBytes, err := reader.reader.Read(destination)
|
|
// Sampling after a forced collection measures the live heap retained by each
|
|
// streaming checkpoint instead of scheduler-dependent allocation churn.
|
|
runtime.GC()
|
|
var sample runtime.MemStats
|
|
runtime.ReadMemStats(&sample)
|
|
runtime.KeepAlive(destination)
|
|
if sample.HeapAlloc > reader.baseline {
|
|
reader.peak = max(reader.peak, sample.HeapAlloc-reader.baseline)
|
|
}
|
|
return readBytes, err
|
|
}
|
|
|
|
func TestFixture_PeakRetainedHeapDetectsRetainedAllocation(t *testing.T) {
|
|
// Given
|
|
reader := &allocationRetainingReader{reader: bytes.NewReader([]byte("x"))}
|
|
|
|
// When
|
|
_, peakRetainedHeap, err := verifyPayloadPeakRetainedHeap(reader, 1)
|
|
requireNoFixtureError(t, err)
|
|
|
|
// Then
|
|
if peakRetainedHeap <= contract.TransferHeapBytes {
|
|
t.Fatalf("peak retained heap = %d, want greater than %d", peakRetainedHeap, contract.TransferHeapBytes)
|
|
}
|
|
}
|
|
|
|
type allocationRetainingReader struct {
|
|
reader io.Reader
|
|
retained []byte
|
|
}
|
|
|
|
func (reader *allocationRetainingReader) Read(destination []byte) (int, error) {
|
|
if reader.retained == nil {
|
|
reader.retained = make([]byte, contract.TransferHeapBytes+1024*1024)
|
|
}
|
|
return reader.reader.Read(destination)
|
|
}
|