1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package winutil
import (
"reflect"
"testing"
"unsafe"
)
//lint:file-ignore U1000 Fields are unused but necessary for tests.
const (
localSystemSID = "S-1-5-18"
networkSID = "S-1-5-2"
)
func TestLookupPseudoUser(t *testing.T) {
localSystem, err := LookupPseudoUser(localSystemSID)
if err != nil {
t.Errorf("LookupPseudoUser(%q) error: %v", localSystemSID, err)
}
if localSystem.Gid != localSystemSID {
t.Errorf("incorrect Gid, got %q, want %q", localSystem.Gid, localSystemSID)
}
t.Logf("localSystem: %v", localSystem)
// networkSID is a built-in known group but not a pseudo-user.
_, err = LookupPseudoUser(networkSID)
if err == nil {
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 ln := len(slcs); ln != 1 {
t.Errorf("len(slcs) got %d, want 1", ln)
}
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)
}
}
|