github.com/arthurnavah/cpuid/v2@v2.0.14/cpuid_test.go (about) 1 // Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. 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 // There is no real way to test a CPU identifier, since results will 24 // obviously differ on each machine. 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) 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 // Print basic CPU information: 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 // Test if we have these specific features: 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 // Print basic CPU information: 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 // Cut out last byte 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 // TestSGX tests SGX detection 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 // Disable it. 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 // Reenable 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 // TestSGXLC tests SGX Launch Control detection 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 // Test VM function 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 // Test RTCounter function 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 // Prints the value of Ia32TscAux() 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 // Prints the value of LogicalCPU() 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 // This example will calculate the chip/core number on Linux 235 // Linux encodes numa id (<<12) and core id (8bit) into TSC_AUX. 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 }