facter 1.7.6 → 2.0.1.rc1
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.
- checksums.yaml +7 -0
- data/COMMITTERS.md +194 -0
- data/CONTRIBUTING.md +63 -235
- data/Gemfile +12 -8
- data/README.md +1 -2
- data/Rakefile +1 -1
- data/bin/facter +0 -4
- data/ext/build_defaults.yaml +2 -2
- data/ext/project_data.yaml +18 -0
- data/install.rb +1 -16
- data/lib/facter.rb +171 -171
- data/lib/facter/application.rb +65 -54
- data/lib/facter/core/aggregate.rb +220 -0
- data/lib/facter/core/directed_graph.rb +46 -0
- data/lib/facter/core/execution.rb +100 -0
- data/lib/facter/core/execution/base.rb +73 -0
- data/lib/facter/core/execution/posix.rb +50 -0
- data/lib/facter/core/execution/windows.rb +57 -0
- data/lib/facter/core/logging.rb +169 -0
- data/lib/facter/core/resolvable.rb +94 -0
- data/lib/facter/core/suitable.rb +117 -0
- data/lib/facter/domain.rb +15 -9
- data/lib/facter/filesystems.rb +1 -1
- data/lib/facter/hardwaremodel.rb +1 -1
- data/lib/facter/hostname.rb +3 -3
- data/lib/facter/interfaces.rb +6 -1
- data/lib/facter/ipaddress.rb +2 -2
- data/lib/facter/kernel.rb +1 -1
- data/lib/facter/kernelrelease.rb +1 -1
- data/lib/facter/ldom.rb +1 -1
- data/lib/facter/lsbdistcodename.rb +1 -1
- data/lib/facter/lsbdistdescription.rb +1 -1
- data/lib/facter/lsbdistid.rb +1 -1
- data/lib/facter/lsbdistrelease.rb +1 -1
- data/lib/facter/lsbrelease.rb +1 -1
- data/lib/facter/macaddress.rb +1 -14
- data/lib/facter/macosx.rb +2 -2
- data/lib/facter/memory.rb +8 -19
- data/lib/facter/operatingsystem.rb +1 -1
- data/lib/facter/operatingsystemrelease.rb +34 -1
- data/lib/facter/physicalprocessorcount.rb +6 -6
- data/lib/facter/processor.rb +11 -10
- data/lib/facter/selinux.rb +4 -15
- data/lib/facter/ssh.rb +5 -2
- data/lib/facter/util/architecture.rb +2 -2
- data/lib/facter/util/collection.rb +42 -38
- data/lib/facter/util/config.rb +19 -9
- data/lib/facter/util/confine.rb +34 -4
- data/lib/facter/util/ec2.rb +1 -1
- data/lib/facter/util/fact.rb +108 -36
- data/lib/facter/util/file_read.rb +7 -6
- data/lib/facter/util/formatter.rb +38 -0
- data/lib/facter/util/ip.rb +3 -3
- data/lib/facter/util/loader.rb +62 -42
- data/lib/facter/util/macosx.rb +7 -8
- data/lib/facter/util/manufacturer.rb +3 -3
- data/lib/facter/util/memory.rb +13 -13
- data/lib/facter/util/monkey_patches.rb +0 -31
- data/lib/facter/util/netmask.rb +3 -3
- data/lib/facter/util/normalization.rb +94 -0
- data/lib/facter/util/nothing_loader.rb +3 -6
- data/lib/facter/util/parser.rb +3 -5
- data/lib/facter/util/plist/generator.rb +1 -1
- data/lib/facter/util/processor.rb +15 -15
- data/lib/facter/util/resolution.rb +112 -289
- data/lib/facter/util/solaris_zones.rb +4 -4
- data/lib/facter/util/uptime.rb +8 -3
- data/lib/facter/util/values.rb +67 -1
- data/lib/facter/util/virtual.rb +10 -10
- data/lib/facter/util/xendomains.rb +1 -1
- data/lib/facter/version.rb +42 -39
- data/lib/facter/virtual.rb +6 -7
- data/lib/facter/zfs_version.rb +3 -3
- data/lib/facter/zpool_version.rb +3 -3
- data/spec/fixtures/unit/netmask/darwin_10_8_5.txt +30 -0
- data/spec/unit/application_spec.rb +46 -1
- data/spec/unit/core/aggregate_spec.rb +125 -0
- data/spec/unit/core/directed_graph_spec.rb +79 -0
- data/spec/unit/core/execution/base_spec.rb +119 -0
- data/spec/unit/core/execution/posix_spec.rb +86 -0
- data/spec/unit/core/execution/windows_spec.rb +106 -0
- data/spec/unit/core/execution_spec.rb +37 -0
- data/spec/unit/core/logging_spec.rb +104 -0
- data/spec/unit/core/resolvable_spec.rb +81 -0
- data/spec/unit/core/suitable_spec.rb +96 -0
- data/spec/unit/domain_spec.rb +5 -5
- data/spec/unit/facter_spec.rb +61 -222
- data/spec/unit/filesystems_spec.rb +2 -2
- data/spec/unit/hardwareisa_spec.rb +5 -5
- data/spec/unit/hardwaremodel_spec.rb +1 -1
- data/spec/unit/hostname_spec.rb +4 -4
- data/spec/unit/id_spec.rb +3 -3
- data/spec/unit/interfaces_spec.rb +10 -0
- data/spec/unit/ipaddress6_spec.rb +4 -4
- data/spec/unit/ipaddress_spec.rb +1 -1
- data/spec/unit/kernel_spec.rb +2 -2
- data/spec/unit/kernelmajversion_spec.rb +1 -1
- data/spec/unit/kernelrelease_spec.rb +4 -4
- data/spec/unit/kernelversion_spec.rb +2 -2
- data/spec/unit/ldom_spec.rb +2 -2
- data/spec/unit/lsbdistcodename_spec.rb +2 -2
- data/spec/unit/lsbdistdescription_spec.rb +2 -2
- data/spec/unit/lsbdistid_spec.rb +2 -2
- data/spec/unit/lsbdistrelease_spec.rb +2 -2
- data/spec/unit/lsbrelease_spec.rb +2 -2
- data/spec/unit/manufacturer_spec.rb +1 -1
- data/spec/unit/memory_spec.rb +24 -31
- data/spec/unit/netmask_spec.rb +9 -0
- data/spec/unit/operatingsystem_spec.rb +1 -1
- data/spec/unit/operatingsystemrelease_spec.rb +62 -4
- data/spec/unit/physicalprocessorcount_spec.rb +10 -10
- data/spec/unit/processor_spec.rb +11 -11
- data/spec/unit/selinux_spec.rb +2 -8
- data/spec/unit/ssh_spec.rb +3 -2
- data/spec/unit/uniqueid_spec.rb +3 -3
- data/spec/unit/util/collection_spec.rb +37 -35
- data/spec/unit/util/config_spec.rb +20 -0
- data/spec/unit/util/confine_spec.rb +21 -0
- data/spec/unit/util/directory_loader_spec.rb +1 -0
- data/spec/unit/util/ec2_spec.rb +6 -6
- data/spec/unit/util/fact_spec.rb +92 -90
- data/spec/unit/util/ip_spec.rb +2 -2
- data/spec/unit/util/loader_spec.rb +127 -186
- data/spec/unit/util/macaddress_spec.rb +2 -2
- data/spec/unit/util/macosx_spec.rb +8 -8
- data/spec/unit/util/manufacturer_spec.rb +3 -3
- data/spec/unit/util/normalization_spec.rb +113 -0
- data/spec/unit/util/parser_spec.rb +25 -3
- data/spec/unit/util/processor_spec.rb +2 -2
- data/spec/unit/util/resolution_spec.rb +60 -631
- data/spec/unit/util/solaris_zones_spec.rb +5 -5
- data/spec/unit/util/uptime_spec.rb +1 -1
- data/spec/unit/util/values_spec.rb +131 -0
- data/spec/unit/util/virtual_spec.rb +16 -16
- data/spec/unit/util/xendomains_spec.rb +2 -2
- data/spec/unit/virtual_spec.rb +39 -39
- data/spec/unit/zfs_version_spec.rb +11 -11
- data/spec/unit/zonename_spec.rb +2 -2
- data/spec/unit/zones_spec.rb +1 -1
- data/spec/unit/zpool_version_spec.rb +11 -11
- metadata +466 -447
- data/lib/facter/util/cfpropertylist.rb +0 -6
- data/lib/facter/util/cfpropertylist/LICENSE +0 -19
- data/lib/facter/util/cfpropertylist/README +0 -44
- data/lib/facter/util/cfpropertylist/Rakefile +0 -44
- data/lib/facter/util/cfpropertylist/THANKS +0 -7
- data/lib/facter/util/cfpropertylist/lib/cfpropertylist.rb +0 -6
- data/lib/facter/util/cfpropertylist/lib/rbBinaryCFPropertyList.rb +0 -562
- data/lib/facter/util/cfpropertylist/lib/rbCFPlistError.rb +0 -26
- data/lib/facter/util/cfpropertylist/lib/rbCFPropertyList.rb +0 -407
- data/lib/facter/util/cfpropertylist/lib/rbCFTypes.rb +0 -244
- data/lib/facter/util/cfpropertylist/lib/rbLibXMLParser.rb +0 -135
- data/lib/facter/util/cfpropertylist/lib/rbNokogiriParser.rb +0 -140
- data/lib/facter/util/cfpropertylist/lib/rbREXMLParser.rb +0 -136
- data/spec/unit/util/monkey_patches_spec.rb +0 -42
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'facter/core/aggregate'
|
3
|
+
|
4
|
+
describe Facter::Core::Aggregate do
|
5
|
+
|
6
|
+
let(:fact) { stub('stub_fact', :name => 'stub_fact') }
|
7
|
+
|
8
|
+
subject { obj = described_class.new('aggregated', fact) }
|
9
|
+
|
10
|
+
it "can be resolved" do
|
11
|
+
expect(subject).to be_a_kind_of Facter::Core::Resolvable
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can be confined and weighted" do
|
15
|
+
expect(subject).to be_a_kind_of Facter::Core::Suitable
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "setting options" do
|
19
|
+
|
20
|
+
it "can set the timeout" do
|
21
|
+
subject.set_options(:timeout => 314)
|
22
|
+
expect(subject.limit).to eq 314
|
23
|
+
end
|
24
|
+
|
25
|
+
it "can set the weight" do
|
26
|
+
subject.set_options(:weight => 27)
|
27
|
+
expect(subject.weight).to eq 27
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can set the name" do
|
31
|
+
subject.set_options(:name => 'something')
|
32
|
+
expect(subject.name).to eq 'something'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "fails on unhandled options" do
|
36
|
+
expect do
|
37
|
+
subject.set_options(:foo => 'bar')
|
38
|
+
end.to raise_error(ArgumentError, /Invalid aggregate options .*foo/)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "declaring chunks" do
|
43
|
+
it "requires that an chunk is given a block" do
|
44
|
+
expect { subject.chunk(:fail) }.to raise_error(ArgumentError, /requires a block/)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "allows an chunk to have a list of requirements" do
|
48
|
+
subject.chunk(:data, :require => [:other]) { }
|
49
|
+
expect(subject.deps[:data]).to eq [:other]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "converts a single chunk requirement to an array" do
|
53
|
+
subject.chunk(:data, :require => :other) { }
|
54
|
+
expect(subject.deps[:data]).to eq [:other]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "raises an error when an unhandled option is passed" do
|
58
|
+
expect {
|
59
|
+
subject.chunk(:data, :before => [:other]) { }
|
60
|
+
}.to raise_error(ArgumentError, /Unexpected options.*#chunk: .*before/)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "handling interactions between chunks" do
|
65
|
+
it "generates a warning when there is a dependency cycle in chunks" do
|
66
|
+
subject.chunk(:first, :require => [:second]) { }
|
67
|
+
subject.chunk(:second, :require => [:first]) { }
|
68
|
+
|
69
|
+
Facter.expects(:warn) do |msg|
|
70
|
+
expect(msg).to match /dependency cycles: .*[:first, :second]/
|
71
|
+
end
|
72
|
+
|
73
|
+
subject.value
|
74
|
+
end
|
75
|
+
|
76
|
+
it "passes all requested chunk results to the depending chunk" do
|
77
|
+
subject.chunk(:first) { ['foo'] }
|
78
|
+
subject.chunk(:second, :require => [:first]) do |first|
|
79
|
+
[first[0] + ' bar']
|
80
|
+
end
|
81
|
+
|
82
|
+
output = subject.value
|
83
|
+
expect(output).to include 'foo'
|
84
|
+
expect(output).to include 'foo bar'
|
85
|
+
end
|
86
|
+
|
87
|
+
it "clones and freezes chunk results passed to other chunks" do
|
88
|
+
subject.chunk(:first) { 'foo' }
|
89
|
+
subject.chunk(:second, :require => [:first]) do |first|
|
90
|
+
expect(first).to be_frozen
|
91
|
+
end
|
92
|
+
|
93
|
+
subject.aggregate do |chunks|
|
94
|
+
chunks.values.each do |chunk|
|
95
|
+
expect(chunk).to be_frozen
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "aggregating chunks" do
|
102
|
+
it "passes all chunk results as a hash to the aggregate block" do
|
103
|
+
subject.chunk(:data) { 'data chunk' }
|
104
|
+
subject.chunk(:datum) { 'datum chunk' }
|
105
|
+
|
106
|
+
subject.aggregate do |chunks|
|
107
|
+
expect(chunks).to eq(:data => 'data chunk', :datum => 'datum chunk')
|
108
|
+
end
|
109
|
+
|
110
|
+
subject.value
|
111
|
+
end
|
112
|
+
|
113
|
+
it "uses the result of the aggregate block as the value" do
|
114
|
+
subject.aggregate { "who needs chunks anyways" }
|
115
|
+
expect(subject.value).to eq "who needs chunks anyways"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "evaluating" do
|
120
|
+
it "evaluates the block in the context of the aggregate" do
|
121
|
+
subject.expects(:has_weight).with(5)
|
122
|
+
subject.evaluate { has_weight(5) }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'facter/core/directed_graph'
|
3
|
+
|
4
|
+
describe Facter::Core::DirectedGraph do
|
5
|
+
subject(:graph) { described_class.new }
|
6
|
+
|
7
|
+
describe "detecting cycles" do
|
8
|
+
it "is acyclic if the graph is empty" do
|
9
|
+
expect(graph).to be_acyclic
|
10
|
+
end
|
11
|
+
|
12
|
+
it "is acyclic if the graph has no edges" do
|
13
|
+
graph[:one] = []
|
14
|
+
graph[:two] = []
|
15
|
+
|
16
|
+
expect(graph).to be_acyclic
|
17
|
+
end
|
18
|
+
|
19
|
+
it "is acyclic if a vertex has an edge to itself" do
|
20
|
+
graph[:one] = [:one]
|
21
|
+
expect(graph).to be_acyclic
|
22
|
+
end
|
23
|
+
|
24
|
+
it "is acyclic if there are no loops in the graph" do
|
25
|
+
graph[:one] = [:two, :three]
|
26
|
+
graph[:two] = [:four]
|
27
|
+
graph[:three] = [:four]
|
28
|
+
graph[:four] = []
|
29
|
+
|
30
|
+
expect(graph).to be_acyclic
|
31
|
+
end
|
32
|
+
|
33
|
+
it "is cyclic if there is a loop in the graph" do
|
34
|
+
graph[:one] = [:two]
|
35
|
+
graph[:two] = [:one]
|
36
|
+
expect(graph).to_not be_acyclic
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can return the cycles in the graph" do
|
40
|
+
graph[:one] = [:two]
|
41
|
+
graph[:two] = [:one]
|
42
|
+
|
43
|
+
graph[:three] = [:four]
|
44
|
+
graph[:four] = [:three]
|
45
|
+
|
46
|
+
first_cycle = graph.cycles.find { |cycle| cycle.include? :one }
|
47
|
+
second_cycle = graph.cycles.find { |cycle| cycle.include? :three }
|
48
|
+
|
49
|
+
expect(first_cycle).to include :two
|
50
|
+
expect(second_cycle).to include :four
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "sorting" do
|
55
|
+
it "returns the vertices in topologically sorted order" do
|
56
|
+
graph[:one] = [:two, :three]
|
57
|
+
graph[:two] = [:three]
|
58
|
+
graph[:three] = []
|
59
|
+
expect(graph.tsort).to eq [:three, :two, :one]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "raises an error if there is a cycle in the graph" do
|
63
|
+
graph[:one] = [:two]
|
64
|
+
graph[:two] = [:one]
|
65
|
+
|
66
|
+
expect {
|
67
|
+
graph.tsort
|
68
|
+
}.to raise_error(Facter::Core::DirectedGraph::CycleError, /found the following cycles:/)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "raises an error if there is an edge to a non-existent vertex" do
|
72
|
+
graph[:one] = [:two, :three]
|
73
|
+
graph[:two] = [:three]
|
74
|
+
expect {
|
75
|
+
graph.tsort
|
76
|
+
}.to raise_error(Facter::Core::DirectedGraph::MissingVertex, /missing elements.*three/)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'facter/core/execution'
|
3
|
+
|
4
|
+
describe Facter::Core::Execution::Base do
|
5
|
+
|
6
|
+
describe "#with_env" do
|
7
|
+
it "should execute the caller's block with the specified env vars" do
|
8
|
+
test_env = { "LANG" => "C", "FOO" => "BAR" }
|
9
|
+
subject.with_env test_env do
|
10
|
+
test_env.keys.each do |key|
|
11
|
+
ENV[key].should == test_env[key]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should restore pre-existing environment variables to their previous values" do
|
17
|
+
orig_env = {}
|
18
|
+
new_env = {}
|
19
|
+
# an arbitrary sentinel value to use to temporarily set the environment vars to
|
20
|
+
sentinel_value = "Abracadabra"
|
21
|
+
|
22
|
+
# grab some values from the existing ENV (arbitrarily choosing 3 here)
|
23
|
+
ENV.keys.first(3).each do |key|
|
24
|
+
# save the original values so that we can test against them later
|
25
|
+
orig_env[key] = ENV[key]
|
26
|
+
# create bogus temp values for the chosen keys
|
27
|
+
new_env[key] = sentinel_value
|
28
|
+
end
|
29
|
+
|
30
|
+
# verify that, during the 'with_env', the new values are used
|
31
|
+
subject.with_env new_env do
|
32
|
+
orig_env.keys.each do |key|
|
33
|
+
ENV[key].should == new_env[key]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# verify that, after the 'with_env', the old values are restored
|
38
|
+
orig_env.keys.each do |key|
|
39
|
+
ENV[key].should == orig_env[key]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not be affected by a 'return' statement in the yield block" do
|
44
|
+
@sentinel_var = :resolution_test_foo.to_s
|
45
|
+
|
46
|
+
# the intent of this test case is to test a yield block that contains a return statement. However, it's illegal
|
47
|
+
# to use a return statement outside of a method, so we need to create one here to give scope to the 'return'
|
48
|
+
def handy_method()
|
49
|
+
ENV[@sentinel_var] = "foo"
|
50
|
+
new_env = { @sentinel_var => "bar" }
|
51
|
+
|
52
|
+
subject.with_env new_env do
|
53
|
+
ENV[@sentinel_var].should == "bar"
|
54
|
+
return
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
handy_method()
|
59
|
+
|
60
|
+
ENV[@sentinel_var].should == "foo"
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#exec" do
|
66
|
+
|
67
|
+
it "switches LANG to C when executing the command" do
|
68
|
+
subject.expects(:with_env).with('LANG' => 'C')
|
69
|
+
subject.exec('foo')
|
70
|
+
end
|
71
|
+
|
72
|
+
it "switches LC_ALL to C when executing the command"
|
73
|
+
|
74
|
+
it "expands the command before running it" do
|
75
|
+
subject.stubs(:`).returns ''
|
76
|
+
subject.expects(:expand_command).with('foo').returns '/bin/foo'
|
77
|
+
subject.exec('foo')
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns an empty string when the command could not be expanded" do
|
81
|
+
subject.expects(:expand_command).with('foo').returns nil
|
82
|
+
expect(subject.exec('foo')).to be_empty
|
83
|
+
end
|
84
|
+
|
85
|
+
it "logs a warning and returns an empty string when the command execution fails" do
|
86
|
+
subject.expects(:`).with("/bin/foo").raises "kaboom!"
|
87
|
+
Facter.expects(:warn).with("kaboom!")
|
88
|
+
|
89
|
+
subject.expects(:expand_command).with('foo').returns '/bin/foo'
|
90
|
+
|
91
|
+
expect(subject.exec("foo")).to be_empty
|
92
|
+
end
|
93
|
+
|
94
|
+
it "launches a thread to wait on children if the command was interrupted" do
|
95
|
+
subject.expects(:`).with("/bin/foo").raises "kaboom!"
|
96
|
+
subject.expects(:expand_command).with('foo').returns '/bin/foo'
|
97
|
+
|
98
|
+
Facter.stubs(:warn)
|
99
|
+
Thread.expects(:new).yields
|
100
|
+
Process.expects(:waitall).once
|
101
|
+
|
102
|
+
subject.exec("foo")
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns the output of the command" do
|
106
|
+
subject.expects(:`).with("/bin/foo").returns 'hi'
|
107
|
+
subject.expects(:expand_command).with('foo').returns '/bin/foo'
|
108
|
+
|
109
|
+
expect(subject.exec("foo")).to eq 'hi'
|
110
|
+
end
|
111
|
+
|
112
|
+
it "strips off trailing newlines" do
|
113
|
+
subject.expects(:`).with("/bin/foo").returns "hi\n"
|
114
|
+
subject.expects(:expand_command).with('foo').returns '/bin/foo'
|
115
|
+
|
116
|
+
expect(subject.exec("foo")).to eq 'hi'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Facter::Core::Execution::Posix, :as_plaform => :posix do
|
4
|
+
|
5
|
+
describe "#search_paths" do
|
6
|
+
it "should use the PATH environment variable plus /sbin and /usr/sbin on unix" do
|
7
|
+
ENV.expects(:[]).with('PATH').returns "/bin:/usr/bin"
|
8
|
+
subject.search_paths.should == %w{/bin /usr/bin /sbin /usr/sbin}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#which" do
|
13
|
+
before :each do
|
14
|
+
subject.stubs(:search_paths).returns [ '/bin', '/sbin', '/usr/sbin']
|
15
|
+
end
|
16
|
+
|
17
|
+
context "and provided with an absolute path" do
|
18
|
+
it "should return the binary if executable" do
|
19
|
+
File.expects(:executable?).with('/opt/foo').returns true
|
20
|
+
subject.which('/opt/foo').should == '/opt/foo'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return nil if the binary is not executable" do
|
24
|
+
File.expects(:executable?).with('/opt/foo').returns false
|
25
|
+
subject.which('/opt/foo').should be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "and not provided with an absolute path" do
|
30
|
+
it "should return the absolute path if found" do
|
31
|
+
File.expects(:executable?).with('/bin/foo').returns false
|
32
|
+
File.expects(:executable?).with('/sbin/foo').returns true
|
33
|
+
File.expects(:executable?).with('/usr/sbin/foo').never
|
34
|
+
subject.which('foo').should == '/sbin/foo'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return nil if not found" do
|
38
|
+
File.expects(:executable?).with('/bin/foo').returns false
|
39
|
+
File.expects(:executable?).with('/sbin/foo').returns false
|
40
|
+
File.expects(:executable?).with('/usr/sbin/foo').returns false
|
41
|
+
subject.which('foo').should be_nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#expand_command" do
|
47
|
+
it "should expand binary" do
|
48
|
+
subject.expects(:which).with('foo').returns '/bin/foo'
|
49
|
+
subject.expand_command('foo -a | stuff >> /dev/null').should == '/bin/foo -a | stuff >> /dev/null'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should expand double quoted binary" do
|
53
|
+
subject.expects(:which).with('/tmp/my foo').returns '/tmp/my foo'
|
54
|
+
subject.expand_command(%q{"/tmp/my foo" bar}).should == %q{'/tmp/my foo' bar}
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should expand single quoted binary" do
|
58
|
+
subject.expects(:which).with('my foo').returns '/home/bob/my path/my foo'
|
59
|
+
subject.expand_command(%q{'my foo' -a}).should == %q{'/home/bob/my path/my foo' -a}
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should quote expanded binary if found in path with spaces" do
|
63
|
+
subject.expects(:which).with('foo.sh').returns '/home/bob/my tools/foo.sh'
|
64
|
+
subject.expand_command('foo.sh /a /b').should == %q{'/home/bob/my tools/foo.sh' /a /b}
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should return nil if not found" do
|
68
|
+
subject.expects(:which).with('foo').returns nil
|
69
|
+
subject.expand_command('foo -a | stuff >> /dev/null').should be_nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#absolute_path?" do
|
74
|
+
%w[/ /foo /foo/../bar //foo //Server/Foo/Bar //?/C:/foo/bar /\Server/Foo /foo//bar/baz].each do |path|
|
75
|
+
it "should return true for #{path}" do
|
76
|
+
subject.should be_absolute_path(path)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
%w[. ./foo \foo C:/foo \\Server\Foo\Bar \\?\C:\foo\bar \/?/foo\bar \/Server/foo foo//bar/baz].each do |path|
|
81
|
+
it "should return false for #{path}" do
|
82
|
+
subject.should_not be_absolute_path(path)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Facter::Core::Execution::Windows, :as_platform => :windows do
|
4
|
+
|
5
|
+
describe "#search_paths" do
|
6
|
+
it "should use the PATH environment variable to determine locations" do
|
7
|
+
ENV.expects(:[]).with('PATH').returns 'C:\Windows;C:\Windows\System32'
|
8
|
+
subject.search_paths.should == %w{C:\Windows C:\Windows\System32}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#which" do
|
13
|
+
before :each do
|
14
|
+
subject.stubs(:search_paths).returns ['C:\Windows\system32', 'C:\Windows', 'C:\Windows\System32\Wbem' ]
|
15
|
+
ENV.stubs(:[]).with('PATHEXT').returns nil
|
16
|
+
end
|
17
|
+
|
18
|
+
context "and provided with an absolute path" do
|
19
|
+
it "should return the binary if executable" do
|
20
|
+
File.expects(:executable?).with('C:\Tools\foo.exe').returns true
|
21
|
+
File.expects(:executable?).with('\\\\remote\dir\foo.exe').returns true
|
22
|
+
subject.which('C:\Tools\foo.exe').should == 'C:\Tools\foo.exe'
|
23
|
+
subject.which('\\\\remote\dir\foo.exe').should == '\\\\remote\dir\foo.exe'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return nil if the binary is not executable" do
|
27
|
+
File.expects(:executable?).with('C:\Tools\foo.exe').returns false
|
28
|
+
File.expects(:executable?).with('\\\\remote\dir\foo.exe').returns false
|
29
|
+
subject.which('C:\Tools\foo.exe').should be_nil
|
30
|
+
subject.which('\\\\remote\dir\foo.exe').should be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "and not provided with an absolute path" do
|
35
|
+
it "should return the absolute path if found" do
|
36
|
+
File.expects(:executable?).with('C:\Windows\system32\foo.exe').returns false
|
37
|
+
File.expects(:executable?).with('C:\Windows\foo.exe').returns true
|
38
|
+
File.expects(:executable?).with('C:\Windows\System32\Wbem\foo.exe').never
|
39
|
+
subject.which('foo.exe').should == 'C:\Windows\foo.exe'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return the absolute path with file extension if found" do
|
43
|
+
['.COM', '.EXE', '.BAT', '.CMD', '' ].each do |ext|
|
44
|
+
File.stubs(:executable?).with('C:\Windows\system32\foo'+ext).returns false
|
45
|
+
File.stubs(:executable?).with('C:\Windows\System32\Wbem\foo'+ext).returns false
|
46
|
+
end
|
47
|
+
['.COM', '.BAT', '.CMD', '' ].each do |ext|
|
48
|
+
File.stubs(:executable?).with('C:\Windows\foo'+ext).returns false
|
49
|
+
end
|
50
|
+
File.stubs(:executable?).with('C:\Windows\foo.EXE').returns true
|
51
|
+
|
52
|
+
subject.which('foo').should == 'C:\Windows\foo.EXE'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return nil if not found" do
|
56
|
+
File.expects(:executable?).with('C:\Windows\system32\foo.exe').returns false
|
57
|
+
File.expects(:executable?).with('C:\Windows\foo.exe').returns false
|
58
|
+
File.expects(:executable?).with('C:\Windows\System32\Wbem\foo.exe').returns false
|
59
|
+
subject.which('foo.exe').should be_nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#expand_command" do
|
65
|
+
it "should expand binary" do
|
66
|
+
subject.expects(:which).with('cmd').returns 'C:\Windows\System32\cmd'
|
67
|
+
subject.expand_command(
|
68
|
+
'cmd /c echo foo > C:\bar'
|
69
|
+
).should == 'C:\Windows\System32\cmd /c echo foo > C:\bar'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should expand double quoted binary" do
|
73
|
+
subject.expects(:which).with('my foo').returns 'C:\My Tools\my foo.exe'
|
74
|
+
subject.expand_command('"my foo" /a /b').should == '"C:\My Tools\my foo.exe" /a /b'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not expand single quoted binary" do
|
78
|
+
subject.expects(:which).with('\'C:\My').returns nil
|
79
|
+
subject.expand_command('\'C:\My Tools\foo.exe\' /a /b').should be_nil
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should quote expanded binary if found in path with spaces" do
|
83
|
+
subject.expects(:which).with('foo').returns 'C:\My Tools\foo.exe'
|
84
|
+
subject.expand_command('foo /a /b').should == '"C:\My Tools\foo.exe" /a /b'
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return nil if not found" do
|
88
|
+
subject.expects(:which).with('foo').returns nil
|
89
|
+
subject.expand_command('foo /a | stuff >> NUL').should be_nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#absolute_path?" do
|
94
|
+
%w[C:/foo C:\foo \\\\Server\Foo\Bar \\\\?\C:\foo\bar //Server/Foo/Bar //?/C:/foo/bar /\?\C:/foo\bar \/Server\Foo/Bar c:/foo//bar//baz].each do |path|
|
95
|
+
it "should return true for #{path}" do
|
96
|
+
subject.should be_absolute_path(path)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
%w[/ . ./foo \foo /foo /foo/../bar //foo C:foo/bar foo//bar/baz].each do |path|
|
101
|
+
it "should return false for #{path}" do
|
102
|
+
subject.should_not be_absolute_path(path)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|