From 1a314662fe100e0a915ce6238a2118476682ea8d Mon Sep 17 00:00:00 2001 From: Oana Tanasoiu Date: Tue, 28 Apr 2020 11:56:10 +0300 Subject: [PATCH] (FACT-2553) Quote special string in YAML format --- .rubocop_todo.yml | 11 +- lib/facts/windows/networking/primary.rb | 2 +- .../formatters/yaml_fact_formatter.rb | 54 ++++++++- lib/resolvers/windows/ffi/network_utils.rb | 2 +- lib/resolvers/windows/networking_resolver.rb | 15 +-- .../windows/virtualization_resolver.rb | 9 +- .../facter/facts/windows/fips_enabled_spec.rb | 2 +- .../facts/windows/networking/primary_spec.rb | 21 +++- .../utils/windows/network_utils_spec.rb | 22 ++-- .../windows/networking_resolver_spec.rb | 48 ++++---- .../windows/virtualization_resolver_spec.rb | 106 +++++++++++++----- .../formatters/yaml_fact_formatter_spec.rb | 10 +- spec/mocks/win32ole_mock.rb | 6 + 13 files changed, 213 insertions(+), 95 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 3d337cbbc..8939043ac 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 1000` -# on 2020-05-06 13:07:31 +0300 using RuboCop version 0.74.0. +# on 2020-05-07 16:13:14 +0300 using RuboCop version 0.74.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -110,7 +110,7 @@ RSpec/LeakyConstantDeclaration: - 'spec/facter/resolvers/macosx/mountpoints_resolver_spec.rb' - 'spec/facter/resolvers/utils/windows/network_utils_spec.rb' -# Offense count: 114 +# Offense count: 108 # Configuration parameters: EnforcedStyle. # SupportedStyles: have_received, receive RSpec/MessageSpies: @@ -146,7 +146,6 @@ RSpec/MessageSpies: - 'spec/facter/facts/windows/dmi/product/name_spec.rb' - 'spec/facter/facts/windows/dmi/product/serial_number_spec.rb' - 'spec/facter/facts/windows/dmi/product/uuid_spec.rb' - - 'spec/facter/facts/windows/fips_enabled_spec.rb' - 'spec/facter/facts/windows/identity/user_spec.rb' - 'spec/facter/facts/windows/ipaddress6_interfaces_spec.rb' - 'spec/facter/facts/windows/ipaddress_interfaces_spec.rb' @@ -176,7 +175,6 @@ RSpec/MessageSpies: - 'spec/facter/facts/windows/ruby/sitedir_spec.rb' - 'spec/facter/facts/windows/scope6_interfaces_spec.rb' - 'spec/facter/resolvers/utils/aix/odm_query_spec.rb' - - 'spec/framework/core/fact_loaders/external_fact_loader_spec.rb' # Offense count: 26 RSpec/SubjectStub: @@ -189,7 +187,7 @@ RSpec/SubjectStub: - 'spec/custom_facts/util/fact_spec.rb' - 'spec/custom_facts/util/resolution_spec.rb' -# Offense count: 162 +# Offense count: 132 # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. RSpec/VerifiedDoubles: Exclude: @@ -217,7 +215,6 @@ RSpec/VerifiedDoubles: - 'spec/facter/facts/windows/networking/dhcp_spec.rb' - 'spec/facter/facts/windows/networking/interfaces_spec.rb' - 'spec/facter/facts/windows/networking/mtu_spec.rb' - - 'spec/facter/facts/windows/networking/primary_spec.rb' - 'spec/facter/facts/windows/processors/models_spec.rb' - 'spec/facter/facts/windows/virtualization/is_virtual_spec.rb' - 'spec/facter/facts/windows/virtualization/virtual_spec.rb' @@ -236,11 +233,9 @@ RSpec/VerifiedDoubles: - 'spec/facter/resolvers/windows/identity_resolver_spec.rb' - 'spec/facter/resolvers/windows/kernel_resolver_spec.rb' - 'spec/facter/resolvers/windows/memory_resolver_spec.rb' - - 'spec/facter/resolvers/windows/networking_resolver_spec.rb' - 'spec/facter/resolvers/windows/processors_resolver_spec.rb' - 'spec/facter/resolvers/windows/system32_resolver_spec.rb' - 'spec/facter/resolvers/windows/uptime_resolver_spec.rb' - - 'spec/facter/resolvers/windows/virtualization_resolver_spec.rb' - 'spec/facter/resolvers/windows/win_os_description_resolver_spec.rb' - 'spec/framework/core/fact_loaders/external_fact_loader_spec.rb' - 'spec/framework/core/fact_loaders/fact_loader_spec.rb' diff --git a/lib/facts/windows/networking/primary.rb b/lib/facts/windows/networking/primary.rb index ee740b326..393cb18bb 100644 --- a/lib/facts/windows/networking/primary.rb +++ b/lib/facts/windows/networking/primary.rb @@ -7,7 +7,7 @@ class Primary FACT_NAME = 'networking.primary' def call_the_resolver - fact_value = Facter::Resolvers::Networking.resolve(:primary) + fact_value = Facter::Resolvers::Networking.resolve(:primary_interface) Facter::ResolvedFact.new(FACT_NAME, fact_value) end diff --git a/lib/framework/formatters/yaml_fact_formatter.rb b/lib/framework/formatters/yaml_fact_formatter.rb index ee5687991..3611db39f 100644 --- a/lib/framework/formatters/yaml_fact_formatter.rb +++ b/lib/framework/formatters/yaml_fact_formatter.rb @@ -6,13 +6,59 @@ def initialize @log = Log.new(self) end - def format(fact_hash) - yaml_pretty = YAML.dump(JSON.parse(JsonFactFormatter.new.format(fact_hash))) + def format(resolved_facts) + user_queries = resolved_facts.uniq(&:user_query).map(&:user_query) + + facts_to_display = if user_queries.count == 1 && user_queries.first.empty? + FormatterHelper.retrieve_fact_collection(resolved_facts) + else + FormatterHelper.retrieve_facts_to_display_for_user_query(user_queries, resolved_facts) + end + + facts_to_display = Psych.parse_stream(facts_to_display.to_yaml) + facts_to_display.children[0].tag_directives = [] + yaml_pretty = quote_special_strings(facts_to_display) - @log.debug('Replace single backslash with double backslashes') - yaml_pretty.gsub!(/\\/, '\&\&') @log.debug('Replace --- from yaml beginning, to keep it compatible with C facter') yaml_pretty.gsub(/^---[\r\n]+/, '') end + + private + + def quote_special_strings(fact_hash) + require 'psych' + + fact_hash.grep(Psych::Nodes::Scalar).each do |node| + next unless needs_quote?(node.value) + + node.plain = false + node.quoted = true + node.style = Psych::Nodes::Scalar::DOUBLE_QUOTED + end + + fact_hash = unquote_keys(fact_hash) + fact_hash.yaml + end + + def unquote_keys(fact_hash) + fact_hash.grep(Psych::Nodes::Mapping).each do |node| + node.children.each_slice(2) do |k, _| + k.plain = true + k.quoted = false + k.style = Psych::Nodes::Scalar::ANY + end + end + fact_hash + end + + def needs_quote?(value) + return false if value =~ /true|false/ + return false if value[/^[0-9]+$/] + return true if value =~ /y|Y|yes|Yes|YES|n|N|no|No|NO|True|TRUE|False|FALSE|on|On|ON|off|Off|OFF|:/ + return false if value[/[a-zA-Z]/] + return false if value[/[0-9]+\.[0-9]+\./] + + true + end end end diff --git a/lib/resolvers/windows/ffi/network_utils.rb b/lib/resolvers/windows/ffi/network_utils.rb index e5833e99e..143801526 100644 --- a/lib/resolvers/windows/ffi/network_utils.rb +++ b/lib/resolvers/windows/ffi/network_utils.rb @@ -42,7 +42,7 @@ def build_binding(addr, mask_length) else IPAddr.new('255.255.255.255').mask(mask_length) end - { address: addr, netmask: mask, network: ip.mask(mask_length) } + { address: addr, netmask: mask.to_s, network: ip.mask(mask_length).to_s } end def get_scope(sockaddr) diff --git a/lib/resolvers/windows/networking_resolver.rb b/lib/resolvers/windows/networking_resolver.rb index 7e084f315..a8df0cb15 100644 --- a/lib/resolvers/windows/networking_resolver.rb +++ b/lib/resolvers/windows/networking_resolver.rb @@ -27,6 +27,7 @@ def read_network_information(fact_name) iterate_list(adapter_addresses) set_interfaces_other_facts if @fact_list[:interfaces] + @fact_list[:primary_interface] = @fact_list[:primary_interface].to_s @fact_list[fact_name] end @@ -112,8 +113,8 @@ def add_ip_data(addr, unicast, sock_addr, bindings) result = find_bindings(sock_addr, unicast, addr) return unless result - bindings[:ipv6] << result if result[:network].ipv6? - bindings[:ipv4] << result if result[:network].ipv4? + bindings[:ipv6] << result if sock_addr[:sa_family] == NetworkingFFI::AF_INET6 + bindings[:ipv4] << result if sock_addr[:sa_family] == NetworkingFFI::AF_INET end def find_bindings(sock_addr, unicast, addr) @@ -126,7 +127,7 @@ def find_primary_interface(sock_addr, name, addr) if !@fact_list[:primary_interface] && ([NetworkingFFI::AF_INET, NetworkingFFI::AF_INET6].include?(sock_addr[:sa_family]) && !NetworkUtils.ignored_ip_address(addr)) - @fact_list[:primary] = name + @fact_list[:primary_interface] = name end end @@ -138,7 +139,7 @@ def set_interfaces_other_facts end if value[:bindings6] binding = find_valid_binding(value[:bindings6]) - populate_interface(binding, value) + populate_interface(binding, value, true) end set_networking_other_facts(value, interface_name) end @@ -151,10 +152,10 @@ def find_valid_binding(bindings) bindings.empty? ? nil : bindings.first end - def populate_interface(bind, interface) + def populate_interface(bind, interface, ipv6 = false) return if !bind || bind.empty? - if bind[:network].ipv6? + if ipv6 interface[:ip6] = bind[:address] interface[:netmask6] = bind[:netmask] interface[:network6] = bind[:network] @@ -167,7 +168,7 @@ def populate_interface(bind, interface) end def set_networking_other_facts(value, interface_name) - return unless @fact_list[:primary] == interface_name + return unless @fact_list[:primary_interface] == interface_name %i[mtu dhcp mac ip ip6 scope6 netmask netmask6 network network6].each do |key| @fact_list[key] = value[key] diff --git a/lib/resolvers/windows/virtualization_resolver.rb b/lib/resolvers/windows/virtualization_resolver.rb index 063d20201..f8df3cd35 100644 --- a/lib/resolvers/windows/virtualization_resolver.rb +++ b/lib/resolvers/windows/virtualization_resolver.rb @@ -11,6 +11,9 @@ class << self # Virtual # Is_Virtual + MODEL_HASH = { 'VirtualBox' => 'virtualbox', 'VMware' => 'vmware', 'KVM' => 'kvm', + 'Bochs' => 'bochs', 'Google' => 'gce', 'OpenStack' => 'openstack' }.freeze + private def post_resolve(fact_name) @@ -31,9 +34,7 @@ def read_fact_from_computer_system(fact_name) end def determine_hypervisor_by_model(comp) - model_hash = { 'VirtualBox' => 'virtualbox', 'VMware' => 'vmware', 'KVM' => 'kvm', - 'Bochs' => 'bochs', 'Google' => 'gce', 'OpenStack' => 'openstack' } - model_hash[model_hash.keys.find { |key| comp.Model =~ /^#{key}/ }] + MODEL_HASH[MODEL_HASH.keys.find { |key| comp.Model =~ /^#{key}/ }] end def determine_hypervisor_by_manufacturer(comp) @@ -57,7 +58,7 @@ def build_fact_list(comp) hypervisor = determine_hypervisor_by_model(comp) || determine_hypervisor_by_manufacturer(comp) @fact_list[:virtual] = hypervisor - @fact_list[:is_virtual] = (!hypervisor.include?('physical')).to_s + @fact_list[:is_virtual] = hypervisor.include?('physical') ? false : true end end end diff --git a/spec/facter/facts/windows/fips_enabled_spec.rb b/spec/facter/facts/windows/fips_enabled_spec.rb index e897311b5..c89b843bd 100644 --- a/spec/facter/facts/windows/fips_enabled_spec.rb +++ b/spec/facter/facts/windows/fips_enabled_spec.rb @@ -11,8 +11,8 @@ end it 'calls Facter::Windows::Resolvers::Fips' do - expect(Facter::Resolvers::Windows::Fips).to receive(:resolve).with(:fips_enabled) fact.call_the_resolver + expect(Facter::Resolvers::Windows::Fips).to have_received(:resolve).with(:fips_enabled) end it 'returns true if fips enabled' do diff --git a/spec/facter/facts/windows/networking/primary_spec.rb b/spec/facter/facts/windows/networking/primary_spec.rb index d6f0dc138..8e3f96cdc 100644 --- a/spec/facter/facts/windows/networking/primary_spec.rb +++ b/spec/facter/facts/windows/networking/primary_spec.rb @@ -2,13 +2,22 @@ describe Facts::Windows::Networking::Primary do describe '#call_the_resolver' do - it 'returns a fact' do - expected_fact = double(Facter::ResolvedFact, name: 'networking.primary', value: 'value') - allow(Facter::Resolvers::Networking).to receive(:resolve).with(:primary).and_return('value') - allow(Facter::ResolvedFact).to receive(:new).with('networking.primary', 'value').and_return(expected_fact) + subject(:fact) { Facts::Windows::Networking::Primary.new } - fact = Facts::Windows::Networking::Primary.new - expect(fact.call_the_resolver).to eq(expected_fact) + let(:value) { 'Ethernet0' } + + before do + allow(Facter::Resolvers::Networking).to receive(:resolve).with(:primary_interface).and_return(value) + end + + it 'calls Facter::Windows::Resolvers::Fips' do + fact.call_the_resolver + expect(Facter::Resolvers::Networking).to have_received(:resolve).with(:primary_interface) + end + + it 'returns true if fips enabled' do + expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact).and \ + have_attributes(name: 'networking.primary', value: value) end end end diff --git a/spec/facter/resolvers/utils/windows/network_utils_spec.rb b/spec/facter/resolvers/utils/windows/network_utils_spec.rb index 4375ff3aa..3c14701e9 100644 --- a/spec/facter/resolvers/utils/windows/network_utils_spec.rb +++ b/spec/facter/resolvers/utils/windows/network_utils_spec.rb @@ -3,9 +3,9 @@ describe NetworkUtils do describe '#address_to_strig' do let(:logger) { instance_spy(Facter::Log) } - let(:addr) { double('SocketAddress') } - let(:size) { double(FFI::MemoryPointer) } - let(:buffer) { double(FFI::MemoryPointer) } + let(:addr) { instance_spy('SocketAddress') } + let(:size) { instance_spy(FFI::MemoryPointer) } + let(:buffer) { instance_spy(FFI::MemoryPointer) } let(:length) { 32 } before do @@ -31,7 +31,7 @@ end context 'when error code is zero' do - let(:address) { double(FFI::MemoryPointer) } + let(:address) { instance_spy(FFI::MemoryPointer) } let(:error) { 0 } it 'returns an address' do @@ -40,7 +40,7 @@ end context 'when error code is not zero' do - let(:address) { double(FFI::MemoryPointer) } + let(:address) { instance_spy(FFI::MemoryPointer) } let(:error) { 1 } it 'returns nil and logs debug message' do @@ -90,8 +90,8 @@ describe '#build_binding' do context 'when input is ipv4 address' do - let(:netmask) { IPAddr.new('255.255.240.0/255.255.240.0') } - let(:network) { IPAddr.new('10.16.112.0/255.255.240.0') } + let(:netmask) { IPAddr.new('255.255.240.0/255.255.240.0').to_s } + let(:network) { IPAddr.new('10.16.112.0/255.255.240.0').to_s } let(:addr) { '10.16.121.248' } it 'returns ipv4 binding' do @@ -100,8 +100,12 @@ end context 'when input is ipv6 address' do - let(:network) { IPAddr.new('fe80:0000:0000:0000:0000:0000:0000:0000/ffff:ffff:ffff:ffff:0000:0000:0000:0000') } - let(:netmask) { IPAddr.new('ffff:ffff:ffff:ffff:0000:0000:0000:0000/ffff:ffff:ffff:ffff:0000:0000:0000:0000') } + let(:network) do + IPAddr.new('fe80:0000:0000:0000:0000:0000:0000:0000/ffff:ffff:ffff:ffff:0000:0000:0000:0000').to_s + end + let(:netmask) do + IPAddr.new('ffff:ffff:ffff:ffff:0000:0000:0000:0000/ffff:ffff:ffff:ffff:0000:0000:0000:0000').to_s + end let(:addr) { 'fe80::dc20:a2b9:5253:9b46' } it 'returns ipv6 binding' do diff --git a/spec/facter/resolvers/windows/networking_resolver_spec.rb b/spec/facter/resolvers/windows/networking_resolver_spec.rb index 5c1489c52..2d016e01e 100644 --- a/spec/facter/resolvers/windows/networking_resolver_spec.rb +++ b/spec/facter/resolvers/windows/networking_resolver_spec.rb @@ -5,8 +5,8 @@ describe '#resolve' do let(:logger) { instance_spy(Facter::Log) } - let(:size_ptr) { double(FFI::MemoryPointer) } - let(:adapter_address) { double(FFI::MemoryPointer) } + let(:size_ptr) { instance_spy(FFI::MemoryPointer) } + let(:adapter_address) { instance_spy(FFI::MemoryPointer) } before do allow(FFI::MemoryPointer).to receive(:new) @@ -65,7 +65,7 @@ context 'when it succeeded to retrieve networking information but all interface are down' do let(:error_code) { NetworkingFFI::ERROR_SUCCES } let(:adapter) { OpenStruct.new(OperStatus: NetworkingFFI::IF_OPER_STATUS_DOWN, Next: next_adapter) } - let(:next_adapter) { double(FFI::Pointer) } + let(:next_adapter) { instance_spy(FFI::Pointer) } before do allow(IpAdapterAddressesLh).to receive(:read_list).with(adapter_address).and_yield(adapter) @@ -85,9 +85,9 @@ DnsSuffix: dns_ptr, FriendlyName: friendly_name_ptr, Flags: 0, Mtu: 1500, FirstUnicastAddress: ptr) end - let(:dns_ptr) { double(FFI::Pointer, read_wide_string_without_length: '10.122.0.2') } - let(:friendly_name_ptr) { double(FFI::Pointer, read_wide_string_without_length: 'Ethernet0') } - let(:ptr) { double(FFI::Pointer) } + let(:dns_ptr) { instance_spy(FFI::Pointer) } + let(:friendly_name_ptr) { instance_spy(FFI::Pointer) } + let(:ptr) { instance_spy(FFI::Pointer) } let(:unicast) { OpenStruct.new(Address: ptr, Next: ptr, to_ptr: FFI::Pointer::NULL) } before do @@ -96,6 +96,8 @@ allow(NetworkUtils).to receive(:address_to_string).with(ptr).and_return(nil) allow(IpAdapterUnicastAddressLH).to receive(:new).with(ptr).and_return(unicast) allow(NetworkUtils).to receive(:find_mac_address).with(adapter).and_return('00:50:56:9A:F8:6B') + allow(friendly_name_ptr).to receive(:read_wide_string_without_length).and_return('Ethernet0') + allow(dns_ptr).to receive(:read_wide_string_without_length).and_return('10.122.0.2') end it 'returns interfaces' do @@ -127,17 +129,17 @@ DnsSuffix: dns_ptr, FriendlyName: friendly_name_ptr, Flags: 0, Mtu: 1500, FirstUnicastAddress: ptr, Next: ptr, to_ptr: FFI::Pointer::NULL) end - let(:ptr) { double(FFI::Pointer) } - let(:dns_ptr) { double(FFI::Pointer, read_wide_string_without_length: '10.122.0.2') } - let(:friendly_name_ptr) { double(FFI::Pointer, read_wide_string_without_length: 'Ethernet0') } + let(:ptr) { instance_spy(FFI::Pointer) } + let(:dns_ptr) { instance_spy(FFI::Pointer) } + let(:friendly_name_ptr) { instance_spy(FFI::Pointer) } let(:unicast) { OpenStruct.new(Address: address, Next: ptr, to_ptr: FFI::Pointer::NULL, OnLinkPrefixLength: 24) } let(:address) { OpenStruct.new(lpSockaddr: ptr) } let(:sock_address) { OpenStruct.new(sa_family: NetworkingFFI::AF_INET) } let(:binding) do { address: '10.16.127.3', - netmask: IPAddr.new('255.255.255.0/255.255.255.0'), - network: IPAddr.new('10.16.127.0/255.255.255.0') + netmask: '255.255.255.0', + network: '10.16.127.0' } end @@ -150,6 +152,8 @@ allow(IpAdapterUnicastAddressLH).to receive(:new).with(ptr).and_return(unicast) allow(NetworkUtils).to receive(:find_mac_address).with(adapter).and_return('00:50:56:9A:F8:6B') allow(IpAdapterAddressesLh).to receive(:new).with(ptr).and_return(adapter) + allow(dns_ptr).to receive(:read_wide_string_without_length).and_return('10.122.0.2') + allow(friendly_name_ptr).to receive(:read_wide_string_without_length).and_return('Ethernet0') end it 'returns interface' do @@ -160,8 +164,8 @@ ip: '10.16.127.3', mac: '00:50:56:9A:F8:6B', mtu: 1500, - netmask: IPAddr.new('255.255.255.0/255.255.255.0'), - network: IPAddr.new('10.16.127.0/255.255.255.0') + netmask: '255.255.255.0', + network: '10.16.127.0' } } expect(resolver.resolve(:interfaces)).to eql(result) @@ -175,17 +179,17 @@ DnsSuffix: dns_ptr, FriendlyName: friendly_name_ptr, Flags: 0, Mtu: 1500, FirstUnicastAddress: ptr, Next: ptr, to_ptr: FFI::Pointer::NULL) end - let(:ptr) { double(FFI::Pointer) } - let(:dns_ptr) { double(FFI::Pointer, read_wide_string_without_length: '10.122.0.2') } - let(:friendly_name_ptr) { double(FFI::Pointer, read_wide_string_without_length: 'Ethernet0') } + let(:ptr) { instance_spy(FFI::Pointer) } + let(:dns_ptr) { instance_spy(FFI::Pointer) } + let(:friendly_name_ptr) { instance_spy(FFI::Pointer) } let(:unicast) { OpenStruct.new(Address: address, Next: ptr, to_ptr: FFI::Pointer::NULL, OnLinkPrefixLength: 24) } let(:address) { OpenStruct.new(lpSockaddr: ptr) } - let(:sock_address) { OpenStruct.new(sa_family: NetworkingFFI::AF_INET) } + let(:sock_address) { OpenStruct.new(sa_family: NetworkingFFI::AF_INET6) } let(:binding) do { address: 'fe80::7ca0:ab22:703a:b329', - netmask: IPAddr.new('ffff:ff00:0000:0000:0000:0000:0000:0000/ffff:ff00:0000:0000:0000:0000:0000:0000'), - network: IPAddr.new('fe80:0000:0000:0000:0000:0000:0000:0000/ffff:ff00:0000:0000:0000:0000:0000:0000') + netmask: 'ffff:ff00::', + network: 'fe80::' } end @@ -198,6 +202,8 @@ allow(IpAdapterUnicastAddressLH).to receive(:new).with(ptr).and_return(unicast) allow(NetworkUtils).to receive(:find_mac_address).with(adapter).and_return('00:50:56:9A:F8:6B') allow(IpAdapterAddressesLh).to receive(:new).with(ptr).and_return(adapter) + allow(dns_ptr).to receive(:read_wide_string_without_length).and_return('10.122.0.2') + allow(friendly_name_ptr).to receive(:read_wide_string_without_length).and_return('Ethernet0') end it 'returns interface' do @@ -208,8 +214,8 @@ ip6: 'fe80::7ca0:ab22:703a:b329', mac: '00:50:56:9A:F8:6B', mtu: 1500, - netmask6: IPAddr.new('ffff:ff00:0000:0000:0000:0000:0000:0000/ffff:ff00:0000:0000:0000:0000:0000:0000'), - network6: IPAddr.new('fe80:0000:0000:0000:0000:0000:0000:0000/ffff:ff00:0000:0000:0000:0000:0000:0000'), + netmask6: 'ffff:ff00::', + network6: 'fe80::', scope6: 'link' } } diff --git a/spec/facter/resolvers/windows/virtualization_resolver_spec.rb b/spec/facter/resolvers/windows/virtualization_resolver_spec.rb index 6d0521c69..7ad9c042d 100644 --- a/spec/facter/resolvers/windows/virtualization_resolver_spec.rb +++ b/spec/facter/resolvers/windows/virtualization_resolver_spec.rb @@ -2,13 +2,14 @@ describe Facter::Resolvers::Virtualization do let(:logger) { instance_spy(Facter::Log) } + let(:win32ole) { instance_spy('WIN32OLE') } + let(:win32ole2) { instance_spy('WIN32OLE') } + let(:win) { instance_spy('Win32Ole') } before do - win = double('Win32Ole') - allow(Win32Ole).to receive(:new).and_return(win) allow(win).to receive(:exec_query).with('SELECT Manufacturer,Model,OEMStringArray FROM Win32_ComputerSystem') - .and_return(comp) + .and_return(query_result) Facter::Resolvers::Virtualization.instance_variable_set(:@log, logger) end @@ -17,10 +18,16 @@ Facter::Resolvers::Virtualization.invalidate_cache end - let(:comp) do - [double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: vbox_version), - double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: vbox_revision)] + before do + allow(win32ole).to receive(:Model).and_return(model) + allow(win32ole).to receive(:Manufacturer).and_return(manufacturer) + allow(win32ole).to receive(:OEMStringArray).and_return(vbox_version) + allow(win32ole2).to receive(:Model).and_return(model) + allow(win32ole2).to receive(:Manufacturer).and_return(manufacturer) + allow(win32ole2).to receive(:OEMStringArray).and_return(vbox_revision) end + + let(:query_result) { [win32ole, win32ole2] } let(:model) { 'VirtualBox' } let(:manufacturer) {} let(:vbox_version) { 'vboxVer_6.0.4' } @@ -31,7 +38,7 @@ end it 'detects that is virtual' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('true') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(true) end it 'detects oem_strings facts' do @@ -44,7 +51,13 @@ Facter::Resolvers::Virtualization.invalidate_cache end - let(:comp) { [double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: '')] } + before do + allow(win32ole).to receive(:Model).and_return(model) + allow(win32ole).to receive(:Manufacturer).and_return(manufacturer) + allow(win32ole).to receive(:OEMStringArray).and_return('') + end + + let(:query_result) { [win32ole] } let(:model) { 'VMware' } let(:manufacturer) {} @@ -53,7 +66,7 @@ end it 'detects that is virtual' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('true') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(true) end end @@ -62,7 +75,13 @@ Facter::Resolvers::Virtualization.invalidate_cache end - let(:comp) { [double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: '')] } + before do + allow(win32ole).to receive(:Model).and_return(model) + allow(win32ole).to receive(:Manufacturer).and_return(manufacturer) + allow(win32ole).to receive(:OEMStringArray).and_return('') + end + + let(:query_result) { [win32ole] } let(:model) { 'KVM10' } let(:manufacturer) {} @@ -71,7 +90,7 @@ end it 'detects that is virtual' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('true') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(true) end end @@ -80,7 +99,13 @@ Facter::Resolvers::Virtualization.invalidate_cache end - let(:comp) { [double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: '')] } + before do + allow(win32ole).to receive(:Model).and_return(model) + allow(win32ole).to receive(:Manufacturer).and_return(manufacturer) + allow(win32ole).to receive(:OEMStringArray).and_return('') + end + + let(:query_result) { [win32ole] } let(:model) { 'OpenStack' } let(:manufacturer) {} @@ -89,7 +114,7 @@ end it 'detects that is virtual' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('true') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(true) end end @@ -98,7 +123,13 @@ Facter::Resolvers::Virtualization.invalidate_cache end - let(:comp) { [double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: '')] } + before do + allow(win32ole).to receive(:Model).and_return(model) + allow(win32ole).to receive(:Manufacturer).and_return(manufacturer) + allow(win32ole).to receive(:OEMStringArray).and_return('') + end + + let(:query_result) { [win32ole] } let(:model) { 'Virtual Machine' } let(:manufacturer) { 'Microsoft' } @@ -107,7 +138,7 @@ end it 'detects that is virtual' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('true') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(true) end end @@ -116,7 +147,13 @@ Facter::Resolvers::Virtualization.invalidate_cache end - let(:comp) { [double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: '')] } + before do + allow(win32ole).to receive(:Model).and_return(model) + allow(win32ole).to receive(:Manufacturer).and_return(manufacturer) + allow(win32ole).to receive(:OEMStringArray).and_return('') + end + + let(:query_result) { [win32ole] } let(:model) { '' } let(:manufacturer) { 'Xen' } @@ -125,7 +162,7 @@ end it 'detects that is virtual' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('true') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(true) end end @@ -134,7 +171,13 @@ Facter::Resolvers::Virtualization.invalidate_cache end - let(:comp) { [double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: '')] } + before do + allow(win32ole).to receive(:Model).and_return(model) + allow(win32ole).to receive(:Manufacturer).and_return(manufacturer) + allow(win32ole).to receive(:OEMStringArray).and_return('') + end + + let(:query_result) { [win32ole] } let(:model) { '' } let(:manufacturer) { 'Amazon EC2' } @@ -143,12 +186,18 @@ end it 'detects that is virtual' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('true') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(true) end end describe '#resolve Physical Machine' do - let(:comp) { [double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: '')] } + before do + allow(win32ole).to receive(:Model).and_return(model) + allow(win32ole).to receive(:Manufacturer).and_return(manufacturer) + allow(win32ole).to receive(:OEMStringArray).and_return('') + end + + let(:query_result) { [win32ole] } let(:model) { '' } let(:manufacturer) { '' } @@ -157,21 +206,19 @@ end it 'detects that is not virtual' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('false') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(false) end end describe '#resolve should cache facts in the same run' do - let(:comp) { [double('WIN32OLE', Model: model, Manufacturer: manufacturer, OEMStringArray: '')] } - let(:model) { '' } - let(:manufacturer) { 'Amazon EC2' } + let(:query_result) { nil } it 'detects virtual machine model' do expect(Facter::Resolvers::Virtualization.resolve(:virtual)).to eql('physical') end it 'detects that is virtual' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('false') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(false) end end @@ -180,7 +227,7 @@ Facter::Resolvers::Virtualization.invalidate_cache end - let(:comp) { nil } + let(:query_result) { nil } it 'logs that query failed and virtual nil' do allow(logger).to receive(:debug) @@ -197,16 +244,19 @@ describe '#resolve when WMI query returns nil for Model and Manufacturer' do before do Facter::Resolvers::Virtualization.invalidate_cache + allow(win32ole).to receive(:Model).and_return(nil) + allow(win32ole).to receive(:Manufacturer).and_return(nil) + allow(win32ole).to receive(:OEMStringArray).and_return('') end - let(:comp) { [double('WIN32OLE', Model: nil, Manufacturer: nil, OEMStringArray: '')] } + let(:query_result) { [win32ole] } it 'detects that is physical' do expect(Facter::Resolvers::Virtualization.resolve(:virtual)).to eql('physical') end it 'detects that is_virtual is false' do - expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to eql('false') + expect(Facter::Resolvers::Virtualization.resolve(:is_virtual)).to be(false) end end end diff --git a/spec/framework/formatters/yaml_fact_formatter_spec.rb b/spec/framework/formatters/yaml_fact_formatter_spec.rb index 556a81135..3062a1dd3 100644 --- a/spec/framework/formatters/yaml_fact_formatter_spec.rb +++ b/spec/framework/formatters/yaml_fact_formatter_spec.rb @@ -21,7 +21,7 @@ context 'when no user query' do let(:resolved_fact_list) { [resolved_fact1, resolved_fact2, resolved_fact3] } - let(:expected_output) { "os:\n architecture: x86_64\n family: Darwin\n name: Darwin\n" } + let(:expected_output) { "os:\n architecture: x86_64\n family: \"Darwin\"\n name: \"Darwin\"\n" } it 'formats to yaml' do expect(yaml_formatter.format(resolved_fact_list)).to eq(expected_output) @@ -30,7 +30,7 @@ context 'when there is a single user query' do let(:resolved_fact_list) { [resolved_fact1] } - let(:expected_output) { "os.name: Darwin\n" } + let(:expected_output) { "os.name: \"Darwin\"\n" } let(:user_query1) { 'os.name' } it 'formats to yaml' do @@ -40,7 +40,7 @@ context 'when there are multiple user queries' do let(:resolved_fact_list) { [resolved_fact1, resolved_fact2] } - let(:expected_output) { "os.family: Darwin\nos.name: Darwin\n" } + let(:expected_output) { "os.family: \"Darwin\"\nos.name: \"Darwin\"\n" } let(:user_query1) { 'os.name' } let(:user_query2) { 'os.family' } @@ -55,10 +55,10 @@ user_query: '', filter_tokens: [], type: :core) end let(:value) { 'C:\\Program Files\\Puppet Labs\\Puppet\\bin;C:\\cygwin64\\bin' } - let(:expected_output) { "path: C:\\\\Program Files\\\\Puppet Labs\\\\Puppet\\\\bin;C:\\\\cygwin64\\\\bin\n" } + let(:expected_output) { "path: \"C:\\\\Program Files\\\\Puppet Labs\\\\Puppet\\\\bin;C:\\\\cygwin64\\\\bin\"\n" } let(:resolved_fact_list) { [win_path] } - it 'formats path with double escaped backslashes' do + it 'formats quoted path with double escaped backslashes' do expect(yaml_formatter.format(resolved_fact_list)).to eq(expected_output) end end diff --git a/spec/mocks/win32ole_mock.rb b/spec/mocks/win32ole_mock.rb index 3d1019238..1e294cd63 100644 --- a/spec/mocks/win32ole_mock.rb +++ b/spec/mocks/win32ole_mock.rb @@ -8,4 +8,10 @@ def ConnectServer(*); end def Security_; end def ImpersonationLevel=; end + + def Model; end + + def Manufacturer; end + + def OEMStringArray; end end