(#7670) Never fail to find a fact that is present
With the previous behavior, any fact which depended on another fact in a file
not matching its name would fail to properly load the required fact, resulting
in missing, incorrect, or inconsistent values.
For instance, the operatingsystem fact depends on the lsbdistid fact found in
lsb.rb. The first time the operatingsystem fact is requested, it requires
lsb.rb, and so the required fact is loaded first. But if Facter is subsequently
cleared and the operatingsystem fact requested again, the require will not
occur, and the fact will not be automatically loaded because it doesn't match
its filename.
Now if a fact is requested and can't be found, we will attempt to load all the
facts to find it. Such an approach appears heavy-handed, but in the case where
we want a particular fact, this is the only way to make sure we've found it. In
the case where we eventually want other facts, we are conveniently eagerly
loading them.
Paired-With: Jacob Helwig <jacob@puppetlabs.com>
Nick Lewis
12 years ago
65 | 65 |
def fact(name)
|
66 | 66 |
name = canonize(name)
|
67 | 67 |
|
|
68 |
# Try to load the fact if necessary
|
68 | 69 |
loader.load(name) unless @facts[name]
|
69 | 70 |
|
70 | |
return @facts[name]
|
|
71 |
# Try HARDER
|
|
72 |
loader.load_all unless @facts[name]
|
|
73 |
|
|
74 |
@facts[name]
|
71 | 75 |
end
|
72 | 76 |
|
73 | 77 |
# Flush all cached values.
|
17 | 17 |
|
18 | 18 |
# Ensure that we don't accidentally cache between test cases.
|
19 | 19 |
config.before :each do
|
|
20 |
Facter::Util::Loader.any_instance.stubs(:load_all)
|
20 | 21 |
Facter.clear
|
21 | 22 |
end
|
22 | 23 |
end
|
2 | 2 |
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
3 | 3 |
|
4 | 4 |
require 'facter'
|
|
5 |
require 'facter/util/ip'
|
5 | 6 |
|
6 | 7 |
describe "Per Interface IP facts" do
|
7 | |
before do
|
8 | |
Facter.loadfacts
|
9 | |
end
|
10 | |
|
11 | 8 |
it "should replace the ':' in an interface list with '_'" do
|
12 | 9 |
# So we look supported
|
13 | 10 |
Facter.fact(:kernel).stubs(:value).returns("SunOS")
|
14 | 11 |
|
15 | |
Facter::Util::IP.expects(:get_interfaces).returns %w{eth0:1 eth1:2}
|
|
12 |
Facter::Util::IP.stubs(:get_interfaces).returns %w{eth0:1 eth1:2}
|
16 | 13 |
Facter.fact(:interfaces).value.should == %{eth0_1,eth1_2}
|
17 | 14 |
end
|
18 | 15 |
end
|
5 | 5 |
|
6 | 6 |
describe "Memory facts" do
|
7 | 7 |
before do
|
8 | |
Facter.loadfacts
|
|
8 |
# We need these facts loaded, but they belong to a file with a
|
|
9 |
# different name, so load the file explicitly.
|
|
10 |
Facter.collection.loader.load(:memory)
|
9 | 11 |
end
|
10 | 12 |
|
11 | 13 |
after do
|
33 | 33 |
|
34 | 34 |
it "should identify Oracle VM as OVS" do
|
35 | 35 |
Facter.fact(:kernel).stubs(:value).returns("Linux")
|
|
36 |
Facter.stubs(:value).with(:lsbdistid).returns(nil)
|
36 | 37 |
FileTest.stubs(:exists?).returns false
|
37 | 38 |
|
38 | 39 |
FileTest.expects(:exists?).with("/etc/ovs-release").returns true
|
|
43 | 44 |
|
44 | 45 |
it "should identify VMWare ESX" do
|
45 | 46 |
Facter.fact(:kernel).stubs(:value).returns("Linux")
|
|
47 |
Facter.stubs(:value).with(:lsbdistid).returns(nil)
|
46 | 48 |
FileTest.stubs(:exists?).returns false
|
47 | 49 |
|
48 | 50 |
FileTest.expects(:exists?).with("/etc/vmware-release").returns true
|
18 | 18 |
|
19 | 19 |
|
20 | 20 |
describe Facter::Util::Loader do
|
|
21 |
before :each do
|
|
22 |
Facter::Util::Loader.any_instance.unstub(:load_all)
|
|
23 |
end
|
|
24 |
|
21 | 25 |
def with_env(values)
|
22 | 26 |
old = {}
|
23 | 27 |
values.each do |var, value|
|