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
118physical id     : 2
119core id         : 0
120siblings        : 8
121cpu cores       : 4
122cpu MHz dynamic : 5000
123cpu MHz static  : 5000
124
125cpu number      : 1
126physical id     : 2
127core id         : 0
128siblings        : 8
129cpu cores       : 4
130cpu MHz dynamic : 5000
131cpu MHz static  : 5000
132
133cpu number      : 2
134physical id     : 2
135core id         : 1
136siblings        : 8
137cpu cores       : 4
138cpu MHz dynamic : 5000
139cpu MHz static  : 5000
140
141cpu number      : 3
142physical id     : 2
143core id         : 1
144siblings        : 8
145cpu cores       : 4
146cpu MHz dynamic : 5000
147cpu MHz static  : 5000
148`
149
150	cpuinfoMips = `
151system type		: UBNT_E100
152machine			: Unknown
153processor		: 0
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			: 0
166VCED exceptions		: not available
167VCEI exceptions		: not available
168
169processor		: 1
170cpu model		: Cavium Octeon+ V0.1
171BogoMIPS		: 1000.00
172wait instruction	: yes
173microsecond timers	: yes
174tlb_entries		: 64
175extra interrupt vector	: yes
176hardware watchpoint	: yes, count: 2, address/irw mask: [0x0ffc, 0x0ffb]
177isa			: mips1 mips2 mips3 mips4 mips5 mips64r2
178ASEs implemented	:
179shadow register sets	: 1
180kscratch registers	: 0
181core			: 1
182VCED exceptions		: not available
183VCEI exceptions		: not available
184
185`
186
187	cpuinfoPpc64 = `
188processor	: 0
189cpu		: POWER7 (architected), altivec supported
190clock		: 3000.000000MHz
191revision	: 2.1 (pvr 003f 0201)
192
193processor	: 1
194cpu		: POWER7 (architected), altivec supported
195clock		: 3000.000000MHz
196revision	: 2.1 (pvr 003f 0201)
197
198processor	: 2
199cpu		: POWER7 (architected), altivec supported
200clock		: 3000.000000MHz
201revision	: 2.1 (pvr 003f 0201)
202
203processor	: 3
204cpu		: POWER7 (architected), altivec supported
205clock		: 3000.000000MHz
206revision	: 2.1 (pvr 003f 0201)
207
208processor	: 4
209cpu		: POWER7 (architected), altivec supported
210clock		: 3000.000000MHz
211revision	: 2.1 (pvr 003f 0201)
212
213processor	: 5
214cpu		: POWER7 (architected), altivec supported
215clock		: 3000.000000MHz
216revision	: 2.1 (pvr 003f 0201)
217
218timebase	: 512000000
219platform	: pSeries
220model		: IBM,8233-E8B
221machine		: CHRP IBM,8233-E8B
222`
223
224	cpuinfoRiscv64 = `
225processor	: 0
226hart		: 0
227isa		: rv64imafdcsu
228mmu		: sv48
229
230processor	: 1
231hart		: 1
232isa		: rv64imafdcsu
233mmu		: sv48
234`
235)
236
237func TestCPUInfoX86(t *testing.T) {
238	parseCPUInfo = parseCPUInfoX86
239	cpuinfo, err := getProcFixtures(t).CPUInfo()
240	if err != nil {
241		t.Fatal(err)
242	}
243
244	if cpuinfo == nil {
245		t.Fatal("cpuinfo is nil")
246	}
247
248	if want, have := 8, len(cpuinfo); want != have {
249		t.Errorf("want number of processors %v, have %v", want, have)
250	}
251
252	if want, have := uint(7), cpuinfo[7].Processor; want != have {
253		t.Errorf("want processor %v, have %v", want, have)
254	}
255	if want, have := "GenuineIntel", cpuinfo[0].VendorID; want != have {
256		t.Errorf("want vendor %v, have %v", want, have)
257	}
258	if want, have := "6", cpuinfo[1].CPUFamily; want != have {
259		t.Errorf("want family %v, have %v", want, have)
260	}
261	if want, have := "142", cpuinfo[2].Model; want != have {
262		t.Errorf("want model %v, have %v", want, have)
263	}
264	if want, have := "Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz", cpuinfo[3].ModelName; want != have {
265		t.Errorf("want model %v, have %v", want, have)
266	}
267	if want, have := uint(8), cpuinfo[4].Siblings; want != have {
268		t.Errorf("want siblings %v, have %v", want, have)
269	}
270	if want, have := "1", cpuinfo[5].CoreID; want != have {
271		t.Errorf("want core id %v, have %v", want, have)
272	}
273	if want, have := uint(4), cpuinfo[6].CPUCores; want != have {
274		t.Errorf("want cpu cores %v, have %v", want, have)
275	}
276	if want, have := "vme", cpuinfo[7].Flags[1]; want != have {
277		t.Errorf("want flag %v, have %v", want, have)
278	}
279}
280
281func TestCPUInfoParseARMLegacy(t *testing.T) {
282	cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7Legacy))
283	if err != nil || cpuinfo == nil {
284		t.Fatalf("unable to parse arm cpu info: %v", err)
285	}
286	if want, have := 2, len(cpuinfo); want != have {
287		t.Errorf("want number of processors %v, have %v", want, have)
288	}
289	if want, have := "ARMv7 Processor rev 5 (v7l)", cpuinfo[0].ModelName; want != have {
290		t.Errorf("want vendor %v, have %v", want, have)
291	}
292	if want, have := "thumb", cpuinfo[1].Flags[2]; want != have {
293		t.Errorf("want flag %v, have %v", want, have)
294	}
295}
296
297func TestCPUInfoParseARMLegacyV1(t *testing.T) {
298	cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7LegacyV1))
299	if err != nil || cpuinfo == nil {
300		t.Fatalf("unable to parse arm cpu info: %v", err)
301	}
302	if want, have := 1, len(cpuinfo); want != have {
303		t.Errorf("want number of processors %v, have %v", want, have)
304	}
305	if want, have := "ARMv6-compatible processor rev 5 (v6l)", cpuinfo[0].ModelName; want != have {
306		t.Errorf("want vendor %v, have %v", want, have)
307	}
308	if want, have := "thumb", cpuinfo[0].Flags[2]; want != have {
309		t.Errorf("want flag %v, have %v", want, have)
310	}
311}
312
313func TestCPUInfoParseARM(t *testing.T) {
314	cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7))
315	if err != nil || cpuinfo == nil {
316		t.Fatalf("unable to parse arm 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 := "ARMv7 Processor rev 3 (v7l)", cpuinfo[0].ModelName; want != have {
322		t.Errorf("want vendor %v, have %v", want, have)
323	}
324	if want, have := "thumb", cpuinfo[1].Flags[1]; want != have {
325		t.Errorf("want flag %v, have %v", want, have)
326	}
327}
328
329func TestCPUInfoParseS390X(t *testing.T) {
330	cpuinfo, err := parseCPUInfoS390X([]byte(cpuinfoS390x))
331	if err != nil || cpuinfo == nil {
332		t.Fatalf("unable to parse s390x cpu info: %v", err)
333	}
334	if want, have := 4, len(cpuinfo); want != have {
335		t.Errorf("want number of processors %v, have %v", want, have)
336	}
337	if want, have := "IBM/S390", cpuinfo[0].VendorID; want != have {
338		t.Errorf("want vendor %v, have %v", want, have)
339	}
340	if want, have := "ldisp", cpuinfo[1].Flags[4]; want != have {
341		t.Errorf("want flag %v, have %v", want, have)
342	}
343	if want, have := 5000.0, cpuinfo[2].CPUMHz; want != have {
344		t.Errorf("want cpu MHz %v, have %v", want, have)
345	}
346	if want, have := uint(8), cpuinfo[3].Siblings; want != have {
347		t.Errorf("want siblings %v, have %v", want, have)
348	}
349	if want, have := "1", cpuinfo[3].CoreID; want != have {
350		t.Errorf("want core id %v, have %v", want, have)
351	}
352	if want, have := uint(4), cpuinfo[2].CPUCores; want != have {
353		t.Errorf("want cpu cores %v, have %v", want, have)
354	}
355	if want, have := "2", cpuinfo[2].PhysicalID; want != have {
356		t.Errorf("want physical id %v, have %v", want, have)
357	}
358}
359
360func TestCPUInfoParseMips(t *testing.T) {
361	cpuinfo, err := parseCPUInfoMips([]byte(cpuinfoMips))
362	if err != nil || cpuinfo == nil {
363		t.Fatalf("unable to parse mips cpu info: %v", err)
364	}
365	if want, have := 2, len(cpuinfo); want != have {
366		t.Errorf("want number of processors %v, have %v", want, have)
367	}
368	if want, have := 1000.00, cpuinfo[0].BogoMips; want != have {
369		t.Errorf("want BogoMIPS %v, have %v", want, have)
370	}
371	if want, have := "Cavium Octeon+ V0.1", cpuinfo[1].ModelName; want != have {
372		t.Errorf("want ModelName '%v', have '%v'", want, have)
373	}
374}
375
376func TestCPUInfoParsePPC(t *testing.T) {
377	cpuinfo, err := parseCPUInfoPPC([]byte(cpuinfoPpc64))
378	if err != nil || cpuinfo == nil {
379		t.Fatalf("unable to parse ppc cpu info: %v", err)
380	}
381	if want, have := 6, len(cpuinfo); want != have {
382		t.Errorf("want number of processors %v, have %v", want, have)
383	}
384	if want, have := 3000.00, cpuinfo[2].CPUMHz; want != have {
385		t.Errorf("want cpu mhz %v, have %v", want, have)
386	}
387}
388
389func TestCPUInfoParseRISCV64(t *testing.T) {
390	cpuinfo, err := parseCPUInfoRISCV([]byte(cpuinfoRiscv64))
391	if err != nil || cpuinfo == nil {
392		t.Fatalf("unable to parse ppc cpu info: %v", err)
393	}
394	if want, have := 2, len(cpuinfo); want != have {
395		t.Errorf("want number of processors %v, have %v", want, have)
396	}
397	if want, have := "1", cpuinfo[1].CoreID; want != have {
398		t.Errorf("want CoreId %v, have %v", want, have)
399	}
400	if want, have := "rv64imafdcsu", cpuinfo[1].ModelName; want != have {
401		t.Errorf("want ModelName %v, have %v", want, have)
402	}
403}
404