Refactored lib/facter/manufacturer.rb and
lib/facter/util/manufacturer.rb to conform more closely to the general
facter style. Manufacturer facts were moved out of the utility class and
changed into independent fact blocks, and use confines instead of
if/else blocks to confine facts to specific operatingsystem.

In the manufacturer utility module, removed unneeded utility methods,
simplified DMI querying to make it more general purpose, and cleaned up
the dmi table accessor. Refactored the accompanying unit tests and moved
raw test data into fixture files.

Signed-off-by: Adrien Thebo <[email protected]>
---
Local-branch: ticket/master/7142
 lib/facter/manufacturer.rb          |  100 ++++++++++++++------
 lib/facter/util/manufacturer.rb     |  115 ++++------------------
 spec/unit/data/dmi_match_section    |   28 ++++++
 spec/unit/data/dmi_split_handle     |   12 +++
 spec/unit/manufacturer_spec.rb      |   44 +++++++++
 spec/unit/util/manufacturer_spec.rb |  180 +++++++++++------------------------
 6 files changed, 230 insertions(+), 249 deletions(-)
 create mode 100644 spec/unit/data/dmi_match_section
 create mode 100644 spec/unit/data/dmi_split_handle
 create mode 100644 spec/unit/manufacturer_spec.rb

diff --git a/lib/facter/manufacturer.rb b/lib/facter/manufacturer.rb
index 26aef5f..769c0e1 100644
--- a/lib/facter/manufacturer.rb
+++ b/lib/facter/manufacturer.rb
@@ -18,35 +18,75 @@
 
 require 'facter/util/manufacturer'
 
-if Facter.value(:kernel) == "OpenBSD"
-    mfg_keys = {
-        'hw.vendor'   => 'manufacturer',
-        'hw.product'  => 'productname',
-        'hw.serialno' => 'serialnumber'
-    }
-
-    Facter::Manufacturer.sysctl_find_system_info(mfg_keys)
-elsif Facter.value(:kernel) == "SunOS" and Facter.value(:hardwareisa) == 
"sparc"
-    Facter::Manufacturer.prtdiag_sparc_find_system_info()
-elsif Facter.value(:kernel) == "windows"
-    win32_keys = {
-        'manufacturer' => ['Manufacturer', 'Bios'],
-        'serialNumber' => ['Serialnumber', 'Bios'],
-        'productname'  => ['Name', 'ComputerSystemProduct']
-    }
-    Facter::Manufacturer.win32_find_system_info(win32_keys)
-else
-    query = {
-        '[Ss]ystem [Ii]nformation' => [
-            { 'Manufacturer:'      => 'manufacturer' },
-            { 'Product(?: Name)?:' => 'productname' },
-            { 'Serial Number:'     => 'serialnumber' }
-        ],
-        '(Chassis Information|system enclosure or chassis)' => [
-            { '(?:Chassis )?Type:' => 'type' }
-        ]
-    }
-
-    Facter::Manufacturer.dmi_find_system_info(query)
+{
+  'manufacturer'  => 'hw.vendor',
+  'productname'   => 'hw.product',
+  'serialnumber'  => 'hw.serialno',
+}.each do | fact, sysctl |
+  Facter.add(fact) do
+    confine :kernel => :openbsd
+    setcode do
+      Facter::Util::Resolution.exec("sysctl -n " + sysctl)
+    end
+  end
 end
 
