@ -4,9 +4,13 @@
package winutil
package winutil
import (
import (
"reflect"
"testing"
"testing"
"unsafe"
)
)
//lint:file-ignore U1000 Fields are unused but necessary for tests.
const (
const (
localSystemSID = "S-1-5-18"
localSystemSID = "S-1-5-18"
networkSID = "S-1-5-2"
networkSID = "S-1-5-2"
@ -28,3 +32,103 @@ func TestLookupPseudoUser(t *testing.T) {
t . Errorf ( "LookupPseudoUser(%q) unexpectedly succeeded" , networkSID )
t . Errorf ( "LookupPseudoUser(%q) unexpectedly succeeded" , networkSID )
}
}
}
}
type testType interface {
byte | uint16 | uint32 | uint64
}
type noPointers [ T testType ] struct {
foo byte
bar T
baz bool
}
type hasPointer struct {
foo byte
bar uint32
s1 * struct { }
baz byte
}
func checkContiguousBuffer [ T any , BU BufUnit ] ( t * testing . T , extra [ ] BU , pt * T , ptLen uint32 , slcs [ ] [ ] BU ) {
szBU := int ( unsafe . Sizeof ( BU ( 0 ) ) )
expectedAlign := max ( reflect . TypeFor [ T ] ( ) . Align ( ) , szBU )
// Check that pointer is aligned
if rem := uintptr ( unsafe . Pointer ( pt ) ) % uintptr ( expectedAlign ) ; rem != 0 {
t . Errorf ( "pointer alignment got %d, want 0" , rem )
}
// Check that alloc length is aligned
if rem := int ( ptLen ) % expectedAlign ; rem != 0 {
t . Errorf ( "allocation length alignment got %d, want 0" , rem )
}
expectedLen := int ( unsafe . Sizeof ( * pt ) )
expectedLen = alignUp ( expectedLen , szBU )
expectedLen += len ( extra ) * szBU
expectedLen = alignUp ( expectedLen , expectedAlign )
if gotLen := int ( ptLen ) ; gotLen != expectedLen {
t . Errorf ( "allocation length got %d, want %d" , gotLen , expectedLen )
}
if l := len ( slcs ) ; l != 1 {
t . Errorf ( "len(slcs) got %d, want 1" , l )
}
if len ( extra ) == 0 && slcs [ 0 ] != nil {
t . Error ( "slcs[0] got non-nil, want nil" )
}
if len ( extra ) != len ( slcs [ 0 ] ) {
t . Errorf ( "len(slcs[0]) got %d, want %d" , len ( slcs [ 0 ] ) , len ( extra ) )
} else if rem := uintptr ( unsafe . Pointer ( unsafe . SliceData ( slcs [ 0 ] ) ) ) % uintptr ( szBU ) ; rem != 0 {
t . Errorf ( "additional data alignment got %d, want 0" , rem )
}
}
func TestAllocateContiguousBuffer ( t * testing . T ) {
t . Run ( "NoValues" , testNoValues )
t . Run ( "NoPointers" , testNoPointers )
t . Run ( "HasPointer" , testHasPointer )
}
func testNoValues ( t * testing . T ) {
defer func ( ) {
if r := recover ( ) ; r == nil {
t . Error ( "expected panic but didn't get one" )
}
} ( )
AllocateContiguousBuffer [ hasPointer , byte ] ( )
}
const maxTestBufLen = 8
func testNoPointers ( t * testing . T ) {
buf8 := make ( [ ] byte , maxTestBufLen )
buf16 := make ( [ ] uint16 , maxTestBufLen )
for i := range maxTestBufLen {
s8 , sl , slcs8 := AllocateContiguousBuffer [ noPointers [ byte ] ] ( buf8 [ : i ] )
checkContiguousBuffer ( t , buf8 [ : i ] , s8 , sl , slcs8 )
s16 , sl , slcs8 := AllocateContiguousBuffer [ noPointers [ uint16 ] ] ( buf8 [ : i ] )
checkContiguousBuffer ( t , buf8 [ : i ] , s16 , sl , slcs8 )
s32 , sl , slcs8 := AllocateContiguousBuffer [ noPointers [ uint32 ] ] ( buf8 [ : i ] )
checkContiguousBuffer ( t , buf8 [ : i ] , s32 , sl , slcs8 )
s64 , sl , slcs8 := AllocateContiguousBuffer [ noPointers [ uint64 ] ] ( buf8 [ : i ] )
checkContiguousBuffer ( t , buf8 [ : i ] , s64 , sl , slcs8 )
s8 , sl , slcs16 := AllocateContiguousBuffer [ noPointers [ byte ] ] ( buf16 [ : i ] )
checkContiguousBuffer ( t , buf16 [ : i ] , s8 , sl , slcs16 )
s16 , sl , slcs16 = AllocateContiguousBuffer [ noPointers [ uint16 ] ] ( buf16 [ : i ] )
checkContiguousBuffer ( t , buf16 [ : i ] , s16 , sl , slcs16 )
s32 , sl , slcs16 = AllocateContiguousBuffer [ noPointers [ uint32 ] ] ( buf16 [ : i ] )
checkContiguousBuffer ( t , buf16 [ : i ] , s32 , sl , slcs16 )
s64 , sl , slcs16 = AllocateContiguousBuffer [ noPointers [ uint64 ] ] ( buf16 [ : i ] )
checkContiguousBuffer ( t , buf16 [ : i ] , s64 , sl , slcs16 )
}
}
func testHasPointer ( t * testing . T ) {
buf8 := make ( [ ] byte , maxTestBufLen )
buf16 := make ( [ ] uint16 , maxTestBufLen )
for i := range maxTestBufLen {
s , sl , slcs8 := AllocateContiguousBuffer [ hasPointer ] ( buf8 [ : i ] )
checkContiguousBuffer ( t , buf8 [ : i ] , s , sl , slcs8 )
s , sl , slcs16 := AllocateContiguousBuffer [ hasPointer ] ( buf16 [ : i ] )
checkContiguousBuffer ( t , buf16 [ : i ] , s , sl , slcs16 )
}
}