1
2
3 package cpuid
4
5 import (
6 "fmt"
7 "strings"
8 "testing"
9 )
10
11 func TestLastID(t *testing.T) {
12 if lastID.String() != "lastID" {
13 t.Fatal("stringer not updated, run go generate")
14 }
15 }
16
17 func TestLastVendorID(t *testing.T) {
18 if lastVendor.String() != "lastVendor" {
19 t.Fatal("stringer not updated, run go generate")
20 }
21 }
22
23
24
25 func TestCPUID(t *testing.T) {
26 Detect()
27 n := maxFunctionID()
28 t.Logf("Max Function:0x%x", n)
29 n = maxExtendedFunction()
30 t.Logf("Max Extended Function:0x%x", n)
31 t.Log("VendorString:", CPU.VendorString)
32 t.Log("VendorID:", CPU.VendorID)
33 t.Log("Name:", CPU.BrandName)
34 t.Log("PhysicalCores:", CPU.PhysicalCores)
35 t.Log("ThreadsPerCore:", CPU.ThreadsPerCore)
36 t.Log("LogicalCores:", CPU.LogicalCores)
37 t.Log("Family", CPU.Family, "Model:", CPU.Model, "Stepping:", CPU.Stepping)
38 t.Log("Features:", strings.Join(CPU.FeatureSet(), ","))
39 t.Log("Cacheline bytes:", CPU.CacheLine)
40 t.Log("L1 Instruction Cache:", CPU.Cache.L1I, "bytes")
41 t.Log("L1 Data Cache:", CPU.Cache.L1D, "bytes")
42 t.Log("L2 Cache:", CPU.Cache.L2, "bytes")
43 t.Log("L3 Cache:", CPU.Cache.L3, "bytes")
44 t.Log("Hz:", CPU.Hz, "Hz")
45 t.Log("VM:", CPU.VM())
46 t.Log("BoostFreq:", CPU.BoostFreq, "Hz")
47 }
48
49 func TestExample(t *testing.T) {
50 Detect()
51
52 fmt.Println("Name:", CPU.BrandName)
53 fmt.Println("PhysicalCores:", CPU.PhysicalCores)
54 fmt.Println("ThreadsPerCore:", CPU.ThreadsPerCore)
55 fmt.Println("LogicalCores:", CPU.LogicalCores)
56 fmt.Println("Family", CPU.Family, "Model:", CPU.Model, "Vendor ID:", CPU.VendorID)
57 fmt.Println("Features:", strings.Join(CPU.FeatureSet(), ","))
58 fmt.Println("Cacheline bytes:", CPU.CacheLine)
59 fmt.Println("L1 Data Cache:", CPU.Cache.L1D, "bytes")
60 fmt.Println("L1 Instruction Cache:", CPU.Cache.L1D, "bytes")
61 fmt.Println("L2 Cache:", CPU.Cache.L2, "bytes")
62 fmt.Println("L3 Cache:", CPU.Cache.L3, "bytes")
63 fmt.Println("Frequency", CPU.Hz, "hz")
64
65
66 if CPU.Supports(SSE, SSE2) {
67 fmt.Println("We have Streaming SIMD 2 Extensions")
68 }
69 }
70 func TestDumpCPUID(t *testing.T) {
71 n := int(maxFunctionID())
72 for i := 0; i <= n; i++ {
73 a, b, c, d := cpuidex(uint32(i), 0)
74 t.Logf("CPUID %08x: %08x-%08x-%08x-%08x", i, a, b, c, d)
75 ex := uint32(1)
76 for {
77 a2, b2, c2, d2 := cpuidex(uint32(i), ex)
78 if a2 == a && b2 == b && d2 == d || ex > 50 || a2 == 0 {
79 break
80 }
81 t.Logf("CPUID %08x: %08x-%08x-%08x-%08x", i, a2, b2, c2, d2)
82 a, b, c, d = a2, b2, c2, d2
83 ex++
84 }
85 }
86 n2 := maxExtendedFunction()
87 for i := uint32(0x80000000); i <= n2; i++ {
88 a, b, c, d := cpuid(i)
89 t.Logf("CPUID %08x: %08x-%08x-%08x-%08x", i, a, b, c, d)
90 }
91 }
92
93 func Example() {
94
95 fmt.Println("Name:", CPU.BrandName)
96 fmt.Println("PhysicalCores:", CPU.PhysicalCores)
97 fmt.Println("ThreadsPerCore:", CPU.ThreadsPerCore)
98 fmt.Println("LogicalCores:", CPU.LogicalCores)
99 fmt.Println("Family", CPU.Family, "Model:", CPU.Model)
100 fmt.Println("Features:", CPU.FeatureSet())
101 fmt.Println("Cacheline bytes:", CPU.CacheLine)
102 }
103
104 func TestBrandNameZero(t *testing.T) {
105 if len(CPU.BrandName) > 0 {
106
107 last := []byte(CPU.BrandName[len(CPU.BrandName)-1:])
108 if last[0] == 0 {
109 t.Fatal("last byte was zero")
110 } else if last[0] == 32 {
111 t.Fatal("whitespace wasn't trimmed")
112 }
113 }
114 }
115
116
117 func TestSGX(t *testing.T) {
118 got := CPU.SGX.Available
119 expected := CPU.featureSet.inSet(SGX)
120 if got != expected {
121 t.Fatalf("SGX: expected %v, got %v", expected, got)
122 }
123 t.Log("SGX Support:", got)
124
125 if CPU.SGX.Available {
126 var total uint64 = 0
127 leaves := false
128 for _, s := range CPU.SGX.EPCSections {
129 t.Logf("SGX EPC section: base address 0x%x, size %v", s.BaseAddress, s.EPCSize)
130 total += s.EPCSize
131 leaves = true
132 }
133 if leaves && total == 0 {
134 t.Fatal("SGX enabled without any available EPC memory")
135 }
136 }
137 }
138
139
140 func TestAMDMemEncryption(t *testing.T) {
141 got := CPU.AMDMemEncryption.Available
142 expected := CPU.featureSet.inSet(SME) || CPU.featureSet.inSet(SEV)
143 if got != expected {
144 t.Fatalf("AMDMemEncryption: expected %v, got %v", expected, got)
145 }
146 t.Log("AMDMemEncryption Support:", got)
147 }
148
149 func TestHas(t *testing.T) {
150 Detect()
151 defer Detect()
152 feats := CPU.FeatureSet()
153 for _, feat := range feats {
154 f := ParseFeature(feat)
155 if f == UNKNOWN {
156 t.Error("Got unknown feature:", feat)
157 continue
158 }
159 if !CPU.Has(f) {
160 t.Error("CPU.Has returned false, want true")
161 }
162 if !CPU.Supports(f) {
163 t.Error("CPU.Supports returned false, want true")
164 }
165
166 CPU.Disable(f)
167 if CPU.Has(f) {
168 t.Error("CPU.Has returned true, want false")
169 }
170 if CPU.Supports(f) {
171 t.Error("CPU.Supports returned true, want false")
172 }
173
174 CPU.Enable(f)
175 if !CPU.Has(f) {
176 t.Error("CPU.Has returned false, want true")
177 }
178 if !CPU.Supports(f) {
179 t.Error("CPU.Supports returned false, want true")
180 }
181 }
182 }
183
184
185 func TestSGXLC(t *testing.T) {
186 got := CPU.SGX.LaunchControl
187 expected := CPU.featureSet.inSet(SGXLC)
188 if got != expected {
189 t.Fatalf("SGX: expected %v, got %v", expected, got)
190 }
191 t.Log("SGX Launch Control Support:", got)
192 }
193
194
195 func TestVM(t *testing.T) {
196 got := CPU.VM()
197 expected := CPU.featureSet.inSet(HYPERVISOR)
198 if got != expected {
199 t.Fatalf("TestVM: expected %v, got %v", expected, got)
200 }
201 t.Log("TestVM:", got)
202 }
203
204
205 func TestRtCounter(t *testing.T) {
206 a := CPU.RTCounter()
207 b := CPU.RTCounter()
208 t.Log("CPU Counter:", a, b, b-a)
209 }
210
211
212 func TestIa32TscAux(t *testing.T) {
213 ecx := CPU.Ia32TscAux()
214 t.Logf("Ia32TscAux:0x%x\n", ecx)
215 if ecx != 0 {
216 chip := (ecx & 0xFFF000) >> 12
217 core := ecx & 0xFFF
218 t.Log("Likely chip, core:", chip, core)
219 }
220 }
221
222 func TestThreadsPerCoreNZ(t *testing.T) {
223 if CPU.ThreadsPerCore == 0 {
224 t.Fatal("threads per core is zero")
225 }
226 }
227
228
229 func TestLogicalCPU(t *testing.T) {
230 t.Log("Currently executing on cpu:", CPU.LogicalCPU())
231 }
232
233 func TestMaxFunction(t *testing.T) {
234 expect := maxFunctionID()
235 if CPU.maxFunc != expect {
236 t.Fatal("Max function does not match, expected", expect, "but got", CPU.maxFunc)
237 }
238 expect = maxExtendedFunction()
239 if CPU.maxExFunc != expect {
240 t.Fatal("Max Extended function does not match, expected", expect, "but got", CPU.maxFunc)
241 }
242 }
243
244
245
246 func ExampleCPUInfo_Ia32TscAux() {
247 ecx := CPU.Ia32TscAux()
248 if ecx == 0 {
249 fmt.Println("Unknown CPU ID")
250 return
251 }
252 chip := (ecx & 0xFFF000) >> 12
253 core := ecx & 0xFFF
254 fmt.Println("Chip, Core:", chip, core)
255 }
256
257 func TestCombineFeatures(t *testing.T) {
258 cpu := CPU
259 for i := FeatureID(0); i < lastID; i++ {
260 if cpu.Has(i) != cpu.HasAll(CombineFeatures(i)) {
261 t.Errorf("id %d:%s mismatch", i, i.String())
262 }
263 }
264 }
265
266 func BenchmarkFlags(b *testing.B) {
267 var a bool
268 var cpu = CPU
269 b.Run("ids", func(b *testing.B) {
270 for i := 0; i < b.N; i++ {
271 a = cpu.Supports(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE) || a
272 }
273 _ = a
274 })
275 b.Run("features", func(b *testing.B) {
276 f := CombineFeatures(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE)
277 for i := 0; i < b.N; i++ {
278 a = cpu.HasAll(f) || a
279 }
280 _ = a
281 })
282 b.Run("id", func(b *testing.B) {
283 for i := 0; i < b.N; i++ {
284 a = cpu.Has(CMOV) || a
285 }
286 _ = a
287 })
288 b.Run("feature", func(b *testing.B) {
289 f := CombineFeatures(CMOV)
290 for i := 0; i < b.N; i++ {
291 a = cpu.HasAll(f) || a
292 }
293 _ = a
294 })
295 }
296
View as plain text