+
+{
+  'manufacturer' => ['Manufacturer', 'Bios'],
+  'serialnumber' => ['Serialnumber', 'Bios'],
+  'productname'  => ['Name', 'ComputerSystemProduct']
+}.each do | fact, win32key |
+  Facter.add(fact) do
+    confine :kernel  => "windows"
+
+    setcode do
+      require 'win32ole'
+
+      value = ""
+      wmi = WIN32OLE.connect("winmgmts://")
+      query = wmi.ExecQuery("select * from Win32_#{win32key.last}")
+      query.each { |x| value = x.__send__( (win32key.first).to_sym) }
+    end
+  end
+end
+
+
+{
+  'manufacturer'  => /^System Configuration:\s+(.+?)\s+sun\d+\S+/,
+  'productname'   => /^System Configuration:.+\s+sun\d+\S+\s+(.+)/,
+}.each do | fact, regex |
+  Facter.add(fact) do
+    confine :kernel => "SunOS"
+    confine :hardwareisa => "sparc"
+
+    setcode do
+      # Parses prtdiag for a SPARC architecture string, won't work with 
Solaris x86
+      output = Facter::Util::Resolution.exec('/usr/sbin/prtdiag')
+
+      if output and regex.match(output)
+        $1
+      end
+    end
+  end
+end
+
+{
+  'manufacturer' => 'Manufacturer:',
+  'productname'  => 'Product(?: Name)?:',
+  'serialnumber' => 'Serial Number:',
+}.each do | fact, key |
+  Facter.add(fact) do
+    confine :kernel => [ :linux, :freebsd, :netbsd, :sunos, :"gnu/kfreebsd" ]
+    setcode do
+      Facter::Util::Manufacturer.query_dmi '[Ss]ystem [Ii]nformation', key
+    end
+  end
+end
+
+Facter.add("type") do
+  confine :kernel => [ :linux, :freebsd, :netbsd, :sunos, :"gnu/kfreebsd" ]
+  setcode do
+    Facter::Util::Manufacturer.query_dmi '(Chassis Information|system 
enclosure or chassis)', '(?:Chassis )?Type:'
+  end
+end
diff --git a/lib/facter/util/manufacturer.rb b/lib/facter/util/manufacturer.rb
index 8e9bde2..f6e1657 100644
--- a/lib/facter/util/manufacturer.rb
+++ b/lib/facter/util/manufacturer.rb
@@ -1,100 +1,29 @@
 # mamufacturer.rb
 # Support methods for manufacturer specific facts
 
-module Facter::Manufacturer
-
-    def self.get_dmi_table()
-        case Facter.value(:kernel)
-        when 'Linux', 'GNU/kFreeBSD'
-            return nil unless FileTest.exists?("/usr/sbin/dmidecode")
-
-            output=%x{/usr/sbin/dmidecode 2>/dev/null}
-        when 'FreeBSD'
-            return nil unless FileTest.exists?("/usr/local/sbin/dmidecode")
-
-            output=%x{/usr/local/sbin/dmidecode 2>/dev/null}
-        when 'NetBSD'
-            return nil unless FileTest.exists?("/usr/pkg/sbin/dmidecode")
-
-            output=%x{/usr/pkg/sbin/dmidecode 2>/dev/null}
-        when 'SunOS'
-            return nil unless FileTest.exists?("/usr/sbin/smbios")
-
-            output=%x{/usr/sbin/smbios 2>/dev/null}
-        else
-            output=nil
-        end
-        return output
-    end
-
-    def self.dmi_find_system_info(name)
-        splitstr=  Facter.value(:kernel) ==  'SunOS' ? "ID    SIZE TYPE" : 
/^Handle/
-        output = self.get_dmi_table()
-        return if output.nil?
-        name.each_pair do |key,v|
-            v.each do |v2|
-                v2.each_pair do |value,facterkey|
-                    output.split(splitstr).each do |line|
-                        if line =~ /#{key}/ and line =~ /\n\s+#{value} (.+)\n/
-                            result = $1.strip
-                            Facter.add(facterkey) do
-                                confine :kernel => [ :linux, :freebsd, 
:netbsd, :sunos, :"gnu/kfreebsd" ]
-                                setcode do
-                                    result
-                                end
-                            end
-                        end
-                    end
-                end
-            end
-        end
+module Facter::Util::Manufacturer
+
+  def self.get_dmi_table()
+    executable = case Facter.value(:kernel)
+    when 'Linux', 'GNU/kFreeBSD' then "/usr/sbin/dmidecode"
+    when 'FreeBSD' then "/usr/local/sbin/dmidecode"
+    when 'NetBSD' then "/usr/pkg/sbin/dmidecode"
+    when 'SunOS' then "/usr/sbin/smbios"
     end
 
