diff --git a/internal/buffer/out_message_test.go b/internal/buffer/out_message_test.go index bf08110..77b7de9 100644 --- a/internal/buffer/out_message_test.go +++ b/internal/buffer/out_message_test.go @@ -1,11 +1,62 @@ package buffer import ( + "crypto/rand" "fmt" + "io" "testing" "unsafe" ) +func randBytes(n int) (b []byte, err error) { + b = make([]byte, n) + _, err = io.ReadFull(rand.Reader, b) + return +} + +func TestMemclr(t *testing.T) { + // All sizes up to 32 bytes. + var sizes []int + for i := 0; i <= 32; i++ { + sizes = append(sizes, i) + } + + // And a few hand-chosen sizes. + sizes = append(sizes, []int{ + 39, 41, 64, 127, 128, 129, + 1<<20 - 1, + 1 << 20, + 1<<20 + 1, + }...) + + // For each size, fill a buffer with random bytes and then zero it. + for _, size := range sizes { + size := size + t.Run(fmt.Sprintf("size=%d", size), func(t *testing.T) { + // Generate + b, err := randBytes(size) + if err != nil { + t.Fatalf("randBytes: %v", err) + } + + // Clear + var p unsafe.Pointer + if len(b) != 0 { + p = unsafe.Pointer(&b[0]) + } + + memclr(p, uintptr(len(b))) + + // Check + for i, x := range b { + if x != 0 { + t.Fatalf("non-zero byte %d at offset %d", x, i) + } + } + }) + } +} + func BenchmarkOutMessageReset(b *testing.B) { // A single buffer, which should fit in some level of CPU cache. b.Run("Single buffer", func(b *testing.B) {