facter 1.5 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of facter might be problematic. Click here for more details.

Files changed (41) hide show
  1. data/CHANGELOG +51 -1
  2. data/Rakefile +10 -1
  3. data/conf/osx/PackageInfo.plist +36 -0
  4. data/conf/osx/createpackage.sh +167 -0
  5. data/conf/osx/preflight +11 -0
  6. data/conf/redhat/facter.spec +120 -0
  7. data/conf/solaris/pkginfo +7 -0
  8. data/documentation/custom.page +22 -0
  9. data/documentation/index.page +19 -0
  10. data/install.rb +227 -92
  11. data/lib/facter.rb +1 -1
  12. data/lib/facter/domain.rb +14 -0
  13. data/lib/facter/hardwaremodel.rb +8 -0
  14. data/lib/facter/ipaddress.rb +21 -2
  15. data/lib/facter/ipmess.rb +8 -37
  16. data/lib/facter/kernel.rb +7 -1
  17. data/lib/facter/kernelrelease.rb +16 -1
  18. data/lib/facter/kernelversion.rb +5 -0
  19. data/lib/facter/lsb.rb +1 -0
  20. data/lib/facter/macaddress.rb +15 -1
  21. data/lib/facter/operatingsystem.rb +6 -1
  22. data/lib/facter/operatingsystemrelease.rb +34 -7
  23. data/lib/facter/puppetversion.rb +1 -1
  24. data/lib/facter/util/ip.rb +37 -47
  25. data/lib/facter/util/manufacturer.rb +2 -2
  26. data/lib/facter/util/resolution.rb +13 -3
  27. data/lib/facter/virtual.rb +62 -0
  28. data/spec/Rakefile +18 -0
  29. data/spec/integration/facter.rb +27 -0
  30. data/spec/spec.opts +3 -0
  31. data/spec/spec_helper.rb +25 -0
  32. data/spec/unit/data/linux_ifconfig_all_with_single_interface +18 -0
  33. data/spec/unit/data/solaris_ifconfig_single_interface +3 -0
  34. data/spec/unit/facter.rb +134 -0
  35. data/spec/unit/util/collection.rb +255 -0
  36. data/spec/unit/util/confine.rb +75 -0
  37. data/spec/unit/util/fact.rb +129 -0
  38. data/spec/unit/util/ip.rb +40 -0
  39. data/spec/unit/util/loader.rb +219 -0
  40. data/spec/unit/util/resolution.rb +209 -0
  41. metadata +31 -2
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../../spec_helper'
4
+
5
+ require 'facter/util/confine'
6
+
7
+ describe Facter::Util::Confine do
8
+ it "should require a fact name" do
9
+ Facter::Util::Confine.new("yay", true).fact.should == "yay"
10
+ end
11
+
12
+ it "should accept a value specified individually" do
13
+ Facter::Util::Confine.new("yay", "test").values.should == ["test"]
14
+ end
15
+
16
+ it "should accept multiple values specified at once" do
17
+ Facter::Util::Confine.new("yay", "test", "other").values.should == ["test", "other"]
18
+ end
19
+
20
+ it "should convert all values to strings" do
21
+ Facter::Util::Confine.new("yay", :test).values.should == %w{test}
22
+ end
23
+
24
+ it "should fail if no fact name is provided" do
25
+ lambda { Facter::Util::Confine.new(nil, :test) }.should raise_error(ArgumentError)
26
+ end
27
+
28
+ it "should fail if no values were provided" do
29
+ lambda { Facter::Util::Confine.new("yay") }.should raise_error(ArgumentError)
30
+ end
31
+
32
+ it "should have a method for testing whether it matches" do
33
+ Facter::Util::Confine.new("yay", :test).should respond_to(:true?)
34
+ end
35
+
36
+ describe "when evaluating" do
37
+ before do
38
+ @confine = Facter::Util::Confine.new("yay", "one", "two")
39
+ @fact = mock 'fact'
40
+ Facter.stubs(:[]).returns @fact
41
+ end
42
+
43
+ it "should return false if the fact does not exist" do
44
+ Facter.expects(:[]).with("yay").returns nil
45
+
46
+ @confine.true?.should be_false
47
+ end
48
+
49
+ it "should use the returned fact to get the value" do
50
+ Facter.expects(:[]).with("yay").returns @fact
51
+
52
+ @fact.expects(:value).returns nil
53
+
54
+ @confine.true?
55
+ end
56
+
57
+ it "should return false if the fact has no value" do
58
+ @fact.stubs(:value).returns nil
59
+
60
+ @confine.true?.should be_false
61
+ end
62
+
63
+ it "should return true if any of the provided values matches the fact's value" do
64
+ @fact.stubs(:value).returns "two"
65
+
66
+ @confine.true?.should be_true
67
+ end
68
+
69
+ it "should return false if none of the provided values matches the fact's value" do
70
+ @fact.stubs(:value).returns "three"
71
+
72
+ @confine.true?.should be_false
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../../spec_helper'
4
+
5
+ require 'facter/util/fact'
6
+
7
+ describe Facter::Util::Fact do
8
+ it "should require a name" do
9
+ lambda { Facter::Util::Fact.new }.should raise_error(ArgumentError)
10
+ end
11
+
12
+ it "should always downcase the name and convert it to a symbol" do
13
+ Facter::Util::Fact.new("YayNess").name.should == :yayness
14
+ end
15
+
16
+ it "should default to its name converted to a string as its ldapname" do
17
+ Facter::Util::Fact.new("YayNess").ldapname.should == "yayness"
18
+ end
19
+
20
+ it "should allow specifying the ldap name at initialization" do
21
+ Facter::Util::Fact.new("YayNess", :ldapname => "fooness").ldapname.should == "fooness"
22
+ end
23
+
24
+ it "should fail if an unknown option is provided" do
25
+ lambda { Facter::Util::Fact.new('yay', :foo => :bar) }.should raise_error(ArgumentError)
26
+ end
27
+
28
+ it "should have a method for adding resolution mechanisms" do
29
+ Facter::Util::Fact.new("yay").should respond_to(:add)
30
+ end
31
+
32
+ describe "when adding resolution mechanisms" do
33
+ before do
34
+ @fact = Facter::Util::Fact.new("yay")
35
+
36
+ @resolution = mock 'resolution'
37
+ @resolution.stub_everything
38
+
39
+ end
40
+
41
+ it "should fail if no block is given" do
42
+ lambda { @fact.add }.should raise_error(ArgumentError)
43
+ end
44
+
45
+ it "should create a new resolution instance" do
46
+ Facter::Util::Resolution.expects(:new).returns @resolution
47
+
48
+ @fact.add { }
49
+ end
50
+
51
+ it "should instance_eval the passed block on the new resolution" do
52
+ @resolution.expects(:instance_eval)
53
+
54
+ Facter::Util::Resolution.stubs(:new).returns @resolution
55
+
56
+ @fact.add { }
57
+ end
58
+
59
+ it "should re-sort the resolutions by length, so the most restricted resolutions are first" do
60
+ r1 = stub 'r1', :length => 1
61
+ r2 = stub 'r2', :length => 2
62
+ r3 = stub 'r3', :length => 0
63
+ Facter::Util::Resolution.expects(:new).times(3).returns(r1).returns(r2).returns(r3)
64
+ @fact.add { }
65
+ @fact.add { }
66
+ @fact.add { }
67
+
68
+ @fact.instance_variable_get("@resolves").should == [r2, r1, r3]
69
+ end
70
+ end
71
+
72
+ it "should be able to return a value" do
73
+ Facter::Util::Fact.new("yay").should respond_to(:value)
74
+ end
75
+
76
+ describe "when returning a value" do
77
+ before do
78
+ @fact = Facter::Util::Fact.new("yay")
79
+ end
80
+
81
+ it "should return nil if there are no resolutions" do
82
+ Facter::Util::Fact.new("yay").value.should be_nil
83
+ end
84
+
85
+ it "should return the first value returned by a resolution" do
86
+ r1 = stub 'r1', :length => 2, :value => nil, :suitable? => true
87
+ r2 = stub 'r2', :length => 1, :value => "yay", :suitable? => true
88
+ r3 = stub 'r3', :length => 0, :value => "foo", :suitable? => true
89
+ Facter::Util::Resolution.expects(:new).times(3).returns(r1).returns(r2).returns(r3)
90
+ @fact.add { }
91
+ @fact.add { }
92
+ @fact.add { }
93
+
94
+ @fact.value.should == "yay"
95
+ end
96
+
97
+ it "should short-cut returning the value once one is found" do
98
+ r1 = stub 'r1', :length => 2, :value => "foo", :suitable? => true
99
+ r2 = stub 'r2', :length => 1, :suitable? => true # would fail if 'value' were asked for
100
+ Facter::Util::Resolution.expects(:new).times(2).returns(r1).returns(r2)
101
+ @fact.add { }
102
+ @fact.add { }
103
+
104
+ @fact.value
105
+ end
106
+
107
+ it "should skip unsuitable resolutions" do
108
+ r1 = stub 'r1', :length => 2, :suitable? => false # would fail if 'value' were asked for'
109
+ r2 = stub 'r2', :length => 1, :value => "yay", :suitable? => true
110
+ Facter::Util::Resolution.expects(:new).times(2).returns(r1).returns(r2)
111
+ @fact.add { }
112
+ @fact.add { }
113
+
114
+ @fact.value.should == "yay"
115
+ end
116
+
117
+ it "should return nil if the value is the empty string" do
118
+ r1 = stub 'r1', :suitable? => true, :value => ""
119
+ Facter::Util::Resolution.expects(:new).returns r1
120
+ @fact.add { }
121
+
122
+ @fact.value.should be_nil
123
+ end
124
+ end
125
+
126
+ it "should have a method for flushing the cached fact" do
127
+ Facter::Util::Fact.new(:foo).should respond_to(:flush)
128
+ end
129
+ end
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../../spec_helper'
4
+
5
+ require 'facter/util/ip'
6
+
7
+ describe Facter::IPAddress do
8
+
9
+ it "should return a list of interfaces" do
10
+ Facter::IPAddress.should respond_to(:get_interfaces)
11
+ end
12
+
13
+ it "should return an empty list of interfaces on an unknown kernel" do
14
+ Facter.stubs(:value).returns("UnknownKernel")
15
+ Facter::IPAddress.get_interfaces().should == []
16
+ end
17
+
18
+ it "should return a list with a single interface on Linux with a single interface" do
19
+ sample_output_file = File.dirname(__FILE__) + '/../data/linux_ifconfig_all_with_single_interface'
20
+ linux_ifconfig = File.new(sample_output_file).read()
21
+ Facter::IPAddress.stubs(:get_all_interface_output).returns(linux_ifconfig)
22
+ Facter::IPAddress.get_interfaces().should == ["eth0"]
23
+ end
24
+
25
+ it "should return a value for a specific interface" do
26
+ Facter::IPAddress.should respond_to(:get_interface_value)
27
+ end
28
+
29
+ it "should return a human readable netmask on Solaris" do
30
+ sample_output_file = File.dirname(__FILE__) + "/../data/solaris_ifconfig_single_interface"
31
+ solaris_ifconfig_interface = File.new(sample_output_file).read()
32
+
33
+ Facter::IPAddress.expects(:get_single_interface_output).with("e1000g0").returns(solaris_ifconfig_interface)
34
+ Facter.stubs(:value).with(:kernel).returns("SunOS")
35
+
36
+ Facter::IPAddress.get_interface_value("e1000g0", "netmask").should == "255.255.255.0"
37
+ end
38
+
39
+ end
40
+
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../../spec_helper'
4
+
5
+ require 'facter/util/loader'
6
+
7
+ describe Facter::Util::Loader do
8
+ def with_env(values)
9
+ old = {}
10
+ values.each do |var, value|
11
+ if old_val = ENV[var]
12
+ old[var] = old_val
13
+ end
14
+ ENV[var] = value
15
+ end
16
+ yield
17
+ values.each do |var, value|
18
+ if old.include?(var)
19
+ ENV[var] = old[var]
20
+ else
21
+ ENV.delete(var)
22
+ end
23
+ end
24
+ end
25
+
26
+ it "should have a method for loading individual facts by name" do
27
+ Facter::Util::Loader.new.should respond_to(:load)
28
+ end
29
+
30
+ it "should have a method for loading all facts" do
31
+ Facter::Util::Loader.new.should respond_to(:load_all)
32
+ end
33
+
34
+ it "should have a method for returning directories containing facts" do
35
+ Facter::Util::Loader.new.should respond_to(:search_path)
36
+ end
37
+
38
+ describe "when determining the search path" do
39
+ before do
40
+ @loader = Facter::Util::Loader.new
41
+ @settings = mock 'settings'
42
+ @settings.stubs(:value).returns "/eh"
43
+ end
44
+
45
+ it "should include the facter subdirectory of all paths in ruby LOAD_PATH" do
46
+ dirs = $LOAD_PATH.collect { |d| File.join(d, "facter") }
47
+ paths = @loader.search_path
48
+
49
+ dirs.each do |dir|
50
+ paths.should be_include(dir)
51
+ end
52
+ end
53
+
54
+ it "should include all search paths registered with Facter" do
55
+ Facter.expects(:search_path).returns %w{/one /two}
56
+ paths = @loader.search_path
57
+ paths.should be_include("/one")
58
+ paths.should be_include("/two")
59
+ end
60
+
61
+ describe "and the FACTERLIB environment variable is set" do
62
+ it "should include all paths in FACTERLIB" do
63
+ with_env "FACTERLIB" => "/one/path:/two/path" do
64
+ paths = @loader.search_path
65
+ %w{/one/path /two/path}.each do |dir|
66
+ paths.should be_include(dir)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "when loading facts" do
74
+ before do
75
+ @loader = Facter::Util::Loader.new
76
+ @loader.stubs(:search_path).returns []
77
+ end
78
+
79
+ it "should load values from the matching environment variable if one is present" do
80
+ Facter.expects(:add).with("testing")
81
+
82
+ with_env "facter_testing" => "yayness" do
83
+ @loader.load(:testing)
84
+ end
85
+ end
86
+
87
+ it "should load any files in the search path with names matching the fact name" do
88
+ @loader.expects(:search_path).returns %w{/one/dir /two/dir}
89
+ FileTest.stubs(:exist?).returns false
90
+ FileTest.expects(:exist?).with("/one/dir/testing.rb").returns true
91
+ FileTest.expects(:exist?).with("/two/dir/testing.rb").returns true
92
+
93
+ Kernel.expects(:load).with("/one/dir/testing.rb")
94
+ Kernel.expects(:load).with("/two/dir/testing.rb")
95
+
96
+ @loader.load(:testing)
97
+ end
98
+
99
+ it "should load any ruby files in directories matching the fact name in the search path" do
100
+ @loader.expects(:search_path).returns %w{/one/dir}
101
+ FileTest.stubs(:exist?).returns false
102
+ FileTest.expects(:directory?).with("/one/dir/testing").returns true
103
+
104
+ Dir.expects(:entries).with("/one/dir/testing").returns %w{two.rb}
105
+
106
+ Kernel.expects(:load).with("/one/dir/testing/two.rb")
107
+
108
+ @loader.load(:testing)
109
+ end
110
+
111
+ it "should not load files that don't end in '.rb'" do
112
+ @loader.expects(:search_path).returns %w{/one/dir}
113
+ FileTest.stubs(:exist?).returns false
114
+ FileTest.expects(:directory?).with("/one/dir/testing").returns true
115
+
116
+ Dir.expects(:entries).with("/one/dir/testing").returns %w{one}
117
+
118
+ Kernel.expects(:load).never
119
+
120
+ @loader.load(:testing)
121
+ end
122
+ end
123
+
124
+ describe "when loading all facts" do
125
+ before do
126
+ @loader = Facter::Util::Loader.new
127
+ @loader.stubs(:search_path).returns []
128
+
129
+ FileTest.stubs(:directory?).returns true
130
+ end
131
+
132
+ it "should skip directories that do not exist" do
133
+ @loader.expects(:search_path).returns %w{/one/dir}
134
+
135
+ FileTest.expects(:directory?).with("/one/dir").returns false
136
+
137
+ Dir.expects(:entries).with("/one/dir").never
138
+
139
+ @loader.load_all
140
+ end
141
+
142
+ it "should load all files in all search paths" do
143
+ @loader.expects(:search_path).returns %w{/one/dir /two/dir}
144
+
145
+ Dir.expects(:entries).with("/one/dir").returns %w{a.rb b.rb}
146
+ Dir.expects(:entries).with("/two/dir").returns %w{c.rb d.rb}
147
+
148
+ %w{/one/dir/a.rb /one/dir/b.rb /two/dir/c.rb /two/dir/d.rb}.each { |f| Kernel.expects(:load).with(f) }
149
+
150
+ @loader.load_all
151
+ end
152
+
153
+ it "should load all files in all subdirectories in all search paths" do
154
+ @loader.expects(:search_path).returns %w{/one/dir /two/dir}
155
+
156
+ Dir.expects(:entries).with("/one/dir").returns %w{a}
157
+ Dir.expects(:entries).with("/two/dir").returns %w{b}
158
+
159
+ %w{/one/dir/a /two/dir/b}.each { |f| File.expects(:directory?).with(f).returns true }
160
+
161
+ Dir.expects(:entries).with("/one/dir/a").returns %w{c.rb}
162
+ Dir.expects(:entries).with("/two/dir/b").returns %w{d.rb}
163
+
164
+ %w{/one/dir/a/c.rb /two/dir/b/d.rb}.each { |f| Kernel.expects(:load).with(f) }
165
+
166
+ @loader.load_all
167
+ end
168
+
169
+ it "should not load files in the util subdirectory" do
170
+ @loader.expects(:search_path).returns %w{/one/dir}
171
+
172
+ Dir.expects(:entries).with("/one/dir").returns %w{util}
173
+
174
+ File.expects(:directory?).with("/one/dir/util").returns true
175
+
176
+ Dir.expects(:entries).with("/one/dir/util").never
177
+
178
+ @loader.load_all
179
+ end
180
+
181
+ it "should not load files in a lib subdirectory" do
182
+ @loader.expects(:search_path).returns %w{/one/dir}
183
+
184
+ Dir.expects(:entries).with("/one/dir").returns %w{lib}
185
+
186
+ File.expects(:directory?).with("/one/dir/lib").returns true
187
+
188
+ Dir.expects(:entries).with("/one/dir/lib").never
189
+
190
+ @loader.load_all
191
+ end
192
+
193
+ it "should not load files in '.' or '..'" do
194
+ @loader.expects(:search_path).returns %w{/one/dir}
195
+
196
+ Dir.expects(:entries).with("/one/dir").returns %w{. ..}
197
+
198
+ File.expects(:entries).with("/one/dir/.").never
199
+ File.expects(:entries).with("/one/dir/..").never
200
+
201
+ @loader.load_all
202
+ end
203
+
204
+ it "should load all facts from the environment" do
205
+ Facter.expects(:add).with('one')
206
+ Facter.expects(:add).with('two')
207
+
208
+ with_env "facter_one" => "yayness", "facter_two" => "boo" do
209
+ @loader.load_all
210
+ end
211
+ end
212
+
213
+ it "should only load all facts one time" do
214
+ @loader.expects(:load_env).once
215
+ @loader.load_all
216
+ @loader.load_all
217
+ end
218
+ end
219
+ end