-    def self.sysctl_find_system_info(name)
-        name.each do |sysctlkey,facterkey|
-            Facter.add(facterkey) do
-                confine :kernel => :openbsd
-                setcode do
-                    Facter::Util::Resolution.exec("sysctl -n " + sysctlkey)
-                end
-            end
-        end
+    Facter::Util::Resolution.exec("#{executable} 2>/dev/null") unless 
executable.nil?
+  end
+
+  # Utility method to query the system DMI and return the value of a specific
+  # record entry.
+  def self.query_dmi(header, key)
+    splitstr = Facter.value(:kernel) ==  'SunOS' ? "ID    SIZE TYPE" : 
/^Handle/
+    output = self.get_dmi_table
+    if output
+      line = output.split(splitstr).select {|section| section =~ /#{header}/ 
}.first
+      if line =~ /\n\s+#{key} (.+)\n/
+        $1.strip
+      end
     end
-
-    def self.prtdiag_sparc_find_system_info()
-        # Parses prtdiag for a SPARC architecture string, won't work with 
Solaris x86
-        output = Facter::Util::Resolution.exec('/usr/sbin/prtdiag')
-
-        # System Configuration:  Sun Microsystems  sun4u Sun SPARC Enterprise 
M3000 Server
-        sysconfig = output.split("\n")[0]
-        if sysconfig =~ /^System Configuration:\s+(.+?)\s+(sun\d+\S+)\s+(.+)/ 
then
-            Facter.add('manufacturer') do
-                setcode do
-                    $1
-                end
-            end
-            Facter.add('productname') do
-                setcode do
-                    $3
-                end
-            end
-        end
-    end
-
-    def self.win32_find_system_info(name)
-        require 'win32ole'
-        value = ""
-        wmi = WIN32OLE.connect("winmgmts://")
-        name.each do |facterkey, win32key|
-            query = wmi.ExecQuery("select * from Win32_#{win32key.last}")
-            Facter.add(facterkey) do
-                confine :kernel => :windows
-                setcode do
-                    query.each { |x| value = x.__send__( 
(win32key.first).to_sym) }
-                    value
-                end
-            end
-        end
-    end
-
+  end
 end
