diff options
-rw-r--r-- | Rakefile | 32 | ||||
-rw-r--r-- | lib/facter/operatingsystem.rb | 2 | ||||
-rw-r--r-- | lib/facter/operatingsystemrelease.rb | 4 | ||||
-rw-r--r-- | lib/facter/uptime.rb | 31 | ||||
-rw-r--r-- | lib/facter/uptime_days.rb | 7 | ||||
-rw-r--r-- | lib/facter/uptime_hours.rb | 7 | ||||
-rw-r--r-- | lib/facter/uptime_seconds.rb | 10 | ||||
-rw-r--r-- | lib/facter/util/manufacturer.rb | 2 | ||||
-rw-r--r-- | lib/facter/util/uptime.rb | 65 | ||||
-rw-r--r-- | spec/fixtures/uptime/sysctl_kern_boottime | bin | 0 -> 16 bytes | |||
-rw-r--r-- | spec/fixtures/uptime/ubuntu_proc_uptime | 1 | ||||
-rw-r--r-- | spec/fixtures/uptime/who_b_boottime | 1 | ||||
-rw-r--r-- | spec/spec_helper.rb | 2 | ||||
-rw-r--r-- | spec/unit/data/freebsd_dmidecode | 42 | ||||
-rw-r--r-- | spec/unit/data/opensolaris_smbios | 33 | ||||
-rw-r--r-- | spec/unit/uptime.rb | 112 | ||||
-rw-r--r-- | spec/unit/util/manufacturer.rb | 35 | ||||
-rw-r--r-- | spec/unit/util/uptime.rb | 53 |
18 files changed, 384 insertions, 55 deletions
@@ -3,6 +3,13 @@ $: << File.expand_path('lib') $LOAD_PATH << File.join(File.dirname(__FILE__), 'tasks') +require 'spec' +require 'spec/rake/spectask' +begin + require 'rcov' +rescue LoadError +end + Dir['tasks/**/*.rake'].each { |t| load t } require 'facter.rb' @@ -51,21 +58,14 @@ task :default do sh %{rake -T} end -desc "Run the specs under spec/" -task :spec do - require 'spec' - require 'spec/rake/spectask' - begin - require 'rcov' - rescue LoadError - end +Spec::Rake::SpecTask.new(:spec) do |t| + t.spec_files = FileList['spec/**/*.rb'] +end - Spec::Rake::SpecTask.new do |t| - t.spec_opts = ['--format','s', '--loadby','mtime'] - t.spec_files = FileList['spec/**/*.rb'] - if defined?(Rcov) - t.rcov = true - t.rcov_opts = ['--exclude', 'spec/*,test/*,results/*,/usr/lib/*,/usr/local/lib/*'] - end - end +Spec::Rake::SpecTask.new('spec:rcov') do |t| + t.spec_files = FileList['spec/**/*.rb'] + if defined?(Rcov) + t.rcov = true + t.rcov_opts = ['--exclude', 'spec/*,test/*,results/*,/usr/lib/*,/usr/local/lib/*,gems/*'] + end end diff --git a/lib/facter/operatingsystem.rb b/lib/facter/operatingsystem.rb index d909fba..c5a3dc1 100644 --- a/lib/facter/operatingsystem.rb +++ b/lib/facter/operatingsystem.rb @@ -20,6 +20,8 @@ Facter.add(:operatingsystem) do "Mandriva" elsif FileTest.exists?("/etc/mandrake-release") "Mandrake" + elsif FileTest.exists?("/etc/meego-release") + "MeeGo" elsif FileTest.exists?("/etc/arch-release") "Archlinux" elsif FileTest.exists?("/etc/enterprise-release") diff --git a/lib/facter/operatingsystemrelease.rb b/lib/facter/operatingsystemrelease.rb index 91f40a7..30f2989 100644 --- a/lib/facter/operatingsystemrelease.rb +++ b/lib/facter/operatingsystemrelease.rb @@ -1,11 +1,13 @@ Facter.add(:operatingsystemrelease) do - confine :operatingsystem => %w{CentOS Fedora oel ovs RedHat} + confine :operatingsystem => %w{CentOS Fedora oel ovs RedHat MeeGo} setcode do case Facter.value(:operatingsystem) when "CentOS", "RedHat" releasefile = "/etc/redhat-release" when "Fedora" releasefile = "/etc/fedora-release" + when "MeeGo" + releasefile = "/etc/meego-release" when "OEL" releasefile = "/etc/enterprise-release" when "OVS" diff --git a/lib/facter/uptime.rb b/lib/facter/uptime.rb index 3a3bc86..56a959b 100644 --- a/lib/facter/uptime.rb +++ b/lib/facter/uptime.rb @@ -1,20 +1,23 @@ require 'facter/util/uptime' Facter.add(:uptime) do - confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE SLES Debian Ubuntu Gentoo AIX} - setcode do - Facter::Util::Uptime.get_uptime_simple - end -end + setcode do + seconds = Facter.fact(:uptime_seconds).value -if FileTest.exists?("/proc/uptime") - uptime = Facter::Util::Uptime.get_uptime + unless seconds + "unknown" + else + days = seconds / (60 * 60 * 24) + hours = seconds / (60 * 60) % 24 + minutes = seconds / 60 % 60 - %w{days hours seconds}.each do |label| - Facter.add("uptime_" + label) do - setcode do - Facter::Util::Uptime.get_uptime_period(uptime, label) - end - end - end + case days + when 0 then "#{hours}:#{"%02d" % minutes} hours" + when 1 then '1 day' + else "#{days} days" + end + end + + end end + diff --git a/lib/facter/uptime_days.rb b/lib/facter/uptime_days.rb new file mode 100644 index 0000000..add305c --- /dev/null +++ b/lib/facter/uptime_days.rb @@ -0,0 +1,7 @@ +Facter.add(:uptime_days) do + setcode do + hours = Facter.value(:uptime_hours) + hours && hours / 24 # hours in day + end +end + diff --git a/lib/facter/uptime_hours.rb b/lib/facter/uptime_hours.rb new file mode 100644 index 0000000..ce691d2 --- /dev/null +++ b/lib/facter/uptime_hours.rb @@ -0,0 +1,7 @@ +Facter.add(:uptime_hours) do + setcode do + seconds = Facter.value(:uptime_seconds) + seconds && seconds / (60 * 60) # seconds in hour + end +end + diff --git a/lib/facter/uptime_seconds.rb b/lib/facter/uptime_seconds.rb new file mode 100644 index 0000000..14bb573 --- /dev/null +++ b/lib/facter/uptime_seconds.rb @@ -0,0 +1,10 @@ +require 'facter/util/uptime' + +Facter.add(:uptime_seconds) do + setcode { Facter::Util::Uptime.get_uptime_seconds_unix } +end + +Facter.add(:uptime_seconds) do + confine :kernel => :windows + setcode { Facter::Util::Uptime.get_uptime_seconds_win } +end diff --git a/lib/facter/util/manufacturer.rb b/lib/facter/util/manufacturer.rb index b781e12..112380b 100644 --- a/lib/facter/util/manufacturer.rb +++ b/lib/facter/util/manufacturer.rb @@ -35,7 +35,7 @@ module Facter::Manufacturer v.each do |v2| v2.each_pair do |value,facterkey| output.split(splitstr).each do |line| - if line =~ /#{key}/ and ( line =~ /#{value} 0x\d+ \(([-\w].*)\)\n*/ or line =~ /#{value} ([-\w].*)\n*/ ) + if line =~ /#{key}/ and line =~ /\n\s+#{value} (.+)\n/ result = $1.strip Facter.add(facterkey) do confine :kernel => [ :linux, :freebsd, :netbsd, :sunos ] diff --git a/lib/facter/util/uptime.rb b/lib/facter/util/uptime.rb index c1e339b..353ebf5 100644 --- a/lib/facter/util/uptime.rb +++ b/lib/facter/util/uptime.rb @@ -1,32 +1,51 @@ +require 'time' + # A module to gather uptime facts # module Facter::Util::Uptime - def self.get_uptime_simple - time = Facter::Util::Resolution.exec('uptime') - if time =~ /up\s*(\d+\s\w+)/ - $1 - elsif time =~ /up\s*(\d+:\d+)/ - $1 + " hours" - else - "unknown" + def self.get_uptime_seconds_unix + uptime_proc_uptime or uptime_sysctl or uptime_who_dash_b + end + + def self.get_uptime_seconds_win + require 'Win32API' + getTickCount = Win32API.new("kernel32", "GetTickCount", nil, 'L') + compute_uptime(Time.at(getTickCount.call() / 1000.0)) + end + + private + + def self.uptime_proc_uptime + if output = `/bin/cat #{uptime_file} 2>/dev/null` and $?.success? + output.chomp.split(" ").first.to_i + end + end + + def self.uptime_sysctl + if output = `#{uptime_sysctl_cmd} 2>/dev/null` and $?.success? + compute_uptime(Time.at(output.unpack('L').first)) + end + end + + def self.uptime_who_dash_b + if output = `#{uptime_who_cmd} 2>/dev/null` and $?.success? + compute_uptime(Time.parse(output)) end end - def self.get_uptime - r = IO.popen("/bin/cat /proc/uptime") - uptime, idletime = r.readline.split(" ") - r.close - uptime_seconds = uptime.to_i + def self.compute_uptime(time) + (Time.now - time).to_i + end + + def self.uptime_file + "/proc/uptime" + end + + def self.uptime_sysctl_cmd + 'sysctl -b kern.boottime' end - def self.get_uptime_period(seconds, label) - case label - when 'days' - value = seconds / 86400 - when 'hours' - value = seconds / 3600 - when 'seconds' - seconds - end + def self.uptime_who_cmd + 'who -b' end -end +end diff --git a/spec/fixtures/uptime/sysctl_kern_boottime b/spec/fixtures/uptime/sysctl_kern_boottime Binary files differnew file mode 100644 index 0000000..0c54fe4 --- /dev/null +++ b/spec/fixtures/uptime/sysctl_kern_boottime diff --git a/spec/fixtures/uptime/ubuntu_proc_uptime b/spec/fixtures/uptime/ubuntu_proc_uptime new file mode 100644 index 0000000..7e8ed74 --- /dev/null +++ b/spec/fixtures/uptime/ubuntu_proc_uptime @@ -0,0 +1 @@ +5097686.63 40756306.43 diff --git a/spec/fixtures/uptime/who_b_boottime b/spec/fixtures/uptime/who_b_boottime new file mode 100644 index 0000000..9b29dcd --- /dev/null +++ b/spec/fixtures/uptime/who_b_boottime @@ -0,0 +1 @@ +reboot ~ Aug 1 14:13 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 34992d7..c8bd547 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,7 @@ dir = File.expand_path(File.dirname(__FILE__)) +SPECDIR = dir + $LOAD_PATH.unshift("#{dir}/") $LOAD_PATH.unshift("#{dir}/../lib") diff --git a/spec/unit/data/freebsd_dmidecode b/spec/unit/data/freebsd_dmidecode new file mode 100644 index 0000000..d765942 --- /dev/null +++ b/spec/unit/data/freebsd_dmidecode @@ -0,0 +1,42 @@ +# dmidecode 2.10 +SMBIOS 2.5 present. +5 structures occupying 352 bytes. +Table at 0x000E1000. + +Handle 0x0000, DMI type 0, 20 bytes +BIOS Information + Vendor: innotek GmbH + Version: VirtualBox + Release Date: 12/01/2006 + Address: 0xE0000 + Runtime Size: 128 kB + ROM Size: 128 kB + Characteristics: + ISA is supported + PCI is supported + Boot from CD is supported + Selectable boot is supported + 8042 keyboard services are supported (int 9h) + CGA/mono video services are supported (int 10h) + ACPI is supported + +Handle 0x0001, DMI type 1, 27 bytes +System Information + Manufacturer: innotek GmbH + Product Name: VirtualBox + Version: 1.2 + Serial Number: 0 + UUID: 3BD58031-AE9E-4F06-8A57-941942861939 + Wake-up Type: Power Switch + SKU Number: Not Specified + Family: Virtual Machine + +Handle 0x0003, DMI type 126, 13 bytes +Inactive + +Handle 0x0002, DMI type 126, 7 bytes +Inactive + +Handle 0xFEFF, DMI type 127, 147 bytes +End Of Table + diff --git a/spec/unit/data/opensolaris_smbios b/spec/unit/data/opensolaris_smbios new file mode 100644 index 0000000..68f1004 --- /dev/null +++ b/spec/unit/data/opensolaris_smbios @@ -0,0 +1,33 @@ +ID SIZE TYPE +0 54 SMB_TYPE_BIOS (BIOS information) + + Vendor: innotek GmbH + Version String: VirtualBox + Release Date: 12/01/2006 + Address Segment: 0xe000 + ROM Size: 131072 bytes + Image Size: 131072 bytes + Characteristics: 0x48018090 + SMB_BIOSFL_ISA (ISA is supported) + SMB_BIOSFL_PCI (PCI is supported) + SMB_BIOSFL_CDBOOT (Boot from CD is supported) + SMB_BIOSFL_SELBOOT (Selectable Boot supported) + SMB_BIOSFL_I9_KBD (int 0x9 8042 keyboard svcs) + SMB_BIOSFL_I10_CGA (int 0x10 CGA svcs) + Characteristics Extension Byte 1: 0x1 + SMB_BIOSXB1_ACPI (ACPI is supported) + Characteristics Extension Byte 2: 0x0 + +ID SIZE TYPE +1 72 SMB_TYPE_SYSTEM (system information) + + Manufacturer: innotek GmbH + Product: VirtualBox + Version: 1.2 + Serial Number: 0 + + UUID: cf4bff06-0b33-4891-bda0-5ec17bea5511 + Wake-Up Event: 0x6 (power switch) + SKU Number: + Family: Virtual Machine + diff --git a/spec/unit/uptime.rb b/spec/unit/uptime.rb new file mode 100644 index 0000000..19a55fe --- /dev/null +++ b/spec/unit/uptime.rb @@ -0,0 +1,112 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../spec_helper' + +require 'facter' +require 'facter/util/uptime' + +describe "uptime facts:" do + before { Facter.clear } + after { Facter.clear } + + context "when uptime information is available" do + describe "uptime" do + test_cases = [ + [60 * 60 * 24 * 3, '3 days'], + [60 * 60 * 24 * 3 + 25, '3 days'], + [60 * 60 * 24 * 1, '1 day'], + [60 * 60 * 24 * 1 + 25, '1 day'], + [60 * (60 * 3 + 45), '3:45 hours'], + [60 * (60 * 3 + 4), '3:04 hours'], + [60 * 60, '1:00 hours'], + [60 * 35, '0:35 hours'] + ] + + test_cases.each do |seconds, expected| + it "should return #{expected.inspect} for #{seconds} seconds" do + Facter::Util::Uptime.stubs(:get_uptime_seconds_unix).returns(seconds) + Facter::Util::Uptime.stubs(:get_uptime_seconds_win).returns(seconds) + + Facter.fact(:uptime).value.should == expected + end + end + end + + end + + context "when uptime information is available" do + before do + Facter::Util::Uptime.stubs(:get_uptime_seconds_unix).returns(60 * 60 * 24 + 23) + Facter::Util::Uptime.stubs(:get_uptime_seconds_win).returns(60 * 60 * 24 + 23) + end + + describe "uptime_seconds" do + it "should return the uptime in seconds" do + Facter.fact(:uptime_seconds).value.should == 60 * 60 * 24 + 23 + end + end + + describe "uptime_hours" do + it "should return the uptime in hours" do + Facter.fact(:uptime_hours).value.should == 24 + end + end + + describe "uptime_days" do + it "should return the uptime in days" do + Facter.fact(:uptime_days).value.should == 1 + end + end + end + + context "when uptime information is not available" do + before do + Facter::Util::Uptime.stubs(:get_uptime_seconds_unix).returns(nil) + Facter::Util::Uptime.stubs(:get_uptime_seconds_win).returns(nil) + $stderr, @old = StringIO.new, $stderr + end + + after do + $stderr = @old + end + + describe "uptime" do + it "should return 'unknown'" do + Facter.fact(:uptime).value.should == "unknown" + end + end + + describe "uptime_seconds" do + it "should return nil" do + Facter.fact(:uptime_seconds).value.should == nil + end + + it "should not print a warn message to stderr" do + Facter.fact(:uptime_seconds).value + $stderr.string.should == "" + end + end + + describe "uptime_hours" do + it "should return nil" do + Facter.fact(:uptime_hours).value.should == nil + end + + it "should not print a warn message to stderr" do + Facter.fact(:uptime_hours).value + $stderr.string.should == "" + end + end + + describe "uptime_days" do + it "should return nil" do + Facter.fact(:uptime_days).value.should == nil + end + + it "should not print a warn message to stderr" do + Facter.fact(:uptime_days).value + $stderr.string.should == "" + end + end + end +end diff --git a/spec/unit/util/manufacturer.rb b/spec/unit/util/manufacturer.rb index 74660f7..c0d4b13 100644 --- a/spec/unit/util/manufacturer.rb +++ b/spec/unit/util/manufacturer.rb @@ -24,6 +24,18 @@ describe Facter::Manufacturer do 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 @@ -83,4 +95,27 @@ Handle 0x001F 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": File.dirname(__FILE__) + "/../data/freebsd_dmidecode" + when "SunOS" : 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 + end diff --git a/spec/unit/util/uptime.rb b/spec/unit/util/uptime.rb new file mode 100644 index 0000000..9ba6665 --- /dev/null +++ b/spec/unit/util/uptime.rb @@ -0,0 +1,53 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'facter/util/uptime' + +describe Facter::Util::Uptime do + + describe ".get_uptime_seconds_unix" do + context "when /proc/uptime is available" do + before do + uptime_file = File.join(SPECDIR, "fixtures", "uptime", "ubuntu_proc_uptime") + Facter::Util::Uptime.stubs(:uptime_file).returns(uptime_file) + end + + it "should return the uptime in seconds as an integer" do + Facter::Util::Uptime.get_uptime_seconds_unix.should == 5097686 + end + + end + + it "should use sysctl kern.boottime when /proc/uptime not available" do + nonexistent_file = '/non/existent/file' + File.exists?(nonexistent_file).should == false + Facter::Util::Uptime.stubs(:uptime_file).returns(nonexistent_file) + sysctl_output_file = File.join(SPECDIR, 'fixtures', 'uptime', 'sysctl_kern_boottime') # Aug 01 14:13:47 -0700 2010 + Facter::Util::Uptime.stubs(:uptime_sysctl_cmd).returns("cat #{sysctl_output_file}") + Time.stubs(:now).returns Time.parse("Aug 01 15:13:47 -0700 2010") # one hour later + Facter::Util::Uptime.get_uptime_seconds_unix.should == 60 * 60 + end + + it "should use who -b when neither /proc/uptime nor sysctl kern.boottime is available" do + nonexistent_file = '/non/existent/file' + File.exists?(nonexistent_file).should == false + Facter::Util::Uptime.stubs(:uptime_file).returns(nonexistent_file) + Facter::Util::Uptime.stubs(:uptime_sysctl_cmd).returns("cat #{nonexistent_file}") + who_b_output_file = File.join(SPECDIR, 'fixtures', 'uptime', 'who_b_boottime') # Aug 1 14:13 + Facter::Util::Uptime.stubs(:uptime_who_cmd).returns("cat #{who_b_output_file}") + Time.stubs(:now).returns Time.parse("Aug 01 15:13") # one hour later + Facter::Util::Uptime.get_uptime_seconds_unix.should == 60 * 60 + end + + it "should return nil when none of /proc/uptime, sysctl kern.boottime, or who -b is available" do + nonexistent_file = '/non/existent/file' + File.exists?(nonexistent_file).should == false + Facter::Util::Uptime.stubs(:uptime_file).returns(nonexistent_file) + Facter::Util::Uptime.stubs(:uptime_sysctl_cmd).returns("cat #{nonexistent_file}") + Facter::Util::Uptime.stubs(:uptime_who_cmd).returns("cat #{nonexistent_file}") + Facter::Util::Uptime.get_uptime_seconds_unix.should == nil + end + end + +end |