summaryrefslogtreecommitdiff
path: root/spec/unit/plugins/linux/cpu_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/plugins/linux/cpu_spec.rb')
-rw-r--r--spec/unit/plugins/linux/cpu_spec.rb1413
1 files changed, 1191 insertions, 222 deletions
diff --git a/spec/unit/plugins/linux/cpu_spec.rb b/spec/unit/plugins/linux/cpu_spec.rb
index 78977d39..92acdce6 100644
--- a/spec/unit/plugins/linux/cpu_spec.rb
+++ b/spec/unit/plugins/linux/cpu_spec.rb
@@ -16,24 +16,235 @@
# limitations under the License.
#
-require "tempfile"
require "spec_helper"
-shared_examples "Common cpu info" do |total_cpu, real_cpu|
+shared_examples "Common cpu info" do |total_cpu, real_cpu, ls_cpu, architecture, cpu_opmodes, byte_order, cpus,
+ cpus_online, threads_per_core, cores_per_socket, sockets, numa_nodes, vendor_id, model, model_name, bogomips,
+ l1d_cache, l1i_cache, l2_cache, l3_cache, flags, numa_node_cpus|
describe "cpu" do
it "has cpu[:total] equals to #{total_cpu}" do
plugin.run
expect(plugin[:cpu][:total]).to eq(total_cpu)
end
- it "has cpu[:real] equals to #{real_cpu}" do
+ it "has a cpu 0" do
plugin.run
- expect(plugin[:cpu][:real]).to eq(real_cpu)
+ expect(plugin[:cpu]).to have_key("0")
end
- it "has a cpu 0" do
+ if ls_cpu
+ it "has cpu[:real] equals to #{real_cpu}" do
+ plugin.run
+ expect(plugin[:cpu][:real]).to eq(real_cpu)
+ end
+
+ it "has architecture equal to #{architecture}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("architecture")
+ expect(plugin[:cpu]["architecture"]).to eq(architecture)
+ end
+
+ it "has cpu_opmodes equal to #{cpu_opmodes}" do
+ plugin.run
+ if cpu_opmodes
+ expect(plugin[:cpu]).to have_key("cpu_opmodes")
+ expect(plugin[:cpu]["cpu_opmodes"]).to eq(cpu_opmodes)
+ else
+ expect(plugin[:cpu]).to_not have_key("cpu_opmodes")
+ end
+ end
+
+ it "has byte_order equal to #{byte_order}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("byte_order")
+ expect(plugin[:cpu]["byte_order"]).to eq(byte_order)
+ end
+
+ it "has cpus equal to #{cpus}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("cpus")
+ expect(plugin[:cpu]["cpus"]).to eq(cpus)
+ end
+
+ it "has cpus_online equal to #{cpus_online}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("cpus_online")
+ expect(plugin[:cpu]["cpus_online"]).to eq(cpus_online)
+ end
+
+ it "has threads_per_core equal to #{threads_per_core}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("threads_per_core")
+ expect(plugin[:cpu]["threads_per_core"]).to eq(threads_per_core)
+ end
+
+ it "has cores_per_socket equal to #{cores_per_socket}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("cores_per_socket")
+ expect(plugin[:cpu]["cores_per_socket"]).to eq(cores_per_socket)
+ end
+
+ it "cpu 0 has cores to #{cores_per_socket}" do
+ plugin.run
+ expect(plugin[:cpu]["0"]).to have_key("cores")
+ expect(plugin[:cpu]["0"]["cores"]).to eq(cores_per_socket.to_s)
+ end
+
+ # s390x shows this differently
+ it "has sockets equal to #{sockets}" do
+ plugin.run
+ if sockets
+ expect(plugin[:cpu]).to have_key("sockets")
+ expect(plugin[:cpu]["sockets"]).to eq(sockets)
+ else
+ expect(plugin[:cpu]).to_not have_key("sockets")
+ end
+ end
+
+ it "has numa_nodes equal to #{numa_nodes}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("numa_nodes")
+ expect(plugin[:cpu]["numa_nodes"]).to eq(numa_nodes)
+ end
+
+ it "has vendor_id equal to #{vendor_id}" do
+ plugin.run
+ if vendor_id
+ expect(plugin[:cpu]).to have_key("vendor_id")
+ expect(plugin[:cpu]["vendor_id"]).to eq(vendor_id)
+ else
+ expect(plugin[:cpu]).to_not have_key("vendor_id")
+ end
+ end
+
+ it "has model equal to #{model}" do
+ plugin.run
+ if model
+ expect(plugin[:cpu]).to have_key("model")
+ expect(plugin[:cpu]["model"]).to eq(model)
+ else
+ expect(plugin[:cpu]).to_not have_key("model")
+ end
+ end
+
+ it "has model_name equal to #{model_name}" do
+ plugin.run
+ if model_name
+ expect(plugin[:cpu]).to have_key("model_name")
+ expect(plugin[:cpu]["model_name"]).to eq(model_name)
+ else
+ expect(plugin[:cpu]).to_not have_key("model_name")
+ end
+ end
+
+ it "has bogomips equal to #{bogomips}" do
+ plugin.run
+ if bogomips
+ expect(plugin[:cpu]).to have_key("bogomips")
+ expect(plugin[:cpu]["bogomips"]).to eq(bogomips)
+ else
+ expect(plugin[:cpu]).to_not have_key("bogomips")
+ end
+ end
+
+ it "has l1d_cache equal to #{l1d_cache}" do
+ plugin.run
+ if l1d_cache
+ expect(plugin[:cpu]).to have_key("l1d_cache")
+ expect(plugin[:cpu]["l1d_cache"]).to eq(l1d_cache)
+ else
+ expect(plugin[:cpu]).to_not have_key("l1d_cache")
+ end
+ end
+
+ it "has l1i_cache equal to #{l1i_cache}" do
+ plugin.run
+ if l1i_cache
+ expect(plugin[:cpu]).to have_key("l1i_cache")
+ expect(plugin[:cpu]["l1i_cache"]).to eq(l1i_cache)
+ else
+ expect(plugin[:cpu]).to_not have_key("l1i_cache")
+ end
+ end
+
+ it "has l2_cache equal to #{l2_cache}" do
+ plugin.run
+ if l2_cache
+ expect(plugin[:cpu]).to have_key("l2_cache")
+ expect(plugin[:cpu]["l2_cache"]).to eq(l2_cache)
+ else
+ expect(plugin[:cpu]).to_not have_key("l2_cache")
+ end
+ end
+
+ it "has l3_cache equal to #{l3_cache}" do
+ plugin.run
+ if l3_cache
+ expect(plugin[:cpu]).to have_key("l3_cache")
+ expect(plugin[:cpu]["l3_cache"]).to eq(l3_cache)
+ else
+ expect(plugin[:cpu]).to_not have_key("l3_cache")
+ end
+ end
+
+ it "has flags" do
+ plugin.run
+ if flags
+ expect(plugin[:cpu]).to have_key("flags")
+ expect(plugin[:cpu]["flags"]).to eq(flags)
+ else
+ expect(plugin[:cpu]).to_not have_key("flags")
+ end
+ end
+ it "has numa_node_cpus" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("numa_node_cpus")
+ expect(plugin[:cpu]["numa_node_cpus"]).to eq(numa_node_cpus)
+ end
+ end
+ end
+end
+
+shared_examples "virtualization info" do |virtualization_type, hypervisor_vendor|
+ describe "virtualization" do
+ it "has virtualization_type equal to #{virtualization_type}" do
plugin.run
- expect(plugin[:cpu]).to have_key("0")
+ expect(plugin[:cpu]).to have_key("virtualization_type")
+ expect(plugin[:cpu]["virtualization_type"]).to eq(virtualization_type)
+ end
+
+ it "has hypervisor_vendor equal to #{hypervisor_vendor}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("hypervisor_vendor")
+ expect(plugin[:cpu]["hypervisor_vendor"]).to eq(hypervisor_vendor)
+ end
+ end
+end
+
+shared_examples "x86 processor info" do |cpu_no, family, stepping, mhz, cache_size|
+ describe "x86 processor" do
+ it "has family equal to #{family}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("family")
+ expect(plugin[:cpu]["family"]).to eq(family)
+ end
+
+ it "has stepping equal to #{stepping}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("stepping")
+ expect(plugin[:cpu]["stepping"]).to eq(stepping)
+ end
+
+ it "has mhz equal to #{mhz}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("mhz")
+ expect(plugin[:cpu]["mhz"]).to eq(mhz)
+ end
+
+ it "has cache_size in cpu #{cpu_no}" do
+ plugin.run
+ expect(plugin[:cpu][cpu_no.to_s]).to have_key("cache_size")
+ expect(plugin[:cpu][cpu_no.to_s]["cache_size"]).to eql(cache_size)
end
end
end
@@ -57,6 +268,11 @@ shared_examples "S390 processor info" do |cpu_no, version, identification, machi
expect(plugin[:cpu][cpu_no.to_s]).to have_key("machine")
expect(plugin[:cpu][cpu_no.to_s]["machine"]).to eql(machine)
end
+
+ it "does not have a cache_size for cpu #{cpu_no}" do
+ plugin.run
+ expect(plugin[:cpu][cpu_no.to_s]).to_not have_key("cache_size")
+ end
end
end
@@ -73,96 +289,109 @@ shared_examples "arm64 processor info" do |cpu_no, bogomips, features|
expect(plugin[:cpu][cpu_no.to_s]).to have_key("features")
expect(plugin[:cpu][cpu_no.to_s]["features"]).to eql(features)
end
+
+ it "does not have a cache_size for cpu #{cpu_no}" do
+ plugin.run
+ expect(plugin[:cpu][cpu_no.to_s]).to_not have_key("cache_size")
+ end
end
end
-describe Ohai::System, "General Linux cpu plugin" do
- let(:plugin) { get_plugin("cpu") }
+shared_examples "ppc64le processor info" do |cpu_no, model_name, model, mhz, timebase, platform, machine_model,
+ machine, firmware, mmu|
+ describe "ppc64le processor" do
+ it "has model_name for cpu #{cpu_no}" do
+ plugin.run
+ expect(plugin[:cpu][cpu_no.to_s]).to have_key("model_name")
+ expect(plugin[:cpu][cpu_no.to_s]["model_name"]).to eql(model_name)
+ end
+
+ it "has model for cpu #{cpu_no}" do
+ plugin.run
+ expect(plugin[:cpu][cpu_no.to_s]).to have_key("model")
+ expect(plugin[:cpu][cpu_no.to_s]["model"]).to eql(model)
+ end
+
+ it "has mhz for cpu #{cpu_no}" do
+ plugin.run
+ expect(plugin[:cpu][cpu_no.to_s]).to have_key("mhz")
+ expect(plugin[:cpu][cpu_no.to_s]["mhz"]).to eql(mhz)
+ end
- let(:tempfile_handle) do
- tempfile = Tempfile.new("ohai-rspec-proc-cpuinfo")
- tempfile.write cpuinfo_contents
- tempfile.rewind
- tempfile
+ it "has timebase equal to #{timebase}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("timebase")
+ expect(plugin[:cpu]["timebase"]).to eq(timebase)
+ end
+
+ it "has platform equal to #{platform}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("platform")
+ expect(plugin[:cpu]["platform"]).to eq(platform)
+ end
+
+ it "has machine_model equal to #{machine_model}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("machine_model")
+ expect(plugin[:cpu]["machine_model"]).to eq(machine_model)
+ end
+
+ it "has machine equal to #{machine}" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("machine")
+ expect(plugin[:cpu]["machine"]).to eq(machine)
+ end
+
+ it "has firmware equal to #{firmware}" do
+ plugin.run
+ if firmware
+ expect(plugin[:cpu]).to have_key("firmware")
+ expect(plugin[:cpu]["firmware"]).to eq(firmware)
+ else
+ expect(plugin[:cpu]).to_not have_key("firmware")
+ end
+ end
+
+ it "has mmu equal to #{mmu}" do
+ plugin.run
+ if mmu
+ expect(plugin[:cpu]).to have_key("mmu")
+ expect(plugin[:cpu]["mmu"]).to eq(mmu)
+ else
+ expect(plugin[:cpu]).to_not have_key("mmu")
+ end
+ end
+
+ it "does not have a cache_size for cpu #{cpu_no}" do
+ plugin.run
+ expect(plugin[:cpu][cpu_no.to_s]).to_not have_key("cache_size")
+ end
end
+end
+
+describe Ohai::System, "General Linux cpu plugin" do
+ let(:plugin) { get_plugin("cpu") }
+ let(:cpuinfo_contents) { "" }
+ let(:spectre_v2) { "Mitigation: Full generic retpoline, IBPB: conditional, IBRS_FW, STIBP: conditional, RSB filling" }
before do
allow(plugin).to receive(:collect_os).and_return(:linux)
- allow(File).to receive(:open).with("/proc/cpuinfo").and_return(tempfile_handle)
- end
-
- after do
-
- tempfile.close
- tempfile.unlink
- rescue
- # really do not care
-
- end
-
- context "with old kernel that doesn't include cores in /proc/cpuinfo" do
- let(:cpuinfo_contents) do
- <<-EOF
- processor : 0
- vendor_id : GenuineIntel
- cpu family : 6
- model : 23
- model name : Intel(R) Core(TM)2 Duo CPU T8300 @ 2.40GHz
- stepping : 6
- cpu MHz : 1968.770
- cache size : 64 KB
- fdiv_bug : no
- hlt_bug : no
- f00f_bug : no
- coma_bug : no
- fpu : yes
- fpu_exception : yes
- cpuid level : 10
- wp : yes
- flags : fpu pse tsc msr mce cx8 sep mtrr pge cmov
- bogomips : 2575.86
- clflush size : 32
- EOF
- end
-
- let(:lscpu) do
- <<~EOF
- Architecture: x86_64
- CPU op-mode(s): 32-bit, 64-bit
- Byte Order: Little Endian
- CPU(s): 1
- On-line CPU(s) list: 0
- Thread(s) per core: 1
- Core(s) per socket: 1
- Socket(s): 1
- NUMA node(s): 1
- Vendor ID: GenuineIntel
- CPU family: 6
- Model: 23
- Model name: Intel(R) Core(TM)2 Duo CPU T8300 @ 2.40GHz
- Stepping: 2
- CPU MHz: 1968.770
- BogoMIPS: 2575.86
- Hypervisor vendor: Xen
- Virtualization type: full
- L1d cache: 32K
- L1i cache: 32K
- L2 cache: 256K
- L3 cache: 30720K
- NUMA node0 CPU(s): 0
- Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm fsgsbase bmi1 avx2 smep bmi2 erms invpcid xsaveopt
- EOF
- end
+ allow(File).to receive(:open).with("/proc/cpuinfo").and_return(cpuinfo_contents)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(1, "", ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(1, "", ""))
+ end
- before do
- allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
- end
+ context "with old kernel that doesn't include cores in /proc/cpuinfo and no lscpu" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-no-cores.output")) }
- it_behaves_like "Common cpu info", 1, 1
+ it_behaves_like "Common cpu info",
+ 1, # total_cpu
+ 1, # real_cpu
+ false # ls_cpu
- it "gets total cores" do
+ it "doesn't get total cores" do
plugin.run
- expect(plugin[:cpu][:cores]).to be(1)
+ expect(plugin[:cpu]).not_to have_key("cores")
end
it "doesn't have a cpu 1" do
@@ -234,114 +463,63 @@ describe Ohai::System, "General Linux cpu plugin" do
end
end
+ context "standard x86 host cpu with lscpu" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-no-cores.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-host.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-host-cores.output")) }
+
+ before do
+ allow(File).to receive(:open).with("/proc/cpuinfo").and_return(cpuinfo_contents)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ flags = %w{acpi aes aperfmperf apic arat arch_perfmon bts clflush cmov constant_tsc cx16 cx8 dca de ds_cpl dtes64 dtherm dts eagerfpu epb ept est flexpriority flush_l1d fpu fxsr ht ibpb ibrs ida intel_stibp lahf_lm lm mca mce mmx monitor msr mtrr nonstop_tsc nopl nx pae pat pbe pcid pclmulqdq pdcm pdpe1gb pebs pge pni popcnt pse pse36 rdtscp rep_good sep smx spec_ctrl ss ssbd sse sse2 sse4_1 sse4_2 ssse3 stibp syscall tm tm2 tpr_shadow tsc vme vmx vnmi vpid xtopology xtpr}
+ numa_node_cpus = { "0" => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] }
+
+ it_behaves_like "Common cpu info",
+ 24, # total_cpu
+ 2, # real_cpu
+ true, # ls_cpu
+ "x86_64", # architecture
+ %w{32-bit 64-bit}, # cpu_opmodes
+ "little endian", # byte_order
+ 24, # cpus
+ 24, # cpus_online
+ 2, # threads_per_core
+ 6, # cores_per_socket
+ 2, # sockets
+ 1, # numa_nodes
+ "GenuineIntel", # vendor_id
+ "44", # model
+ "Intel(R) Xeon(R) CPU X5670 @ 2.93GHz", # model_name
+ "5851.68", # bogomips
+ "32K", # l1d_cache
+ "32K", # l1i_cache
+ "256K", # l2_cache
+ "12288K", # l3_cache
+ flags, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "x86 processor info",
+ 0, # cpu number
+ "6", # family
+ "2", # stepping
+ "2927.000", # mhz
+ "64 KB" # cache_size
+
+ it "has virtualization" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("virtualization")
+ expect(plugin[:cpu]["virtualization"]).to eq("VT-x")
+ end
+ end
+
context "with a dual-core hyperthreaded /proc/cpuinfo" do
- let(:cpuinfo_contents) do
- <<~EOF
- processor : 0
- vendor_id : GenuineIntel
- cpu family : 6
- model : 69
- model name : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz
- stepping : 1
- microcode : 0x17
- cpu MHz : 774.000
- cache size : 4096 KB
- physical id : 0
- siblings : 4
- core id : 0
- cpu cores : 2
- apicid : 0
- initial apicid : 0
- fpu : yes
- fpu_exception : yes
- cpuid level : 13
- wp : yes
- flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid
- bogomips : 3591.40
- clflush size : 64
- cache_alignment : 64
- address sizes : 39 bits physical, 48 bits virtual
- power management:
-
- processor : 1
- vendor_id : GenuineIntel
- cpu family : 6
- model : 69
- model name : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz
- stepping : 1
- microcode : 0x17
- cpu MHz : 1600.000
- cache size : 4096 KB
- physical id : 0
- siblings : 4
- core id : 0
- cpu cores : 2
- apicid : 1
- initial apicid : 1
- fpu : yes
- fpu_exception : yes
- cpuid level : 13
- wp : yes
- flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid
- bogomips : 3591.40
- clflush size : 64
- cache_alignment : 64
- address sizes : 39 bits physical, 48 bits virtual
- power management:
-
- processor : 2
- vendor_id : GenuineIntel
- cpu family : 6
- model : 69
- model name : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz
- stepping : 1
- microcode : 0x17
- cpu MHz : 800.000
- cache size : 4096 KB
- physical id : 0
- siblings : 4
- core id : 1
- cpu cores : 2
- apicid : 2
- initial apicid : 2
- fpu : yes
- fpu_exception : yes
- cpuid level : 13
- wp : yes
- flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid
- bogomips : 3591.40
- clflush size : 64
- cache_alignment : 64
- address sizes : 39 bits physical, 48 bits virtual
- power management:
-
- processor : 3
- vendor_id : GenuineIntel
- cpu family : 6
- model : 69
- model name : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz
- stepping : 1
- microcode : 0x17
- cpu MHz : 774.000
- cache size : 4096 KB
- physical id : 0
- siblings : 4
- core id : 1
- cpu cores : 2
- apicid : 3
- initial apicid : 3
- fpu : yes
- fpu_exception : yes
- cpuid level : 13
- wp : yes
- flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid
- bogomips : 3591.40
- clflush size : 64
- cache_alignment : 64
- address sizes : 39 bits physical, 48 bits virtual
- power management:
-
- EOF
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-dual-core-hyperthreaded.output")) }
+
+ before do
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(1, "", ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(1, "", ""))
end
it "has 1 physical socket" do
@@ -359,27 +537,236 @@ describe Ohai::System, "General Linux cpu plugin" do
expect(plugin[:cpu][:total]).to eq(4)
end
end
+
+ context "x86 host with vulnerability data" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-x86-host-vuln.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-host-vuln.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-host-vuln-cores.output")) }
+
+ before do
+ allow(File).to receive(:open).with("/proc/cpuinfo").and_return(cpuinfo_contents)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ flags = %w{ac apic clflush cmov cx8 de dts fpu mca mce msr mtrr pae pat pge pse pse36 sep tsc vme}
+ numa_node_cpus = { "0" => [0, 1, 2, 3] }
+
+ it_behaves_like "Common cpu info",
+ 4, # total_cpu
+ 1, # real_cpu
+ true, # ls_cpu
+ "x86_64", # architecture
+ %w{32-bit 64-bit}, # cpu_opmodes
+ "little endian", # byte_order
+ 4, # cpus
+ 4, # cpus_online
+ 2, # threads_per_core
+ 2, # cores_per_socket
+ 1, # sockets
+ 1, # numa_nodes
+ "GenuineIntel", # vendor_id
+ "61", # model
+ "Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz", # model_name
+ "4389.65", # bogomips
+ "64 KiB", # l1d_cache
+ "64 KiB", # l1i_cache
+ "512 KiB", # l2_cache
+ "3 MiB", # l3_cache
+ flags, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "x86 processor info",
+ 0, # cpu number
+ "6", # family
+ "4", # stepping
+ "2494.232", # mhz
+ "3072 KB" # cache_size
+
+ it "has vulnerability" do
+ plugin.run
+ vuln = {
+ "itlb_multihit" => "KVM: Mitigation: Split huge pages",
+ "l1tf" => "Mitigation; PTE Inversion; VMX conditional cache flushes, SMT vulnerable",
+ "mds" => "Mitigation; Clear CPU buffers; SMT vulnerable",
+ "meltdown" => "Mitigation; PTI",
+ "spec_store_bypass" => "Mitigation; Speculative Store Bypass disabled via prctl and seccomp",
+ "spectre_v1" => "Mitigation; usercopy/swapgs barriers and __user pointer sanitization",
+ "spectre_v2" => "Mitigation; Full generic retpoline, IBPB conditional, IBRS_FW, STIBP conditional, RSB",
+ "srbds" => "Mitigation; Microcode",
+ "tsx_async_abort" => "Not affected",
+ }
+ expect(plugin[:cpu]).to have_key("vulnerability")
+ expect(plugin[:cpu]["vulnerability"]).to eq(vuln)
+ end
+ end
+
+ context "x86 guest on kvm" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-x86-guest-kvm.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-guest-kvm.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-guest-kvm-cores.output")) }
+
+ before do
+ allow(File).to receive(:open).with("/proc/cpuinfo").and_return(cpuinfo_contents)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ flags = %w{apic clflush cmov cx16 cx8 de eagerfpu fpu fxsr hypervisor lahf_lm lm mca mce mmx msr mtrr nopl nx pae pge pni pse pse36 rep_good sep sse sse2 syscall tsc x2apic xtopology}
+ numa_node_cpus = { "0" => [0, 1, 2, 3] }
+
+ it_behaves_like "Common cpu info",
+ 4, # total_cpu
+ 4, # real_cpu
+ true, # ls_cpu
+ "x86_64", # architecture
+ %w{32-bit 64-bit}, # cpu_opmodes
+ "little endian", # byte_order
+ 4, # cpus
+ 4, # cpus_online
+ 1, # threads_per_core
+ 1, # cores_per_socket
+ 4, # sockets
+ 1, # numa_nodes
+ "GenuineIntel", # vendor_id
+ "13", # model
+ "QEMU Virtual CPU version 2.5+", # model_name
+ "6649.99", # bogomips
+ "32K", # l1d_cache
+ "32K", # l1i_cache
+ "4096K", # l2_cache
+ "16384K", # l3_cache
+ flags, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "x86 processor info",
+ 0, # cpu number
+ "6", # family
+ "3", # stepping
+ "3324.998", # mhz
+ "16384 KB" # cache_size
+ it_behaves_like "virtualization info",
+ "full", # virtualization_type
+ "KVM" # hypervisor_vendor
+ end
+
+ context "x86 guest on kvm (nested)" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-x86-guest-kvm-nested.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-guest-kvm-nested.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-guest-kvm-nested-cores.output")) }
+
+ before do
+ allow(File).to receive(:open).with("/proc/cpuinfo").and_return(cpuinfo_contents)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ flags = %w{abm aes apic arat avx avx2 bmi1 bmi2 clflush cmov constant_tsc cx16 cx8 de eagerfpu ept erms f16c flexpriority fma fpu fsgsbase fxsr hypervisor ibpb ibrs intel_stibp invpcid invpcid_single lahf_lm lm mca mce md_clear mmx movbe msr mtrr nopl nx pae pat pcid pclmulqdq pdpe1gb pge pni popcnt pse pse36 rdrand rdtscp rep_good sep smep spec_ctrl ss ssbd sse sse2 sse4_1 sse4_2 ssse3 stibp syscall tpr_shadow tsc tsc_adjust tsc_deadline_timer vme vmx vnmi vpid x2apic xsave xsaveopt xtopology}
+ numa_node_cpus = { "0" => [0] }
+
+ it_behaves_like "Common cpu info",
+ 1, # total_cpu
+ 1, # real_cpu
+ true, # ls_cpu
+ "x86_64", # architecture
+ %w{32-bit 64-bit}, # cpu_opmodes
+ "little endian", # byte_order
+ 1, # cpus
+ 0, # cpus_online
+ 1, # threads_per_core
+ 1, # cores_per_socket
+ 1, # sockets
+ 1, # numa_nodes
+ "GenuineIntel", # vendor_id
+ "60", # model
+ "Intel Core Processor (Haswell, no TSX, IBRS)", # model_name
+ "5193.98", # bogomips
+ "32K", # l1d_cache
+ "32K", # l1i_cache
+ "4096K", # l2_cache
+ "16384K", # l3_cache
+ flags, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "x86 processor info",
+ 0, # cpu number
+ "6", # family
+ "1", # stepping
+ "2596.990", # mhz
+ "16384 KB" # cache_size
+ it_behaves_like "virtualization info",
+ "full", # virtualization_type
+ "KVM" # hypervisor_vendor
+
+ it "has virtualization" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("virtualization")
+ expect(plugin[:cpu]["virtualization"]).to eq("VT-x")
+ end
+ end
+
+ context "x86 guest on xen" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-x86-guest-xen.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-guest-xen.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-x86-guest-xen-cores.output")) }
+
+ before do
+ allow(File).to receive(:open).with("/proc/cpuinfo").and_return(cpuinfo_contents)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ flags = %w{clflush cmov constant_tsc cx16 cx8 de eagerfpu fpu fxsr ht hypervisor lahf_lm lm mmx msr nonstop_tsc nopl nx pae pat pni popcnt rep_good sep ss sse sse2 sse4_1 sse4_2 ssse3 syscall tsc}
+ numa_node_cpus = { "0" => [0, 1, 2, 3] }
+
+ it_behaves_like "Common cpu info",
+ 4, # total_cpu
+ 1, # real_cpu
+ true, # ls_cpu
+ "x86_64", # architecture
+ %w{32-bit 64-bit}, # cpu_opmodes
+ "little endian", # byte_order
+ 4, # cpus
+ 4, # cpus_online
+ 4, # threads_per_core
+ 1, # cores_per_socket
+ 1, # sockets
+ 1, # numa_nodes
+ "GenuineIntel", # vendor_id
+ "26", # model
+ "Intel(R) Xeon(R) CPU L5520 @ 2.27GHz", # model_name
+ "4533.49", # bogomips
+ "32K", # l1d_cache
+ "32K", # l1i_cache
+ "256K", # l2_cache
+ "8192K", # l3_cache
+ flags, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "x86 processor info",
+ 0, # cpu number
+ "6", # family
+ "5", # stepping
+ "2266.542", # mhz
+ "8192 KB" # cache_size
+ it_behaves_like "virtualization info",
+ "para", # virtualization_type
+ "Xen" # hypervisor_vendor
+ end
+
end
describe Ohai::System, "S390 linux cpu plugin" do
let(:plugin) { get_plugin("cpu") }
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-s390x.output")) }
before do
allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(File).to receive(:open).with("/proc/cpuinfo").and_return(cpuinfo_contents)
allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(1, "", ""))
-
- @double_file = double("/proc/cpuinfo")
- allow(@double_file).to receive(:each)
- .and_yield("vendor_id : IBM/S390")
- .and_yield("# processors : 2")
- .and_yield("bogomips per cpu: 9328.00")
- .and_yield("features : esan3 zarch stfle msa ldisp eimm dfp etf3eh highgprs")
- .and_yield("processor 0: version = EE, identification = 06E276, machine = 2717")
- .and_yield("processor 1: version = FF, identification = 06E278, machine = 2818")
- allow(File).to receive(:open).with("/proc/cpuinfo").and_return(@double_file)
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(1, "", ""))
end
- it_behaves_like "Common cpu info", 2, nil
+ it_behaves_like "Common cpu info",
+ 4, # total_cpu
+ nil, # real_cpu
+ false # ls_cpu
it "has a cpu 1" do
plugin.run
@@ -395,47 +782,629 @@ describe Ohai::System, "S390 linux cpu plugin" do
it "has a bogomips per cpu" do
plugin.run
expect(plugin[:cpu]).to have_key("bogomips_per_cpu")
- expect(plugin[:cpu]["bogomips_per_cpu"]).to eql("9328.00")
+ expect(plugin[:cpu]["bogomips_per_cpu"]).to eql("3241.00")
end
it "has features" do
plugin.run
expect(plugin[:cpu]).to have_key("features")
- expect(plugin[:cpu]["features"]).to eq(%w{esan3 zarch stfle msa ldisp eimm dfp etf3eh highgprs})
+ expect(plugin[:cpu]["features"]).to eq(%w{esan3 zarch stfle msa ldisp eimm dfp edat etf3eh highgprs te vx vxd vxe gs vxe2 vxp sort dflt})
end
- it_behaves_like "S390 processor info", 0, "EE", "06E276", "2717"
- it_behaves_like "S390 processor info", 1, "FF", "06E278", "2818"
+ it_behaves_like "S390 processor info", 0, "FF", "0618E8", "8561", false
+ it_behaves_like "S390 processor info", 1, "FF", "0618E8", "8561", false
+
+ context "with lscpu data" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-s390x.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-s390x-guest-kvm.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-s390x-guest-kvm-cores.output")) }
+
+ before do
+ allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ flags = %w{dflt dfp edat eimm esan3 etf3eh gs highgprs ldisp msa sort stfle te vx vxd vxe vxe2 vxp zarch}
+ numa_node_cpus = { "0" => [0, 1, 2, 3] }
+
+ it_behaves_like "Common cpu info",
+ 4, # total_cpu
+ 1, # real_cpu
+ true, # ls_cpu
+ "s390x", # architecture
+ %w{32-bit 64-bit}, # cpu_opmodes
+ "big endian", # byte_order
+ 4, # cpus
+ 4, # cpus_online
+ 1, # threads_per_core
+ 1, # cores_per_socket
+ nil, # sockets
+ 1, # numa_nodes
+ "IBM/S390", # vendor_id
+ nil, # model
+ nil, # model_name
+ "3241.00", # bogomips
+ "128K", # l1d_cache
+ "128K", # l1i_cache
+ nil, # l2_cache
+ "262144K", # l3_cache
+ flags, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "S390 processor info",
+ 0, # cpu_no
+ "FF", # version
+ "0618E8", # identification
+ "8561", # machine
+ false
+ it_behaves_like "S390 processor info",
+ 1, # cpu_no
+ "FF", # version
+ "0618E8", # identification
+ "8561", # machine
+ false
+
+ it "has a cpu 1" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("1")
+ end
+
+ it "has a bogomips per cpu" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("bogomips_per_cpu")
+ expect(plugin[:cpu]["bogomips_per_cpu"]).to eql("3241.00")
+ end
+
+ it "has features" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("features")
+ expect(plugin[:cpu]["features"]).to eq(flags)
+ end
+
+ it "has sockets_per_book" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("sockets_per_book")
+ expect(plugin[:cpu]["sockets_per_book"]).to eq(1)
+ end
+
+ it "has books_per_drawer" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("books_per_drawer")
+ expect(plugin[:cpu]["books_per_drawer"]).to eq(1)
+ end
+
+ it "has drawers" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("drawers")
+ expect(plugin[:cpu]["drawers"]).to eq(4)
+ end
+
+ it "has machine_type" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("machine_type")
+ expect(plugin[:cpu]["machine_type"]).to eq("8561")
+ end
+
+ it "has mhz" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("mhz")
+ expect(plugin[:cpu]["mhz"]).to eq("5200")
+ end
+
+ it "has mhz_dynamic" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("mhz_dynamic")
+ expect(plugin[:cpu]["mhz_dynamic"]).to eq("5200")
+ end
+
+ it "has hypervisor_vendor" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("hypervisor_vendor")
+ expect(plugin[:cpu]["hypervisor_vendor"]).to eq("KVM")
+ end
+
+ it "has virtualization_type" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("virtualization_type")
+ expect(plugin[:cpu]["virtualization_type"]).to eq("full")
+ end
+
+ it "has dispatching_mode" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("dispatching_mode")
+ expect(plugin[:cpu]["dispatching_mode"]).to eq("horizontal")
+ end
+
+ it "has l2d_cache" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("l2d_cache")
+ expect(plugin[:cpu]["l2d_cache"]).to eq("4096K")
+ end
+
+ it "has l2i_cache" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("l2i_cache")
+ expect(plugin[:cpu]["l2i_cache"]).to eq("4096K")
+ end
+ end
end
describe Ohai::System, "arm64 linux cpu plugin" do
let(:plugin) { get_plugin("cpu") }
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-aarch64.output")) }
before do
allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(File).to receive(:open).with("/proc/cpuinfo").and_return(cpuinfo_contents)
allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(1, "", ""))
-
- @double_file = double("/proc/cpuinfo")
- allow(@double_file).to receive(:each)
- .and_yield("processor : 0")
- .and_yield("BogoMIPS : 40.00")
- .and_yield("Features : fp asimd evtstrm aes pmull sha1 sha2 crc32")
- .and_yield("")
- .and_yield("processor : 1")
- .and_yield("BogoMIPS : 40.00")
- .and_yield("Features : fp asimd evtstrm aes pmull sha1 sha2 crc32")
- .and_yield("")
- allow(File).to receive(:open).with("/proc/cpuinfo").and_return(@double_file)
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(1, "", ""))
end
- it_behaves_like "Common cpu info", 2, nil
+ it_behaves_like "Common cpu info", 2, nil, false
it "has a cpu 1" do
plugin.run
expect(plugin[:cpu]).to have_key("1")
end
- features = %w{fp asimd evtstrm aes pmull sha1 sha2 crc32}
- it_behaves_like "arm64 processor info", 0, "40.00", features
- it_behaves_like "arm64 processor info", 1, "40.00", features
+ features = %w{fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid}
+ it_behaves_like "arm64 processor info",
+ 0, # cpu_no
+ "80.00", # bogomips
+ features # features
+ it_behaves_like "arm64 processor info",
+ 1, # cpu_no
+ "80.00", # bogomips
+ features # features
+
+ context "with lscpu data" do
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-aarch64-host.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-aarch64-host-cores.output")) }
+
+ before do
+ allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ flags = %w{aes asimd cpuid crc32 evtstrm fp pmull sha1 sha2}
+ numa_node_cpus = { "0" => Range.new(0, 31).to_a }
+
+ it_behaves_like "Common cpu info",
+ 32, # total_cpu
+ 1, # real_cpu
+ true, # ls_cpu
+ "aarch64", # architecture
+ nil, # cpu_opmodes
+ "little endian", # byte_order
+ 32, # cpus
+ 32, # cpus_online
+ 1, # threads_per_core
+ 32, # cores_per_socket
+ 1, # sockets
+ 1, # numa_nodes
+ nil, # vendor_id
+ "2", # model
+ nil, # model_name
+ "80.00", # bogomips
+ "32K", # l1d_cache
+ "32K", # l1i_cache
+ "256K", # l2_cache
+ nil, # l3_cache
+ flags, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "arm64 processor info",
+ 0, # cpu_no
+ "80.00", # bogomips
+ flags # features
+ it_behaves_like "arm64 processor info",
+ 1, # cpu_no
+ "80.00", # bogomips
+ flags # features
+
+ it "has a cpu 1" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("1")
+ end
+
+ it "has mhz_max" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("mhz_max")
+ expect(plugin[:cpu]["mhz_max"]).to eq("3300.0000")
+ end
+
+ it "has mhz_min" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("mhz_min")
+ expect(plugin[:cpu]["mhz_min"]).to eq("363.9700")
+ end
+ end
+
+ context "aarch64 kvm guest" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-aarch64-guest-kvm.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-aarch64-guest-kvm.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-aarch64-guest-kvm-cores.output")) }
+
+ before do
+ allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ flags = %w{aes asimd cpuid crc32 evtstrm fp pmull sha1 sha2}
+ numa_node_cpus = { "0" => Range.new(0, 1).to_a }
+
+ it_behaves_like "Common cpu info",
+ 2, # total_cpu
+ 1, # real_cpu
+ true, # ls_cpu
+ "aarch64", # architecture
+ nil, # cpu_opmodes
+ "little endian", # byte_order
+ 2, # cpus
+ 2, # cpus_online
+ 1, # threads_per_core
+ 2, # cores_per_socket
+ 1, # sockets
+ 1, # numa_nodes
+ nil, # vendor_id
+ "2", # model
+ nil, # model_name
+ "80.00", # bogomips
+ nil, # l1d_cache
+ nil, # l1i_cache
+ nil, # l2_cache
+ nil, # l3_cache
+ flags, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "arm64 processor info",
+ 0, # cpu_no
+ "80.00", # bogomips
+ flags # features
+ end
+
+ context "aarch64 graviton2 guest" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-aarch64-graviton2.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-aarch64-graviton2.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-aarch64-graviton2-cores.output")) }
+
+ before do
+ allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ flags = %w{aes asimd asimddp asimdhp asimdrdm atomics cpuid crc32 dcpop evtstrm fp fphp lrcpc pmull sha1 sha2 ssbs}
+ numa_node_cpus = { "0" => Range.new(0, 1).to_a }
+
+ it_behaves_like "Common cpu info",
+ 2, # total_cpu
+ 1, # real_cpu
+ true, # ls_cpu
+ "aarch64", # architecture
+ %w{32-bit 64-bit}, # cpu_opmodes
+ "little endian", # byte_order
+ 2, # cpus
+ 2, # cpus_online
+ 1, # threads_per_core
+ 2, # cores_per_socket
+ 1, # sockets
+ 1, # numa_nodes
+ "ARM", # vendor_id
+ "1", # model
+ "Neoverse-N1", # model_name
+ "243.75", # bogomips
+ "128 KiB", # l1d_cache
+ "128 KiB", # l1i_cache
+ "2 MiB", # l2_cache
+ "32 MiB", # l3_cache
+ flags, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "arm64 processor info",
+ 0, # cpu_no
+ "243.75", # bogomips
+ flags # features
+
+ it "has stepping" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("stepping")
+ expect(plugin[:cpu]["stepping"]).to eq("r3p1")
+ end
+ end
+end
+
+describe Ohai::System, "ppc64le linux cpu plugin (POWER9)" do
+ let(:plugin) { get_plugin("cpu") }
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-ppc64le-p9-host.output")) }
+
+ before do
+ allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(File).to receive(:open).with("/proc/cpuinfo").and_return(cpuinfo_contents)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(1, "", ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(1, "", ""))
+ end
+
+ it_behaves_like "Common cpu info",
+ 2, # total_cpu
+ nil, # real_cpu
+ false # ls_cpu
+
+ it "has a cpu 0" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("0")
+ end
+
+ it "has a cpu 4" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("4")
+ end
+
+ context "with lscpu data" do
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-ppc64le-p9-host.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-ppc64le-p9-host-cores.output")) }
+
+ before do
+ allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ numa_node_cpus =
+ {
+ "0" => [0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60],
+ "8" => [64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124],
+ }
+
+ it_behaves_like "Common cpu info",
+ 32, # total_cpu
+ 2, # real_cpu
+ true, # ls_cpu
+ "ppc64le", # architecture
+ nil, # cpu_opmodes
+ "little endian", # byte_order
+ 128, # cpus
+ 32, # cpus_online
+ 1, # threads_per_core
+ 16, # cores_per_socket
+ 2, # sockets
+ 2, # numa_nodes
+ nil, # vendor_id
+ "2.2 (pvr 004e 1202)", # model
+ "POWER9, altivec supported", # model_name
+ nil, # bogomips
+ "32K", # l1d_cache
+ "32K", # l1i_cache
+ "512K", # l2_cache
+ "10240K", # l3_cache
+ nil, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "ppc64le processor info",
+ 0, # cpu_no
+ "POWER9, altivec supported", # model_name
+ "2.2 (pvr 004e 1202)", # model
+ "2166.000000MHz", # mhz
+ "512000000", # timebase
+ "PowerNV", # platform
+ "9006-12P", # machine_model
+ "PowerNV 9006-12P", # machine
+ "OPAL", # firmware
+ "Radix" # mmu
+
+ it "has a cpu 0" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("0")
+ end
+
+ it "has cpus_offline" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("cpus_offline")
+ expect(plugin[:cpu]["cpus_offline"]).to eq(96)
+ end
+
+ it "has mhz_max" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("mhz_max")
+ expect(plugin[:cpu]["mhz_max"]).to eq("3800.0000")
+ end
+
+ it "has mhz_min" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("mhz_min")
+ expect(plugin[:cpu]["mhz_min"]).to eq("2166.0000")
+ end
+ end
+
+ context "POWER8 host" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-ppc64le-p8-host.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-ppc64le-p8-host.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-ppc64le-p8-host-cores.output")) }
+
+ before do
+ allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ numa_node_cpus =
+ {
+ "0" => [0, 8, 16, 24, 32],
+ "1" => [40, 48, 56, 64, 72],
+ "16" => [80, 88, 96, 104, 112],
+ "17" => [120, 128, 136, 144, 152],
+ }
+
+ it_behaves_like "Common cpu info",
+ 20, # total_cpu
+ 4, # real_cpu
+ true, # ls_cpu
+ "ppc64le", # architecture
+ nil, # cpu_opmodes
+ "little endian", # byte_order
+ 160, # cpus
+ 20, # cpus_online
+ 1, # threads_per_core
+ 5, # cores_per_socket
+ 4, # sockets
+ 4, # numa_nodes
+ nil, # vendor_id
+ "2.1 (pvr 004b 0201)", # model
+ "POWER8E (raw), altivec supported", # model_name
+ nil, # bogomips
+ "64K", # l1d_cache
+ "32K", # l1i_cache
+ "512K", # l2_cache
+ "8192K", # l3_cache
+ nil, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "ppc64le processor info",
+ 0, # cpu_no
+ "POWER8E (raw), altivec supported", # model_name
+ "2.1 (pvr 004b 0201)", # model
+ "3690.000000MHz", # mhz
+ "512000000", # timebase
+ "PowerNV", # platform
+ "8247-22L", # machine_model
+ "PowerNV 8247-22L", # machine
+ "OPAL", # firmware
+ "Hash" # mmu
+
+ it "has a cpu 0" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("0")
+ end
+
+ it "has cpus_offline" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("cpus_offline")
+ expect(plugin[:cpu]["cpus_offline"]).to eq(140)
+ end
+
+ it "has mhz_max" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("mhz_max")
+ expect(plugin[:cpu]["mhz_max"]).to eq("3690.0000")
+ end
+
+ it "has mhz_min" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("mhz_min")
+ expect(plugin[:cpu]["mhz_min"]).to eq("2061.0000")
+ end
+ end
+
+ context "POWER8 KVM guest" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-ppc64le-p8-guest-kvm.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-ppc64le-p8-guest-kvm.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-ppc64le-p8-guest-kvm-cores.output")) }
+
+ before do
+ allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ numa_node_cpus = { "0" => Range.new(0, 15).to_a }
+
+ it_behaves_like "Common cpu info",
+ 16, # total_cpu
+ 16, # real_cpu
+ true, # ls_cpu
+ "ppc64le", # architecture
+ nil, # cpu_opmodes
+ "little endian", # byte_order
+ 16, # cpus
+ 16, # cpus_online
+ 1, # threads_per_core
+ 1, # cores_per_socket
+ 16, # sockets
+ 1, # numa_nodes
+ nil, # vendor_id
+ "2.1 (pvr 004b 0201)", # model
+ "POWER8 (architected), altivec supported", # model_name
+ nil, # bogomips
+ "64K", # l1d_cache
+ "32K", # l1i_cache
+ nil, # l2_cache
+ nil, # l3_cache
+ nil, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "ppc64le processor info",
+ 0, # cpu_no
+ "POWER8 (architected), altivec supported", # model_name
+ "2.1 (pvr 004b 0201)", # model
+ "3425.000000MHz", # mhz
+ "512000000", # timebase
+ "pSeries", # platform
+ "IBM pSeries (emulated by qemu)", # machine_model
+ "CHRP IBM pSeries (emulated by qemu)", # machine
+ nil, # firmware
+ nil # mmu
+
+ it_behaves_like "virtualization info",
+ "para", # virtualization_type
+ "KVM" # hypervisor_vendor
+
+ it "has a cpu 0" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("0")
+ end
+ end
+
+ context "POWER9 KVM guest" do
+ let(:cpuinfo_contents) { File.read(File.join(SPEC_PLUGIN_PATH, "cpuinfo-ppc64le-p9-guest-kvm.output")) }
+ let(:lscpu) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-ppc64le-p9-guest-kvm.output")) }
+ let(:lscpu_cores) { File.read(File.join(SPEC_PLUGIN_PATH, "lscpu-ppc64le-p9-guest-kvm-cores.output")) }
+
+ before do
+ allow(plugin).to receive(:collect_os).and_return(:linux)
+ allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, ""))
+ allow(plugin).to receive(:shell_out).with("lscpu -p=CPU,CORE,SOCKET").and_return(mock_shell_out(0, lscpu_cores, ""))
+ end
+
+ numa_node_cpus = { "0" => Range.new(0, 15).to_a }
+
+ it_behaves_like "Common cpu info",
+ 16, # total_cpu
+ 16, # real_cpu
+ true, # ls_cpu
+ "ppc64le", # architecture
+ nil, # cpu_opmodes
+ "little endian", # byte_order
+ 16, # cpus
+ 16, # cpus_online
+ 1, # threads_per_core
+ 1, # cores_per_socket
+ 16, # sockets
+ 1, # numa_nodes
+ nil, # vendor_id
+ "2.2 (pvr 004e 1202)", # model
+ "POWER9 (architected), altivec supported", # model_name
+ nil, # bogomips
+ "32K", # l1d_cache
+ "32K", # l1i_cache
+ nil, # l2_cache
+ nil, # l3_cache
+ nil, # flags
+ numa_node_cpus # numa_node_cpus
+ it_behaves_like "ppc64le processor info",
+ 0, # cpu_no
+ "POWER9 (architected), altivec supported", # model_name
+ "2.2 (pvr 004e 1202)", # model
+ "2200.000000MHz", # mhz
+ "512000000", # timebase
+ "pSeries", # platform
+ "IBM pSeries (emulated by qemu)", # machine_model
+ "CHRP IBM pSeries (emulated by qemu)", # machine
+ nil, # firmware
+ "Radix" # mmu
+
+ it_behaves_like "virtualization info",
+ "para", # virtualization_type
+ "KVM" # hypervisor_vendor
+
+ it "has a cpu 0" do
+ plugin.run
+ expect(plugin[:cpu]).to have_key("0")
+ end
+ end
end