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 func TestHas(t *testing.T) {
140 Detect()
141 defer Detect()
142 feats := CPU.FeatureSet()
143 for _, feat := range feats {
144 f := ParseFeature(feat)
145 if f == UNKNOWN {
146 t.Error("Got unknown feature:", feat)
147 continue
148 }
149 if !CPU.Has(f) {
150 t.Error("CPU.Has returned false, want true")
151 }
152 if !CPU.Supports(f) {
153 t.Error("CPU.Supports returned false, want true")
154 }
155
156 CPU.Disable(f)
157 if CPU.Has(f) {
158 t.Error("CPU.Has returned true, want false")
159 }
160 if CPU.Supports(f) {
161 t.Error("CPU.Supports returned true, want false")
162 }
163
164 CPU.Enable(f)
165 if !CPU.Has(f) {
166 t.Error("CPU.Has returned false, want true")
167 }
168 if !CPU.Supports(f) {
169 t.Error("CPU.Supports returned false, want true")
170 }
171 }
172 }
173
174
175 func TestSGXLC(t *testing.T) {
176 got := CPU.SGX.LaunchControl
177 expected := CPU.featureSet.inSet(SGXLC)
178 if got != expected {
179 t.Fatalf("SGX: expected %v, got %v", expected, got)
180 }
181 t.Log("SGX Launch Control Support:", got)
182 }
183
184
185 func TestVM(t *testing.T) {
186 got := CPU.VM()
187 expected := CPU.featureSet.inSet(HYPERVISOR)
188 if got != expected {
189 t.Fatalf("TestVM: expected %v, got %v", expected, got)
190 }
191 t.Log("TestVM:", got)
192 }
193
194
195 func TestRtCounter(t *testing.T) {
196 a := CPU.RTCounter()
197 b := CPU.RTCounter()
198 t.Log("CPU Counter:", a, b, b-a)
199 }
200
201
202 func TestIa32TscAux(t *testing.T) {
203 ecx := CPU.Ia32TscAux()
204 t.Logf("Ia32TscAux:0x%x\n", ecx)
205 if ecx != 0 {
206 chip := (ecx & 0xFFF000) >> 12
207 core := ecx & 0xFFF
208 t.Log("Likely chip, core:", chip, core)
209 }
210 }
211
212 func TestThreadsPerCoreNZ(t *testing.T) {
213 if CPU.ThreadsPerCore == 0 {
214 t.Fatal("threads per core is zero")
215 }
216 }
217
218
219 func TestLogicalCPU(t *testing.T) {
220 t.Log("Currently executing on cpu:", CPU.LogicalCPU())
221 }
222
223 func TestMaxFunction(t *testing.T) {
224 expect := maxFunctionID()
225 if CPU.maxFunc != expect {
226 t.Fatal("Max function does not match, expected", expect, "but got", CPU.maxFunc)
227 }
228 expect = maxExtendedFunction()
229 if CPU.maxExFunc != expect {
230 t.Fatal("Max Extended function does not match, expected", expect, "but got", CPU.maxFunc)
231 }
232 }
233
234
235
236 func ExampleCPUInfo_Ia32TscAux() {
237 ecx := CPU.Ia32TscAux()
238 if ecx == 0 {
239 fmt.Println("Unknown CPU ID")
240 return
241 }
242 chip := (ecx & 0xFFF000) >> 12
243 core := ecx & 0xFFF
244 fmt.Println("Chip, Core:", chip, core)
245 }
246
247 func TestCombineFeatures(t *testing.T) {
248 cpu := CPU
249 for i := FeatureID(0); i < lastID; i++ {
250 if cpu.Has(i) != cpu.HasAll(CombineFeatures(i)) {
251 t.Errorf("id %d:%s mismatch", i, i.String())
252 }
253 }
254 }
255
256 func BenchmarkFlags(b *testing.B) {
257 var a bool
258 var cpu = CPU
259 b.Run("ids", func(b *testing.B) {
260 for i := 0; i < b.N; i++ {
261 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
262 }
263 _ = a
264 })
265 b.Run("features", func(b *testing.B) {
266 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)
267 for i := 0; i < b.N; i++ {
268 a = cpu.HasAll(f) || a
269 }
270 _ = a
271 })
272 b.Run("id", func(b *testing.B) {
273 for i := 0; i < b.N; i++ {
274 a = cpu.Has(CMOV) || a
275 }
276 _ = a
277 })
278 b.Run("feature", func(b *testing.B) {
279 f := CombineFeatures(CMOV)
280 for i := 0; i < b.N; i++ {
281 a = cpu.HasAll(f) || a
282 }
283 _ = a
284 })
285 }
286
View as plain text