summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Rakefile32
-rw-r--r--lib/facter/operatingsystem.rb2
-rw-r--r--lib/facter/operatingsystemrelease.rb4
-rw-r--r--lib/facter/uptime.rb31
-rw-r--r--lib/facter/uptime_days.rb7
-rw-r--r--lib/facter/uptime_hours.rb7
-rw-r--r--lib/facter/uptime_seconds.rb10
-rw-r--r--lib/facter/util/manufacturer.rb2
-rw-r--r--lib/facter/util/uptime.rb65
-rw-r--r--spec/fixtures/uptime/sysctl_kern_boottimebin0 -> 16 bytes
-rw-r--r--spec/fixtures/uptime/ubuntu_proc_uptime1
-rw-r--r--spec/fixtures/uptime/who_b_boottime1
-rw-r--r--spec/spec_helper.rb2
-rw-r--r--spec/unit/data/freebsd_dmidecode42
-rw-r--r--spec/unit/data/opensolaris_smbios33
-rw-r--r--spec/unit/uptime.rb112
-rw-r--r--spec/unit/util/manufacturer.rb35
-rw-r--r--spec/unit/util/uptime.rb53
18 files changed, 384 insertions, 55 deletions
diff --git a/Rakefile b/Rakefile
index 67d4c90..51b4d13 100644
--- a/Rakefile
+++ b/Rakefile
@@ -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
new file mode 100644
index 0000000..0c54fe4
--- /dev/null
+++ b/spec/fixtures/uptime/sysctl_kern_boottime
Binary files differ
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