159 lines
4.1 KiB
Go
159 lines
4.1 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package verify
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestParseParamsExported(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
names []string
|
|
types []string
|
|
isPtr []bool
|
|
}{
|
|
{
|
|
input: "dst []byte, src []byte",
|
|
names: []string{"dst", "src"},
|
|
types: []string{"[]byte", "[]byte"},
|
|
isPtr: []bool{true, true},
|
|
},
|
|
{
|
|
input: "dst, src []byte",
|
|
names: []string{"dst", "src"},
|
|
types: []string{"[]byte", "[]byte"},
|
|
isPtr: []bool{true, true},
|
|
},
|
|
{
|
|
input: "a, b int",
|
|
names: []string{"a", "b"},
|
|
types: []string{"int", "int"},
|
|
isPtr: []bool{false, false},
|
|
},
|
|
{
|
|
input: "src []byte, dst []byte",
|
|
names: []string{"src", "dst"},
|
|
types: []string{"[]byte", "[]byte"},
|
|
isPtr: []bool{true, true},
|
|
},
|
|
{
|
|
input: "swin []int32, dstP []uint32, hist *[32]uint16",
|
|
names: []string{"swin", "dstP", "hist"},
|
|
types: []string{"[]int32", "[]uint32", "*[32]uint16"},
|
|
isPtr: []bool{true, true, true},
|
|
},
|
|
{
|
|
input: "n int, code int",
|
|
names: []string{"n", "code"},
|
|
types: []string{"int", "int"},
|
|
isPtr: []bool{false, false},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
params := parseParamsExported(tt.input)
|
|
if len(params) != len(tt.names) {
|
|
t.Errorf("parseParamsExported(%q): got %d params, want %d", tt.input, len(params), len(tt.names))
|
|
continue
|
|
}
|
|
for i, p := range params {
|
|
if p.Name != tt.names[i] {
|
|
t.Errorf("parseParamsExported(%q)[%d].Name = %q, want %q", tt.input, i, p.Name, tt.names[i])
|
|
}
|
|
if p.Typ != tt.types[i] {
|
|
t.Errorf("parseParamsExported(%q)[%d].Typ = %q, want %q", tt.input, i, p.Typ, tt.types[i])
|
|
}
|
|
if p.IsPointer() != tt.isPtr[i] {
|
|
t.Errorf("parseParamsExported(%q)[%d].IsPointer() = %v, want %v", tt.input, i, p.IsPointer(), tt.isPtr[i])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseBufSpec(t *testing.T) {
|
|
t.Run("empty", func(t *testing.T) {
|
|
specs, err := ParseBufSpec("")
|
|
if err != nil || len(specs) != 0 {
|
|
t.Errorf("ParseBufSpec(\"\") = %v, %v; want nil, nil", specs, err)
|
|
}
|
|
})
|
|
|
|
t.Run("single", func(t *testing.T) {
|
|
specs, err := ParseBufSpec("dst:64:zero")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(specs) != 1 || specs[0].Name != "dst" || specs[0].Size != 64 || specs[0].Pattern != "zero" {
|
|
t.Errorf("ParseBufSpec(\"dst:64:zero\") = %+v; want [{dst 64 zero}]", specs)
|
|
}
|
|
})
|
|
|
|
t.Run("multiple", func(t *testing.T) {
|
|
specs, err := ParseBufSpec("dst:64:zero,src:128:seq")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(specs) != 2 {
|
|
t.Fatalf("got %d specs, want 2", len(specs))
|
|
}
|
|
if specs[0].Name != "dst" || specs[1].Name != "src" {
|
|
t.Errorf("names = %s, %s; want dst, src", specs[0].Name, specs[1].Name)
|
|
}
|
|
})
|
|
|
|
t.Run("invalid", func(t *testing.T) {
|
|
_, err := ParseBufSpec("bad")
|
|
if err == nil {
|
|
t.Error("ParseBufSpec(\"bad\") should error")
|
|
}
|
|
})
|
|
|
|
t.Run("zero-size", func(t *testing.T) {
|
|
_, err := ParseBufSpec("dst:0:zero")
|
|
if err == nil {
|
|
t.Error("ParseBufSpec(\"dst:0:zero\") should error on zero size")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestBufPoolBuildArgs(t *testing.T) {
|
|
specs, err := ParseBufSpec("dst:64:seq,src:128:zero")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var pool BufPool
|
|
if err := pool.Alloc(specs); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer pool.Close()
|
|
|
|
// Layout for wideCopyAVX2(dst, src []byte): dst at 0, src at 24.
|
|
layout := []ArgOffset{
|
|
{Name: "dst", Typ: "[]byte", Offset: 0, Size: 24, IsPtr: true},
|
|
{Name: "src", Typ: "[]byte", Offset: 24, Size: 24, IsPtr: true},
|
|
}
|
|
args := pool.BuildArgs(layout, 48)
|
|
|
|
// dst.ptr should be non-zero.
|
|
if args[0] == 0 && args[1] == 0 && args[2] == 0 && args[3] == 0 {
|
|
t.Error("dst.ptr is zero; expected a buffer address")
|
|
}
|
|
// dst.len should be 64 (0x40).
|
|
if args[8] != 0x40 {
|
|
t.Errorf("dst.len = %d, want 64", args[8])
|
|
}
|
|
// dst.cap should be 64.
|
|
if args[16] != 0x40 {
|
|
t.Errorf("dst.cap = %d, want 64", args[16])
|
|
}
|
|
// src.ptr should be non-zero.
|
|
if args[24] == 0 && args[25] == 0 && args[26] == 0 && args[27] == 0 {
|
|
t.Error("src.ptr is zero; expected a buffer address")
|
|
}
|
|
// src.len should be 128 (0x80).
|
|
if args[32] != 0x80 {
|
|
t.Errorf("src.len = %d, want 128", args[32])
|
|
}
|
|
}
|