diff --git a/spec/unit/data/dmi_match_section b/spec/unit/data/dmi_match_section
new file mode 100644
index 0000000..a355145
--- /dev/null
+++ b/spec/unit/data/dmi_match_section
@@ -0,0 +1,28 @@
+Handle 0x000C, DMI type 7, 19 bytes
+Cache Information
+        Socket Designation: Internal L2 Cache
+        Configuration: Enabled, Socketed, Level 2
+        Operational Mode: Write Back
+        Location: Internal
+        Installed Size: 4096 KB
+        Maximum Size: 4096 KB
+        Supported SRAM Types:
+                Burst
+        Installed SRAM Type: Burst
+        Speed: Unknown
+        Error Correction Type: Single-bit ECC
+        System Type: Unified
+        Associativity: 8-way Set-associative
+
+Handle 0x1000, DMI type 16, 15 bytes
+Physical Memory Array
+        Location: System Board Or Motherboard
+        Use: System Memory
+        Error Correction Type: None
+        Maximum Capacity: 4 GB
+        Error Information Handle: Not Provided
+        Number Of Devices: 2
+
+Handle 0x001F
+        DMI type 127, 4 bytes.
+        End Of Table
diff --git a/spec/unit/data/dmi_split_handle b/spec/unit/data/dmi_split_handle
new file mode 100644
index 0000000..68d73b9
--- /dev/null
+++ b/spec/unit/data/dmi_split_handle
@@ -0,0 +1,12 @@
+Handle 0x1000, DMI type 16, 15 bytes
+Physical Memory Array
+        Location: System Board Or Motherboard
+        Use: System Memory
+        Error Correction Type: None
+        Maximum Capacity: 4 GB
+        Error Information Handle: Not Provided
+        Number Of Devices: 123
+
+Handle 0x001F
+        DMI type 127, 4 bytes.
+        End Of Table
diff --git a/spec/unit/manufacturer_spec.rb b/spec/unit/manufacturer_spec.rb
new file mode 100644
index 0000000..ebcdd97
--- /dev/null
+++ b/spec/unit/manufacturer_spec.rb
@@ -0,0 +1,44 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe 'Manufacturer facts' do
+  before :each do
+    Facter.collection.loader.load(:manufacturer)
+  end
+
+  describe "on Solaris" do
+    before :each do
+      Facter.fact(:kernel).stubs(:value).returns("SunOS")
+      Facter.fact(:hardwareisa).stubs(:value).returns("sparc")
+    end
+
+    it "should use prtdiag to get the manufacturer" do
+      
Facter::Util::Resolution.expects(:exec).with("/usr/sbin/prtdiag").returns("System
 Configuration:  Sun Microsystems  sun4u Sun SPARC Enterprise M3000 Server")
+      Facter.value(:manufacturer).should == "Sun Microsystems"
+    end
+
+    it "should use prtdiag to get the productname" do
+      
Facter::Util::Resolution.expects(:exec).with("/usr/sbin/prtdiag").returns("System
 Configuration:  Sun Microsystems  sun4u Sun SPARC Enterprise M3000 Server")
+      Facter.value(:productname).should == "Sun SPARC Enterprise M3000 Server"
+    end
+  end
+  describe "on OpenBSD" do
+    before :each do
+      Facter.fact(:kernel).stubs(:value).returns("OpenBSD")
+    end
+
+    it "should use sysctl to get the manufacturer" do
+      Facter::Util::Resolution.expects(:exec).with("sysctl -n 
hw.vendor").returns("innotek GmbH")
+      Facter.value(:manufacturer).should == "innotek GmbH"
+    end
+
+    it "should use sysctl to get the serial number" do
+      Facter::Util::Resolution.expects(:exec).with("sysctl -n 
hw.serialno").returns("0")
+      Facter.value(:serialnumber).should == "0"
+    end
+
+    it "should use sysctl to get the product name" do
+      Facter::Util::Resolution.expects(:exec).with("sysctl -n 
hw.product").returns("VirtualBox")
+      Facter.value(:productname).should == "VirtualBox"
+    end
+  end
+end
diff --git a/spec/unit/util/manufacturer_spec.rb 
b/spec/unit/util/manufacturer_spec.rb
index c3b372e..2cae773 100644
--- a/spec/unit/util/manufacturer_spec.rb
+++ b/spec/unit/util/manufacturer_spec.rb
@@ -2,131 +2,59 @@ require File.expand_path(File.dirname(__FILE__) + 
'/../../spec_helper')
 
 require 'facter/util/manufacturer'
 
-describe Facter::Manufacturer do
-    before :each do
-        Facter.clear
-    end
-
-    it "should return the system DMI table" do
-        Facter::Manufacturer.should respond_to(:get_dmi_table)
-    end
-
-    it "should return nil on non-supported operating systems" do
-        Facter.stubs(:value).with(:kernel).returns("SomeThing")
-        Facter::Manufacturer.get_dmi_table().should be_nil
-    end
-
-    it "should parse prtdiag output" do
-        Facter::Util::Resolution.stubs(:exec).returns("System Configuration:  
Sun Microsystems  sun4u Sun SPARC Enterprise M3000 Server")
-        Facter::Manufacturer.prtdiag_sparc_find_system_info()
-        Facter.value(:manufacturer).should == "Sun Microsystems"
-        Facter.value(:productname).should == "Sun SPARC Enterprise M3000 
Server"
-    end
-
-    it "should strip white space on dmi output with spaces" do
-        sample_output_file = File.dirname(__FILE__) + 
"/../data/linux_dmidecode_with_spaces"
-        dmidecode_output = File.new(sample_output_file).read()
-        Facter::Manufacturer.expects(:get_dmi_table).returns(dmidecode_output)
-        Facter.fact(:kernel).stubs(:value).returns("Linux")
-
-        query = { '[Ss]ystem [Ii]nformation' => [ { 'Product(?: Name)?:' => 
'productname' } ] }
-
-        Facter::Manufacturer.dmi_find_system_info(query)
-        Facter.value(:productname).should == "MS-6754"
-    end
-
-    it "should handle output from smbios when run under sunos" do
-        sample_output_file = File.dirname(__FILE__) + 
"/../data/opensolaris_smbios"
-        smbios_output = File.new(sample_output_file).read()
-        Facter::Manufacturer.expects(:get_dmi_table).returns(smbios_output)
-        Facter.fact(:kernel).stubs(:value).returns("SunOS")
-
-        query = { 'BIOS information' => [ { 'Release Date:' => 'reldate' } ] }
-
-        Facter::Manufacturer.dmi_find_system_info(query)
-        Facter.value(:reldate).should == "12/01/2006"
-    end
-
-    it "should not split on dmi keys containing the string Handle" do
-        dmidecode_output = <<-eos
-Handle 0x1000, DMI type 16, 15 bytes
-Physical Memory Array
-        Location: System Board Or Motherboard
-        Use: System Memory
-        Error Correction Type: None
-        Maximum Capacity: 4 GB
-        Error Information Handle: Not Provided
-        Number Of Devices: 123
-
-Handle 0x001F
-        DMI type 127, 4 bytes.
-        End Of Table
-        eos
-        Facter::Manufacturer.expects(:get_dmi_table).returns(dmidecode_output)
-        Facter.fact(:kernel).stubs(:value).returns("Linux")
-        query = { 'Physical Memory Array' => [ { 'Number Of Devices:' => 
'ramslots'}]}
-        Facter::Manufacturer.dmi_find_system_info(query)
-        Facter.value(:ramslots).should == "123"
-    end
-
-    it "should match the key in the defined section and not the first one 
found" do
-        dmidecode_output = <<-eos
-Handle 0x000C, DMI type 7, 19 bytes
-Cache Information
-        Socket Designation: Internal L2 Cache
-        Configuration: Enabled, Socketed, Level 2
-        Operational Mode: Write Back
-        Location: Internal
-        Installed Size: 4096 KB
-        Maximum Size: 4096 KB
-        Supported SRAM Types:
-                Burst
-        Installed SRAM Type: Burst
-        Speed: Unknown
-        Error Correction Type: Single-bit ECC
-        System Type: Unified
-        Associativity: 8-way Set-associative
-
-Handle 0x1000, DMI type 16, 15 bytes
-Physical Memory Array
-        Location: System Board Or Motherboard
-        Use: System Memory
-        Error Correction Type: None
-        Maximum Capacity: 4 GB
-        Error Information Handle: Not Provided
-        Number Of Devices: 2
-
-Handle 0x001F
-        DMI type 127, 4 bytes.
-        End Of Table
-        eos
-        Facter::Manufacturer.expects(:get_dmi_table).returns(dmidecode_output)
-        Facter.fact(:kernel).stubs(:value).returns("Linux")
-        query = { 'Physical Memory Array' => [ { 'Location:' => 
'ramlocation'}]}
-        Facter::Manufacturer.dmi_find_system_info(query)
-        Facter.value(:ramlocation).should == "System Board Or Motherboard"
-    end
-
-    def find_product_name(os)
-        output_file = case os
-            when "FreeBSD" then File.dirname(__FILE__) + 
"/../data/freebsd_dmidecode"
-            when "SunOS" then File.dirname(__FILE__) + 
"/../data/opensolaris_smbios"
-            end
-
-        output = File.new(output_file).read()
-        query = { '[Ss]ystem [Ii]nformation' => [ { 'Product(?: Name)?:' => 
"product_name_#{os}" } ] }
-
-        Facter.fact(:kernel).stubs(:value).returns(os)
-        Facter::Manufacturer.expects(:get_dmi_table).returns(output)
-
-        Facter::Manufacturer.dmi_find_system_info(query)
-
-        return Facter.value("product_name_#{os}")
-    end
-
-    it "should return the same result with smbios than with dmidecode" do
-        find_product_name("FreeBSD").should_not == nil
-        find_product_name("FreeBSD").should == find_product_name("SunOS")
-    end
+def fixture_data(fixture_name)
+  fixture_path = File.join(SPECDIR, 'unit', 'data')
+  File.read(File.join(fixture_path, fixture_name))
+end
 
+describe Facter::Util::Manufacturer do
+
+  it "should return the system DMI table" do
+    Facter::Util::Manufacturer.should respond_to(:get_dmi_table)
+  end
+
+  it "should return nil on non-supported operating systems" do
+    Facter.stubs(:value).with(:kernel).returns("SomeThing")
+    Facter::Util::Manufacturer.get_dmi_table().should be_nil
+  end
+
+  it "should strip white space on dmi output with spaces" do
+    Facter.fact(:kernel).stubs(:value).returns("Linux")
+    
Facter::Util::Manufacturer.expects(:get_dmi_table).returns(fixture_data('linux_dmidecode_with_spaces'))
+    Facter::Util::Manufacturer.query_dmi('[Ss]ystem 
[Ii]nformation','Product(?: Name)?:').should == "MS-6754"
+  end
+
+  it "should handle output from smbios when run under sunos" do
+    Facter.fact(:kernel).stubs(:value).returns("SunOS")
+    Facter::Util::Resolution.expects(:exec).with("/usr/sbin/smbios 
2>/dev/null").returns(fixture_data("opensolaris_smbios"))
+    Facter::Util::Manufacturer.query_dmi('BIOS information','Release 
Date:').should == "12/01/2006"
+  end
+
+  it "should not split on dmi keys containing the string Handle" do
+    Facter.fact(:kernel).stubs(:value).returns("Linux")
+    
Facter::Util::Manufacturer.expects(:get_dmi_table).returns(fixture_data('dmi_split_handle'))
+    Facter::Util::Manufacturer.query_dmi('Physical Memory Array', 'Number Of 
Devices:').should == "123"
+  end
+
+  it "should match the key in the defined section and not the first one found" 
do
+    Facter.fact(:kernel).stubs(:value).returns("Linux")
+    
Facter::Util::Manufacturer.expects(:get_dmi_table).returns(fixture_data("dmi_match_section"))
+    Facter::Util::Manufacturer.query_dmi('Physical Memory Array', 
'Location:').should == "System Board Or Motherboard"
+  end
+
+  def find_product_name(os)
+    output = case os
+    when "FreeBSD" then fixture_data("freebsd_dmidecode")
+    when "SunOS" then fixture_data("opensolaris_smbios")
+    end
+
+    Facter.fact(:kernel).stubs(:value).returns(os)
+    Facter::Util::Manufacturer.expects(:get_dmi_table).returns(output)
+    Facter::Util::Manufacturer.query_dmi('[Ss]ystem [Ii]nformation', 
'Product(?: Name)?:')
+  end
+
+  it "should return the same result with smbios than with dmidecode" do
+    find_product_name("FreeBSD").should_not == nil
+    find_product_name("FreeBSD").should == find_product_name("SunOS")
+  end
 end
-- 
1.7.4.1

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to