1// Copyright 2019 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// +build linux
15
16package procfs
17
18import "testing"
19
20const (
21	cpuinfoArm7Legacy = `
22Processor : ARMv7 Processor rev 5 (v7l)
23processor : 0
24BogoMIPS : 2400.00
25
26processor : 1
27BogoMIPS : 2400.00
28
29Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpv4 idiva idivt
30CPU implementer : 0x41
31CPU architecture: 7
32CPU variant : 0x0
33CPU part : 0xc07
34CPU revision : 5
35
36Hardware : sun8i
37Revision : 0000
38Serial : 5400503583203c3c040e`
39
40	cpuinfoArm7LegacyV1 = `
41Processor       : ARMv6-compatible processor rev 5 (v6l)
42BogoMIPS        : 791.34
43Features        : swp half thumb fastmult vfp edsp java
44CPU implementer : 0x41
45CPU architecture: 6TEJ
46CPU variant     : 0x1
47CPU part        : 0xb36
48CPU revision    : 5
49
50Hardware        : IMAPX200
51Revision        : 0000
52Serial          : 0000000000000000`
53
54	cpuinfoArm7 = `
55processor : 0
56model name : ARMv7 Processor rev 3 (v7l)
57BogoMIPS : 108.00
58Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
59CPU implementer : 0x41
60CPU architecture: 7
61CPU variant : 0x0
62CPU part : 0xd08
63CPU revision : 3
64
65processor : 1
66model name : ARMv7 Processor rev 3 (v7l)
67BogoMIPS : 108.00
68Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
69CPU implementer : 0x41
70CPU architecture: 7
71CPU variant : 0x0
72CPU part : 0xd08
73CPU revision : 3
74
75processor : 2
76model name : ARMv7 Processor rev 3 (v7l)
77BogoMIPS : 108.00
78Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
79CPU implementer : 0x41
80CPU architecture: 7
81CPU variant : 0x0
82CPU part : 0xd08
83CPU revision : 3
84
85processor : 3
86model name : ARMv7 Processor rev 3 (v7l)
87BogoMIPS : 108.00
88Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
89CPU implementer : 0x41
90CPU architecture: 7
91CPU variant : 0x0
92CPU part : 0xd08
93CPU revision : 3
94
95Hardware : BCM2835
96Revision : c03111
97`
98
99	cpuinfoS390x = `
100vendor_id       : IBM/S390
101# processors    : 4
102bogomips per cpu: 3033.00
103max thread id   : 0
104features	: esan3 zarch stfle msa ldisp eimm dfp edat etf3eh highgprs te vx sie
105facilities      : 0 1 2 3 4 6 7 8 9 10 12 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 30 31 32 33 34 35 36 37 40 41 42 43 44 45 46 47 48 49 50 51 52 53 55 57 73 74 75 76 77 80 81 82 128 129 131
106cache0          : level=1 type=Data scope=Private size=128K line_size=256 associativity=8
107cache1          : level=1 type=Instruction scope=Private size=96K line_size=256 associativity=6
108cache2          : level=2 type=Data scope=Private size=2048K line_size=256 associativity=8
109cache3          : level=2 type=Instruction scope=Private size=2048K line_size=256 associativity=8
110cache4          : level=3 type=Unified scope=Shared size=65536K line_size=256 associativity=16
111cache5          : level=4 type=Unified scope=Shared size=491520K line_size=256 associativity=30
112processor 0: version = FF,  identification = 2733E8,  machine = 2964
113processor 1: version = FF,  identification = 2733E8,  machine = 2964
114processor 2: version = FF,  identification = 2733E8,  machine = 2964
115processor 3: version = FF,  identification = 2733E8,  machine = 2964
116
117cpu number      : 0
118cpu MHz dynamic : 5000
119cpu MHz static  : 5000
120
121cpu number      : 1
122cpu MHz dynamic : 5000
123cpu MHz static  : 5000
124
125cpu number      : 2
126cpu MHz dynamic : 5000
127cpu MHz static  : 5000
128
129cpu number      : 3
130cpu MHz dynamic : 5000
131cpu MHz static  : 5000
132`
133
134	cpuinfoMips = `
135system type		: UBNT_E100
136machine			: Unknown
137processor		: 0
138cpu model		: Cavium Octeon+ V0.1
139BogoMIPS		: 1000.00
140wait instruction	: yes
141microsecond timers	: yes
142tlb_entries		: 64
143extra interrupt vector	: yes
144hardware watchpoint	: yes, count: 2, address/irw mask: [0x0ffc, 0x0ffb]
145isa			: mips1 mips2 mips3 mips4 mips5 mips64r2
146ASEs implemented	:
147shadow register sets	: 1
148kscratch registers	: 0
149core			: 0
150VCED exceptions		: not available
151VCEI exceptions		: not available
152
153processor		: 1
154cpu model		: Cavium Octeon+ V0.1
155BogoMIPS		: 1000.00
156wait instruction	: yes
157microsecond timers	: yes
158tlb_entries		: 64
159extra interrupt vector	: yes
160hardware watchpoint	: yes, count: 2, address/irw mask: [0x0ffc, 0x0ffb]
161isa			: mips1 mips2 mips3 mips4 mips5 mips64r2
162ASEs implemented	:
163shadow register sets	: 1
164kscratch registers	: 0
165core			: 1
166VCED exceptions		: not available
167VCEI exceptions		: not available
168
169`
170
171	cpuinfoPpc64 = `
172processor	: 0
173cpu		: POWER7 (architected), altivec supported
174clock		: 3000.000000MHz
175revision	: 2.1 (pvr 003f 0201)
176
177processor	: 1
178cpu		: POWER7 (architected), altivec supported
179clock		: 3000.000000MHz
180revision	: 2.1 (pvr 003f 0201)
181
182processor	: 2
183cpu		: POWER7 (architected), altivec supported
184clock		: 3000.000000MHz
185revision	: 2.1 (pvr 003f 0201)
186
187processor	: 3
188cpu		: POWER7 (architected), altivec supported
189clock		: 3000.000000MHz
190revision	: 2.1 (pvr 003f 0201)
191
192processor	: 4
193cpu		: POWER7 (architected), altivec supported
194clock		: 3000.000000MHz
195revision	: 2.1 (pvr 003f 0201)
196
197processor	: 5
198cpu		: POWER7 (architected), altivec supported
199clock		: 3000.000000MHz
200revision	: 2.1 (pvr 003f 0201)
201
202timebase	: 512000000
203platform	: pSeries
204model		: IBM,8233-E8B
205machine		: CHRP IBM,8233-E8B
206`
207
208	cpuinfoRiscv64 = `
209processor	: 0
210hart		: 0
211isa		: rv64imafdcsu
212mmu		: sv48
213
214processor	: 1
215hart		: 1
216isa		: rv64imafdcsu
217mmu		: sv48
218`
219)
220
221func TestCPUInfoX86(t *testing.T) {
222	parseCPUInfo = parseCPUInfoX86
223	cpuinfo, err := getProcFixtures(t).CPUInfo()
224	if err != nil {
225		t.Fatal(err)
226	}
227
228	if cpuinfo == nil {
229		t.Fatal("cpuinfo is nil")
230	}
231
232	if want, have := 8, len(cpuinfo); want != have {
233		t.Errorf("want number of processors %v, have %v", want, have)
234	}
235
236	if want, have := uint(7), cpuinfo[7].Processor; want != have {
237		t.Errorf("want processor %v, have %v", want, have)
238	}
239	if want, have := "GenuineIntel", cpuinfo[0].VendorID; want != have {
240		t.Errorf("want vendor %v, have %v", want, have)
241	}
242	if want, have := "6", cpuinfo[1].CPUFamily; want != have {
243		t.Errorf("want family %v, have %v", want, have)
244	}
245	if want, have := "142", cpuinfo[2].Model; want != have {
246		t.Errorf("want model %v, have %v", want, have)
247	}
248	if want, have := "Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz", cpuinfo[3].ModelName; want != have {
249		t.Errorf("want model %v, have %v", want, have)
250	}
251	if want, have := uint(8), cpuinfo[4].Siblings; want != have {
252		t.Errorf("want siblings %v, have %v", want, have)
253	}
254	if want, have := "1", cpuinfo[5].CoreID; want != have {
255		t.Errorf("want core id %v, have %v", want, have)
256	}
257	if want, have := uint(4), cpuinfo[6].CPUCores; want != have {
258		t.Errorf("want cpu cores %v, have %v", want, have)
259	}
260	if want, have := "vme", cpuinfo[7].Flags[1]; want != have {
261		t.Errorf("want flag %v, have %v", want, have)
262	}
263}
264
265func TestCPUInfoParseARMLegacy(t *testing.T) {
266	cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7Legacy))
267	if err != nil || cpuinfo == nil {
268		t.Fatalf("unable to parse arm cpu info: %v", err)
269	}
270	if want, have := 2, len(cpuinfo); want != have {
271		t.Errorf("want number of processors %v, have %v", want, have)
272	}
273	if want, have := "ARMv7 Processor rev 5 (v7l)", cpuinfo[0].ModelName; want != have {
274		t.Errorf("want vendor %v, have %v", want, have)
275	}
276	if want, have := "thumb", cpuinfo[1].Flags[2]; want != have {
277		t.Errorf("want flag %v, have %v", want, have)
278	}
279}
280
281func TestCPUInfoParseARMLegacyV1(t *testing.T) {
282	cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7LegacyV1))
283	if err != nil || cpuinfo == nil {
284		t.Fatalf("unable to parse arm cpu info: %v", err)
285	}
286	if want, have := 1, len(cpuinfo); want != have {
287		t.Errorf("want number of processors %v, have %v", want, have)
288	}
289	if want, have := "ARMv6-compatible processor rev 5 (v6l)", cpuinfo[0].ModelName; want != have {
290		t.Errorf("want vendor %v, have %v", want, have)
291	}
292	if want, have := "thumb", cpuinfo[0].Flags[2]; want != have {
293		t.Errorf("want flag %v, have %v", want, have)
294	}
295}
296
297func TestCPUInfoParseARM(t *testing.T) {
298	cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7))
299	if err != nil || cpuinfo == nil {
300		t.Fatalf("unable to parse arm cpu info: %v", err)
301	}
302	if want, have := 4, len(cpuinfo); want != have {
303		t.Errorf("want number of processors %v, have %v", want, have)
304	}
305	if want, have := "ARMv7 Processor rev 3 (v7l)", cpuinfo[0].ModelName; want != have {
306		t.Errorf("want vendor %v, have %v", want, have)
307	}
308	if want, have := "thumb", cpuinfo[1].Flags[1]; want != have {
309		t.Errorf("want flag %v, have %v", want, have)
310	}
311}
312
313func TestCPUInfoParseS390X(t *testing.T) {
314	cpuinfo, err := parseCPUInfoS390X([]byte(cpuinfoS390x))
315	if err != nil || cpuinfo == nil {
316		t.Fatalf("unable to parse s390x cpu info: %v", err)
317	}
318	if want, have := 4, len(cpuinfo); want != have {
319		t.Errorf("want number of processors %v, have %v", want, have)
320	}
321	if want, have := "IBM/S390", cpuinfo[0].VendorID; want != have {
322		t.Errorf("want vendor %v, have %v", want, have)
323	}
324	if want, have := "ldisp", cpuinfo[1].Flags[4]; want != have {
325		t.Errorf("want flag %v, have %v", want, have)
326	}
327	if want, have := 5000.0, cpuinfo[2].CPUMHz; want != have {
328		t.Errorf("want cpu MHz %v, have %v", want, have)
329	}
330}
331
332func TestCPUInfoParseMips(t *testing.T) {
333	cpuinfo, err := parseCPUInfoMips([]byte(cpuinfoMips))
334	if err != nil || cpuinfo == nil {
335		t.Fatalf("unable to parse mips cpu info: %v", err)
336	}
337	if want, have := 2, len(cpuinfo); want != have {
338		t.Errorf("want number of processors %v, have %v", want, have)
339	}
340	if want, have := 1000.00, cpuinfo[0].BogoMips; want != have {
341		t.Errorf("want BogoMIPS %v, have %v", want, have)
342	}
343	if want, have := "Cavium Octeon+ V0.1", cpuinfo[1].ModelName; want != have {
344		t.Errorf("want ModelName '%v', have '%v'", want, have)
345	}
346}
347
348func TestCPUInfoParsePPC(t *testing.T) {
349	cpuinfo, err := parseCPUInfoPPC([]byte(cpuinfoPpc64))
350	if err != nil || cpuinfo == nil {
351		t.Fatalf("unable to parse ppc cpu info: %v", err)
352	}
353	if want, have := 6, len(cpuinfo); want != have {
354		t.Errorf("want number of processors %v, have %v", want, have)
355	}
356	if want, have := 3000.00, cpuinfo[2].CPUMHz; want != have {
357		t.Errorf("want cpu mhz %v, have %v", want, have)
358	}
359}
360
361func TestCPUInfoParseRISCV64(t *testing.T) {
362	cpuinfo, err := parseCPUInfoRISCV([]byte(cpuinfoRiscv64))
363	if err != nil || cpuinfo == nil {
364		t.Fatalf("unable to parse ppc cpu info: %v", err)
365	}
366	if want, have := 2, len(cpuinfo); want != have {
367		t.Errorf("want number of processors %v, have %v", want, have)
368	}
369	if want, have := "1", cpuinfo[1].CoreID; want != have {
370		t.Errorf("want CoreId %v, have %v", want, have)
371	}
372	if want, have := "rv64imafdcsu", cpuinfo[1].ModelName; want != have {
373		t.Errorf("want ModelName %v, have %v", want, have)
374	}
375}
376