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.

Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/COMMITTERS.md +194 -0
  3. data/CONTRIBUTING.md +63 -235
  4. data/Gemfile +12 -8
  5. data/README.md +1 -2
  6. data/Rakefile +1 -1
  7. data/bin/facter +0 -4
  8. data/ext/build_defaults.yaml +2 -2
  9. data/ext/project_data.yaml +18 -0
  10. data/install.rb +1 -16
  11. data/lib/facter.rb +171 -171
  12. data/lib/facter/application.rb +65 -54
  13. data/lib/facter/core/aggregate.rb +220 -0
  14. data/lib/facter/core/directed_graph.rb +46 -0
  15. data/lib/facter/core/execution.rb +100 -0
  16. data/lib/facter/core/execution/base.rb +73 -0
  17. data/lib/facter/core/execution/posix.rb +50 -0
  18. data/lib/facter/core/execution/windows.rb +57 -0
  19. data/lib/facter/core/logging.rb +169 -0
  20. data/lib/facter/core/resolvable.rb +94 -0
  21. data/lib/facter/core/suitable.rb +117 -0
  22. data/lib/facter/domain.rb +15 -9
  23. data/lib/facter/filesystems.rb +1 -1
  24. data/lib/facter/hardwaremodel.rb +1 -1
  25. data/lib/facter/hostname.rb +3 -3
  26. data/lib/facter/interfaces.rb +6 -1
  27. data/lib/facter/ipaddress.rb +2 -2
  28. data/lib/facter/kernel.rb +1 -1
  29. data/lib/facter/kernelrelease.rb +1 -1
  30. data/lib/facter/ldom.rb +1 -1
  31. data/lib/facter/lsbdistcodename.rb +1 -1
  32. data/lib/facter/lsbdistdescription.rb +1 -1
  33. data/lib/facter/lsbdistid.rb +1 -1
  34. data/lib/facter/lsbdistrelease.rb +1 -1
  35. data/lib/facter/lsbrelease.rb +1 -1
  36. data/lib/facter/macaddress.rb +1 -14
  37. data/lib/facter/macosx.rb +2 -2
  38. data/lib/facter/memory.rb +8 -19
  39. data/lib/facter/operatingsystem.rb +1 -1
  40. data/lib/facter/operatingsystemrelease.rb +34 -1
  41. data/lib/facter/physicalprocessorcount.rb +6 -6
  42. data/lib/facter/processor.rb +11 -10
  43. data/lib/facter/selinux.rb +4 -15
  44. data/lib/facter/ssh.rb +5 -2
  45. data/lib/facter/util/architecture.rb +2 -2
  46. data/lib/facter/util/collection.rb +42 -38
  47. data/lib/facter/util/config.rb +19 -9
  48. data/lib/facter/util/confine.rb +34 -4
  49. data/lib/facter/util/ec2.rb +1 -1
  50. data/lib/facter/util/fact.rb +108 -36
  51. data/lib/facter/util/file_read.rb +7 -6
  52. data/lib/facter/util/formatter.rb +38 -0
  53. data/lib/facter/util/ip.rb +3 -3
  54. data/lib/facter/util/loader.rb +62 -42
  55. data/lib/facter/util/macosx.rb +7 -8
  56. data/lib/facter/util/manufacturer.rb +3 -3
  57. data/lib/facter/util/memory.rb +13 -13
  58. data/lib/facter/util/monkey_patches.rb +0 -31
  59. data/lib/facter/util/netmask.rb +3 -3
  60. data/lib/facter/util/normalization.rb +94 -0
  61. data/lib/facter/util/nothing_loader.rb +3 -6
  62. data/lib/facter/util/parser.rb +3 -5
  63. data/lib/facter/util/plist/generator.rb +1 -1
  64. data/lib/facter/util/processor.rb +15 -15
  65. data/lib/facter/util/resolution.rb +112 -289
  66. data/lib/facter/util/solaris_zones.rb +4 -4
  67. data/lib/facter/util/uptime.rb +8 -3
  68. data/lib/facter/util/values.rb +67 -1
  69. data/lib/facter/util/virtual.rb +10 -10
  70. data/lib/facter/util/xendomains.rb +1 -1
  71. data/lib/facter/version.rb +42 -39
  72. data/lib/facter/virtual.rb +6 -7
  73. data/lib/facter/zfs_version.rb +3 -3
  74. data/lib/facter/zpool_version.rb +3 -3
  75. data/spec/fixtures/unit/netmask/darwin_10_8_5.txt +30 -0
  76. data/spec/unit/application_spec.rb +46 -1
  77. data/spec/unit/core/aggregate_spec.rb +125 -0
  78. data/spec/unit/core/directed_graph_spec.rb +79 -0
  79. data/spec/unit/core/execution/base_spec.rb +119 -0
  80. data/spec/unit/core/execution/posix_spec.rb +86 -0
  81. data/spec/unit/core/execution/windows_spec.rb +106 -0
  82. data/spec/unit/core/execution_spec.rb +37 -0
  83. data/spec/unit/core/logging_spec.rb +104 -0
  84. data/spec/unit/core/resolvable_spec.rb +81 -0
  85. data/spec/unit/core/suitable_spec.rb +96 -0
  86. data/spec/unit/domain_spec.rb +5 -5
  87. data/spec/unit/facter_spec.rb +61 -222
  88. data/spec/unit/filesystems_spec.rb +2 -2
  89. data/spec/unit/hardwareisa_spec.rb +5 -5
  90. data/spec/unit/hardwaremodel_spec.rb +1 -1
  91. data/spec/unit/hostname_spec.rb +4 -4
  92. data/spec/unit/id_spec.rb +3 -3
  93. data/spec/unit/interfaces_spec.rb +10 -0
  94. data/spec/unit/ipaddress6_spec.rb +4 -4
  95. data/spec/unit/ipaddress_spec.rb +1 -1
  96. data/spec/unit/kernel_spec.rb +2 -2
  97. data/spec/unit/kernelmajversion_spec.rb +1 -1
  98. data/spec/unit/kernelrelease_spec.rb +4 -4
  99. data/spec/unit/kernelversion_spec.rb +2 -2
  100. data/spec/unit/ldom_spec.rb +2 -2
  101. data/spec/unit/lsbdistcodename_spec.rb +2 -2
  102. data/spec/unit/lsbdistdescription_spec.rb +2 -2
  103. data/spec/unit/lsbdistid_spec.rb +2 -2
  104. data/spec/unit/lsbdistrelease_spec.rb +2 -2
  105. data/spec/unit/lsbrelease_spec.rb +2 -2
  106. data/spec/unit/manufacturer_spec.rb +1 -1
  107. data/spec/unit/memory_spec.rb +24 -31
  108. data/spec/unit/netmask_spec.rb +9 -0
  109. data/spec/unit/operatingsystem_spec.rb +1 -1
  110. data/spec/unit/operatingsystemrelease_spec.rb +62 -4
  111. data/spec/unit/physicalprocessorcount_spec.rb +10 -10
  112. data/spec/unit/processor_spec.rb +11 -11
  113. data/spec/unit/selinux_spec.rb +2 -8
  114. data/spec/unit/ssh_spec.rb +3 -2
  115. data/spec/unit/uniqueid_spec.rb +3 -3
  116. data/spec/unit/util/collection_spec.rb +37 -35
  117. data/spec/unit/util/config_spec.rb +20 -0
  118. data/spec/unit/util/confine_spec.rb +21 -0
  119. data/spec/unit/util/directory_loader_spec.rb +1 -0
  120. data/spec/unit/util/ec2_spec.rb +6 -6
  121. data/spec/unit/util/fact_spec.rb +92 -90
  122. data/spec/unit/util/ip_spec.rb +2 -2
  123. data/spec/unit/util/loader_spec.rb +127 -186
  124. data/spec/unit/util/macaddress_spec.rb +2 -2
  125. data/spec/unit/util/macosx_spec.rb +8 -8
  126. data/spec/unit/util/manufacturer_spec.rb +3 -3
  127. data/spec/unit/util/normalization_spec.rb +113 -0
  128. data/spec/unit/util/parser_spec.rb +25 -3
  129. data/spec/unit/util/processor_spec.rb +2 -2
  130. data/spec/unit/util/resolution_spec.rb +60 -631
  131. data/spec/unit/util/solaris_zones_spec.rb +5 -5
  132. data/spec/unit/util/uptime_spec.rb +1 -1
  133. data/spec/unit/util/values_spec.rb +131 -0
  134. data/spec/unit/util/virtual_spec.rb +16 -16
  135. data/spec/unit/util/xendomains_spec.rb +2 -2
  136. data/spec/unit/virtual_spec.rb +39 -39
  137. data/spec/unit/zfs_version_spec.rb +11 -11
  138. data/spec/unit/zonename_spec.rb +2 -2
  139. data/spec/unit/zones_spec.rb +1 -1
  140. data/spec/unit/zpool_version_spec.rb +11 -11
  141. metadata +466 -447
  142. data/lib/facter/util/cfpropertylist.rb +0 -6
  143. data/lib/facter/util/cfpropertylist/LICENSE +0 -19
  144. data/lib/facter/util/cfpropertylist/README +0 -44
  145. data/lib/facter/util/cfpropertylist/Rakefile +0 -44
  146. data/lib/facter/util/cfpropertylist/THANKS +0 -7
  147. data/lib/facter/util/cfpropertylist/lib/cfpropertylist.rb +0 -6
  148. data/lib/facter/util/cfpropertylist/lib/rbBinaryCFPropertyList.rb +0 -562
  149. data/lib/facter/util/cfpropertylist/lib/rbCFPlistError.rb +0 -26
  150. data/lib/facter/util/cfpropertylist/lib/rbCFPropertyList.rb +0 -407
  151. data/lib/facter/util/cfpropertylist/lib/rbCFTypes.rb +0 -244
  152. data/lib/facter/util/cfpropertylist/lib/rbLibXMLParser.rb +0 -135
  153. data/lib/facter/util/cfpropertylist/lib/rbNokogiriParser.rb +0 -140
  154. data/lib/facter/util/cfpropertylist/lib/rbREXMLParser.rb +0 -136
  155. data/spec/unit/util/monkey_patches_spec.rb +0 -42
@@ -67,11 +67,11 @@ describe "Darwin", :unless => Facter::Util::Config.is_windows? do
67
67
 
68
68
  it "should warn about the lack of default" do
69
69
  Facter.expects(:warn).with("Could not find a default route. Using first non-loopback interface")
70
- Facter::Util::Macaddress::Darwin.stubs(:default_interface).returns('')
71
70
  Facter::Util::Macaddress::Darwin.macaddress
72
71
  end
73
72
 
74
73
  it "should return the macaddress of the first non-loopback interface" do
74
+ Facter.expects(:warn).with("Could not find a default route. Using first non-loopback interface")
75
75
  Facter::Util::Macaddress::Darwin.macaddress.should == fallback_macaddress
76
76
  end
77
77
  end
@@ -90,7 +90,7 @@ describe "The macaddress fact" do
90
90
  include FacterSpec::WindowsNetwork
91
91
 
92
92
  before :each do
93
- Facter.fact(:kernel).stubs(:value).returns(:windows)
93
+ Facter.fact(:kernel).stubs(:value).returns('windows')
94
94
  Facter::Util::Registry.stubs(:hklm_read).returns(nic_bindings)
95
95
  end
96
96
 
@@ -27,7 +27,7 @@ describe Facter::Util::Macosx do
27
27
  end
28
28
 
29
29
  it "should be able to retrieve profiler data as xml for a given data field" do
30
- Facter::Util::Resolution.expects(:exec).with("/usr/sbin/system_profiler -xml foo").returns "yay"
30
+ Facter::Core::Execution.expects(:exec).with("/usr/sbin/system_profiler -xml foo").returns "yay"
31
31
  Facter::Util::Macosx.profiler_xml("foo").should == "yay"
32
32
  end
33
33
 
@@ -45,7 +45,7 @@ describe Facter::Util::Macosx do
45
45
  STDERR.stubs(:<<)
46
46
  expect {
47
47
  Facter::Util::Macosx.intern_xml('<bad}|%-->xml<--->')
48
- }.to raise_error(RuntimeError, /A plist file could not be properly read by Facter::Util::CFPropertyList/)
48
+ }.to raise_error(RuntimeError, /A plist file could not be properly read by CFPropertyList/)
49
49
  end
50
50
 
51
51
  describe "when collecting profiler data" do
@@ -80,17 +80,17 @@ describe Facter::Util::Macosx do
80
80
  describe "when working out software version" do
81
81
 
82
82
  before do
83
- Facter::Util::Resolution.expects(:exec).with("/usr/bin/sw_vers -productName").returns "Mac OS X"
84
- Facter::Util::Resolution.expects(:exec).with("/usr/bin/sw_vers -buildVersion").returns "9J62"
83
+ Facter::Core::Execution.expects(:exec).with("/usr/bin/sw_vers -productName").returns "Mac OS X"
84
+ Facter::Core::Execution.expects(:exec).with("/usr/bin/sw_vers -buildVersion").returns "9J62"
85
85
  end
86
86
 
87
87
  it "should have called sw_vers three times when determining software version" do
88
- Facter::Util::Resolution.expects(:exec).with("/usr/bin/sw_vers -productVersion").returns "10.5.7"
88
+ Facter::Core::Execution.expects(:exec).with("/usr/bin/sw_vers -productVersion").returns "10.5.7"
89
89
  Facter::Util::Macosx.sw_vers
90
90
  end
91
91
 
92
92
  it "should return a hash with the correct keys when determining software version" do
93
- Facter::Util::Resolution.expects(:exec).with("/usr/bin/sw_vers -productVersion").returns "10.5.7"
93
+ Facter::Core::Execution.expects(:exec).with("/usr/bin/sw_vers -productVersion").returns "10.5.7"
94
94
  Facter::Util::Macosx.sw_vers.keys.sort.should == ["macosx_productName",
95
95
  "macosx_buildVersion",
96
96
  "macosx_productversion_minor",
@@ -99,14 +99,14 @@ describe Facter::Util::Macosx do
99
99
  end
100
100
 
101
101
  it "should split a product version of 'x.y.z' into separate hash entries correctly" do
102
- Facter::Util::Resolution.expects(:exec).with("/usr/bin/sw_vers -productVersion").returns "1.2.3"
102
+ Facter::Core::Execution.expects(:exec).with("/usr/bin/sw_vers -productVersion").returns "1.2.3"
103
103
  sw_vers = Facter::Util::Macosx.sw_vers
104
104
  sw_vers["macosx_productversion_major"].should == "1.2"
105
105
  sw_vers["macosx_productversion_minor"].should == "3"
106
106
  end
107
107
 
108
108
  it "should treat a product version of 'x.y' as 'x.y.0" do
109
- Facter::Util::Resolution.expects(:exec).with("/usr/bin/sw_vers -productVersion").returns "2.3"
109
+ Facter::Core::Execution.expects(:exec).with("/usr/bin/sw_vers -productVersion").returns "2.3"
110
110
  Facter::Util::Macosx.sw_vers["macosx_productversion_minor"].should == "0"
111
111
  end
112
112
  end
@@ -18,14 +18,14 @@ describe Facter::Manufacturer do
18
18
  end
19
19
 
20
20
  it "should parse prtdiag output on a sunfire v120" do
21
- Facter::Util::Resolution.stubs(:exec).returns(my_fixture_read("solaris_sunfire_v120_prtdiag"))
21
+ Facter::Core::Execution.stubs(:exec).returns(my_fixture_read("solaris_sunfire_v120_prtdiag"))
22
22
  Facter::Manufacturer.prtdiag_sparc_find_system_info()
23
23
  Facter.value(:manufacturer).should == "Sun Microsystems"
24
24
  Facter.value(:productname).should == "Sun Fire V120 (UltraSPARC-IIe 648MHz)"
25
25
  end
26
26
 
27
27
  it "should parse prtdiag output on a t5220" do
28
- Facter::Util::Resolution.stubs(:exec).returns(my_fixture_read("solaris_t5220_prtdiag"))
28
+ Facter::Core::Execution.stubs(:exec).returns(my_fixture_read("solaris_t5220_prtdiag"))
29
29
  Facter::Manufacturer.prtdiag_sparc_find_system_info()
30
30
  Facter.value(:manufacturer).should == "Sun Microsystems"
31
31
  Facter.value(:productname).should == "SPARC Enterprise T5220"
@@ -36,7 +36,7 @@ describe Facter::Manufacturer do
36
36
  Facter.fact(:kernel).stubs(:value).returns("SunOS")
37
37
  Facter.fact(:hardwareisa).stubs(:value).returns("sparc")
38
38
 
39
- Facter::Util::Resolution.stubs(:exec).with(regexp_matches(/prtdiag/)).returns(nil)
39
+ Facter::Core::Execution.stubs(:exec).with(regexp_matches(/prtdiag/)).returns(nil)
40
40
  Facter::Manufacturer.prtdiag_sparc_find_system_info()
41
41
  Facter.value(:manufacturer).should_not == "Sun Microsystems"
42
42
  end
@@ -0,0 +1,113 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'facter/util/normalization'
5
+
6
+ describe Facter::Util::Normalization do
7
+
8
+ subject { described_class }
9
+
10
+ def utf16(str)
11
+ if String.method_defined?(:encode) && defined?(::Encoding)
12
+ str.encode(Encoding::UTF_16LE)
13
+ else
14
+ str
15
+ end
16
+ end
17
+
18
+ def utf8(str)
19
+ if String.method_defined?(:encode) && defined?(::Encoding)
20
+ str.encode(Encoding::UTF_8)
21
+ else
22
+ str
23
+ end
24
+ end
25
+
26
+ describe "validating strings" do
27
+ describe "and string encoding is supported", :if => String.instance_methods.include?(:encoding) do
28
+ it "accepts strings that are ASCII and match their encoding and converts them to UTF-8" do
29
+ str = "ASCII".encode(Encoding::ASCII)
30
+ normalized_str = subject.normalize(str)
31
+ expect(normalized_str.encoding).to eq(Encoding::UTF_8)
32
+ end
33
+
34
+ it "accepts strings that are UTF-8 and match their encoding" do
35
+ str = "let's make a ☃!".encode(Encoding::UTF_8)
36
+ expect(subject.normalize(str)).to eq(str)
37
+ end
38
+
39
+ it "converts valid non UTF-8 strings to UTF-8" do
40
+ str = "let's make a ☃!".encode(Encoding::UTF_16LE)
41
+ enc = subject.normalize(str).encoding
42
+ expect(enc).to eq(Encoding::UTF_8)
43
+ end
44
+
45
+ it "normalizes a frozen string returning a non-frozen string" do
46
+ str = "factvalue".encode(Encoding::UTF_16LE).freeze
47
+ normalized_str = subject.normalize(str)
48
+ expect(normalized_str.encoding).to eq(Encoding::UTF_8)
49
+ expect(normalized_str).to_not be_frozen
50
+ end
51
+
52
+ it "rejects strings that are not UTF-8 and do not match their claimed encoding" do
53
+ invalid_shift_jis = "\xFF\x5C!".force_encoding(Encoding::SHIFT_JIS)
54
+ expect {
55
+ subject.normalize(invalid_shift_jis)
56
+ }.to raise_error(Facter::Util::Normalization::NormalizationError, /String encoding Shift_JIS is not UTF-8 and could not be converted to UTF-8/)
57
+ end
58
+
59
+ it "rejects strings that claim to be UTF-8 encoded but aren't" do
60
+ str = "\255ay!".force_encoding(Encoding::UTF_8)
61
+ expect {
62
+ subject.normalize(str)
63
+ }.to raise_error(Facter::Util::Normalization::NormalizationError, /String.*doesn't match the reported encoding UTF-8/)
64
+ end
65
+ end
66
+
67
+ describe "and string encoding is not supported", :unless => String.instance_methods.include?(:encoding) do
68
+ it "accepts strings that are UTF-8 and match their encoding" do
69
+ str = "let's make a ☃!"
70
+ expect(subject.normalize(str)).to eq(str)
71
+ end
72
+
73
+ it "rejects strings that are not UTF-8" do
74
+ str = "let's make a \255\255\255!"
75
+ expect {
76
+ subject.normalize(str)
77
+ }.to raise_error(Facter::Util::Normalization::NormalizationError, /String .* is not valid UTF-8/)
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "normalizing arrays" do
83
+ it "normalizes each element in the array" do
84
+ arr = [utf16('first'), utf16('second'), [utf16('third'), utf16('fourth')]]
85
+ expected_arr = [utf8('first'), utf8('second'), [utf8('third'), utf8('fourth')]]
86
+
87
+ expect(subject.normalize_array(arr)).to eq(expected_arr)
88
+ end
89
+ end
90
+
91
+ describe "normalizing hashes" do
92
+ it "normalizes each element in the array" do
93
+ hsh = {utf16('first') => utf16('second'), utf16('third') => [utf16('fourth'), utf16('fifth')]}
94
+ expected_hsh = {utf8('first') => utf8('second'), utf8('third') => [utf8('fourth'), utf8('fifth')]}
95
+
96
+ expect(subject.normalize_hash(hsh)).to eq(expected_hsh)
97
+ end
98
+ end
99
+
100
+ [1, 1.0, true, false, nil].each do |val|
101
+ it "accepts #{val.inspect}:#{val.class}" do
102
+ expect(subject.normalize(val)).to eq(val)
103
+ end
104
+ end
105
+
106
+ [:sym, Object.new, Set.new].each do |val|
107
+ it "rejects #{val.inspect}:#{val.class}" do
108
+ expect {
109
+ subject.normalize(val)
110
+ }.to raise_error(Facter::Util::Normalization::NormalizationError, /Expected .*but was #{val.class}/ )
111
+ end
112
+ end
113
+ end
@@ -95,7 +95,7 @@ describe Facter::Util::Parser do
95
95
  let(:data_in_txt) { "one=two\nthree=four\n" }
96
96
 
97
97
  def expects_script_to_return(path, content, result)
98
- Facter::Util::Resolution.stubs(:exec).with(path).returns(content)
98
+ Facter::Core::Execution.stubs(:exec).with(path).returns(content)
99
99
  File.stubs(:executable?).with(path).returns(true)
100
100
  File.stubs(:file?).with(path).returns(true)
101
101
 
@@ -123,7 +123,7 @@ describe Facter::Util::Parser do
123
123
  it "quotes scripts with spaces" do
124
124
  path = "/h a s s p a c e s#{ext}"
125
125
 
126
- Facter::Util::Resolution.expects(:exec).with("\"#{path}\"").returns(data_in_txt)
126
+ Facter::Core::Execution.expects(:exec).with("\"#{path}\"").returns(data_in_txt)
127
127
 
128
128
  expects_script_to_return(path, data_in_txt, data)
129
129
  end
@@ -149,12 +149,34 @@ describe Facter::Util::Parser do
149
149
  end
150
150
  end
151
151
 
152
+ context "exe, bat, cmd, and com files" do
153
+ let :cmds do ["/tmp/foo.bat", "/tmp/foo.cmd", "/tmp/foo.exe", "/tmp/foo.com"] end
154
+
155
+ before :each do
156
+ cmds.each {|cmd|
157
+ File.stubs(:executable?).with(cmd).returns(true)
158
+ File.stubs(:file?).with(cmd).returns(true)
159
+ }
160
+ end
161
+
162
+ it "should return nothing parser if not on windows" do
163
+ Facter::Util::Config.stubs(:is_windows?).returns(false)
164
+ cmds.each {|cmd| Facter::Util::Parser.parser_for(cmd).should be_an_instance_of(Facter::Util::Parser::NothingParser) }
165
+ end
166
+
167
+ it "should return script parser if on windows" do
168
+ Facter::Util::Config.stubs(:is_windows?).returns(true)
169
+ cmds.each {|cmd| Facter::Util::Parser.parser_for(cmd).should be_an_instance_of(Facter::Util::Parser::ScriptParser) }
170
+ end
171
+
172
+ end
173
+
152
174
  describe "powershell parser" do
153
175
  let(:ps1) { "/tmp/foo.ps1" }
154
176
 
155
177
  def expects_to_parse_powershell(cmd, content, result)
156
178
  Facter::Util::Config.stubs(:is_windows?).returns(true)
157
- Facter::Util::Resolution.stubs(:exec).returns(content)
179
+ Facter::Core::Execution.stubs(:exec).returns(content)
158
180
  File.stubs(:file?).with(ps1).returns(true)
159
181
 
160
182
  Facter::Util::Parser.parser_for(cmd).results.should == result
@@ -70,14 +70,14 @@ describe Facter::Util::Processor do
70
70
 
71
71
  it "should get the processor description on Solaris (x86)" do
72
72
  Facter.fact(:architecture).stubs(:value).returns("i86pc")
73
- Facter::Util::Resolution.stubs(:exec).with("/usr/bin/kstat cpu_info").returns(my_fixture_read("solaris-i86pc"))
73
+ Facter::Core::Execution.stubs(:exec).with("/usr/bin/kstat cpu_info").returns(my_fixture_read("solaris-i86pc"))
74
74
 
75
75
  Facter::Util::Processor.enum_kstat[0].should == "Intel(r) Core(tm) i5 CPU M 450 @ 2.40GHz"
76
76
  end
77
77
 
78
78
  it "should get the processor description on Solaris (SPARC64)" do
79
79
  Facter.fact(:architecture).stubs(:value).returns("sun4u")
80
- Facter::Util::Resolution.stubs(:exec).with("/usr/bin/kstat cpu_info").returns(my_fixture_read("solaris-sun4u"))
80
+ Facter::Core::Execution.stubs(:exec).with("/usr/bin/kstat cpu_info").returns(my_fixture_read("solaris-sun4u"))
81
81
 
82
82
  Facter::Util::Processor.enum_kstat[0].should == "SPARC64-VII"
83
83
  Facter::Util::Processor.enum_kstat[1].should == "SPARC64-VII"
@@ -6,695 +6,124 @@ require 'facter/util/resolution'
6
6
  describe Facter::Util::Resolution do
7
7
  include FacterSpec::ConfigHelper
8
8
 
9
- it "should require a name" do
10
- lambda { Facter::Util::Resolution.new }.should raise_error(ArgumentError)
11
- end
12
-
13
- it "should have a name" do
14
- Facter::Util::Resolution.new("yay").name.should == "yay"
15
- end
9
+ subject(:resolution) { described_class.new(:foo, stub_fact) }
16
10
 
17
- it "should be able to set the value" do
18
- resolve = Facter::Util::Resolution.new("yay")
19
- resolve.value = "foo"
20
- resolve.value.should == "foo"
21
- end
22
-
23
- it "should have a method for setting the weight" do
24
- Facter::Util::Resolution.new("yay").should respond_to(:has_weight)
25
- end
11
+ let(:stub_fact) { stub('fact', :name => :stubfact) }
26
12
 
27
- it "should have a method for setting the code" do
28
- Facter::Util::Resolution.new("yay").should respond_to(:setcode)
13
+ it "requires a name" do
14
+ expect { Facter::Util::Resolution.new }.to raise_error(ArgumentError)
29
15
  end
30
16
 
31
- it "should support a timeout value" do
32
- Facter::Util::Resolution.new("yay").should respond_to(:timeout=)
17
+ it "requires a fact" do
18
+ expect { Facter::Util::Resolution.new('yay') }.to raise_error(ArgumentError)
33
19
  end
34
20
 
35
- it "should default to a timeout of 0 seconds" do
36
- Facter::Util::Resolution.new("yay").limit.should == 0
21
+ it "can return its name" do
22
+ expect(resolution.name).to eq :foo
37
23
  end
38
24
 
39
- it "should default to nil for code" do
40
- Facter::Util::Resolution.new("yay").code.should be_nil
25
+ it "can explicitly set a value" do
26
+ resolution.value = "foo"
27
+ expect(resolution.value).to eq "foo"
41
28
  end
42
29
 
43
- it "should default to nil for interpreter" do
44
- Facter.expects(:warnonce).with("The 'Facter::Util::Resolution.interpreter' method is deprecated and will be removed in a future version.")
45
- Facter::Util::Resolution.new("yay").interpreter.should be_nil
46
- end
47
-
48
- it "should provide a 'limit' method that returns the timeout" do
49
- res = Facter::Util::Resolution.new("yay")
50
- res.timeout = "testing"
51
- res.limit.should == "testing"
52
- end
53
-
54
-
55
- describe "when overriding environment variables" do
56
- it "should execute the caller's block with the specified env vars" do
57
- test_env = { "LANG" => "C", "FOO" => "BAR" }
58
- Facter::Util::Resolution.with_env test_env do
59
- test_env.keys.each do |key|
60
- ENV[key].should == test_env[key]
61
- end
62
- end
63
- end
64
-
65
- it "should restore pre-existing environment variables to their previous values" do
66
- orig_env = {}
67
- new_env = {}
68
- # an arbitrary sentinel value to use to temporarily set the environment vars to
69
- sentinel_value = "Abracadabra"
70
-
71
- # grab some values from the existing ENV (arbitrarily choosing 3 here)
72
- ENV.keys.first(3).each do |key|
73
- # save the original values so that we can test against them later
74
- orig_env[key] = ENV[key]
75
- # create bogus temp values for the chosen keys
76
- new_env[key] = sentinel_value
77
- end
78
-
79
- # verify that, during the 'with_env', the new values are used
80
- Facter::Util::Resolution.with_env new_env do
81
- orig_env.keys.each do |key|
82
- ENV[key].should == new_env[key]
83
- end
84
- end
85
-
86
- # verify that, after the 'with_env', the old values are restored
87
- orig_env.keys.each do |key|
88
- ENV[key].should == orig_env[key]
89
- end
90
- end
91
-
92
- it "should not be affected by a 'return' statement in the yield block" do
93
- @sentinel_var = :resolution_test_foo.to_s
94
-
95
- # the intent of this test case is to test a yield block that contains a return statement. However, it's illegal
96
- # to use a return statement outside of a method, so we need to create one here to give scope to the 'return'
97
- def handy_method()
98
- ENV[@sentinel_var] = "foo"
99
- new_env = { @sentinel_var => "bar" }
100
-
101
- Facter::Util::Resolution.with_env new_env do
102
- ENV[@sentinel_var].should == "bar"
103
- return
104
- end
105
- end
106
-
107
- handy_method()
108
-
109
- ENV[@sentinel_var].should == "foo"
110
-
111
- end
30
+ it "defaults to nil for code" do
31
+ expect(resolution.code).to be_nil
112
32
  end
113
33
 
114
34
  describe "when setting the code" do
115
35
  before do
116
36
  Facter.stubs(:warnonce)
117
- @resolve = Facter::Util::Resolution.new("yay")
118
- end
119
-
120
- it "should deprecate the interpreter argument to 'setcode'" do
121
- Facter.expects(:warnonce).with("The interpreter parameter to 'setcode' is deprecated and will be removed in a future version.")
122
- @resolve.setcode "foo", "bar"
123
- @resolve.interpreter.should == "bar"
124
- end
125
-
126
- it "should deprecate the interpreter= method" do
127
- Facter.expects(:warnonce).with("The 'Facter::Util::Resolution.interpreter=' method is deprecated and will be removed in a future version.")
128
- @resolve.interpreter = "baz"
129
- @resolve.interpreter.should == "baz"
130
37
  end
131
38
 
132
- it "should deprecate the interpreter method" do
133
- Facter.expects(:warnonce).with("The 'Facter::Util::Resolution.interpreter' method is deprecated and will be removed in a future version.")
134
- @resolve.interpreter
39
+ it "creates a block when given a command" do
40
+ resolution.setcode "foo"
41
+ expect(resolution.code).to be_a_kind_of Proc
135
42
  end
136
43
 
137
- it "should set the code to any provided string" do
138
- @resolve.setcode "foo"
139
- @resolve.code.should == "foo"
140
- end
141
-
142
- it "should set the code to any provided block" do
44
+ it "stores the provided block when given a block" do
143
45
  block = lambda { }
144
- @resolve.setcode(&block)
145
- @resolve.code.should equal(block)
146
- end
147
-
148
- it "should prefer the string over a block" do
149
- @resolve.setcode("foo") { }
150
- @resolve.code.should == "foo"
46
+ resolution.setcode(&block)
47
+ resolution.code.should equal(block)
151
48
  end
152
49
 
153
- it "should fail if neither a string nor block has been provided" do
154
- lambda { @resolve.setcode }.should raise_error(ArgumentError)
155
- end
156
- end
157
50
 
158
- describe 'callbacks when flushing facts' do
159
- class FlushFakeError < StandardError; end
160
-
161
- subject do
162
- Facter::Util::Resolution.new("jeff")
163
- end
164
-
165
- context '#on_flush' do
166
- it 'accepts a block with on_flush' do
167
- subject.on_flush() { raise NotImplementedError }
168
- end
51
+ it "prefers a command over a block" do
52
+ block = lambda { }
53
+ resolution.setcode("foo", &block)
54
+ expect(resolution.code).to_not eq block
169
55
  end
170
56
 
171
- context '#flush' do
172
- it 'calls the block passed to on_flush' do
173
- subject.on_flush() { raise FlushFakeError }
174
- expect { subject.flush }.to raise_error FlushFakeError
175
- end
57
+ it "fails if neither a string nor block has been provided" do
58
+ expect { resolution.setcode }.to raise_error(ArgumentError)
176
59
  end
177
60
  end
178
61
 
179
- it "should be able to return a value" do
180
- Facter::Util::Resolution.new("yay").should respond_to(:value)
181
- end
182
-
183
62
  describe "when returning the value" do
184
- before do
185
- @resolve = Facter::Util::Resolution.new("yay")
186
- end
187
-
188
- it "should return any value that has been provided" do
189
- @resolve.value = "foo"
190
- @resolve.value.should == "foo"
63
+ it "returns any value that has been provided" do
64
+ resolution.value = "foo"
65
+ expect(resolution.value).to eq "foo"
191
66
  end
192
67
 
193
68
  describe "and setcode has not been called" do
194
- it "should return nil" do
195
- Facter::Util::Resolution.expects(:exec).with(nil, nil).never
196
- @resolve.value.should be_nil
69
+ it "returns nil" do
70
+ expect(resolution.value).to be_nil
197
71
  end
198
72
  end
199
73
 
200
74
  describe "and the code is a string" do
201
- describe "on windows" do
202
- before do
203
- given_a_configuration_of(:is_windows => true)
204
- end
205
-
206
- it "should return the result of executing the code" do
207
- @resolve.setcode "/bin/foo"
208
- Facter::Util::Resolution.expects(:exec).once.with("/bin/foo").returns "yup"
209
-
210
- @resolve.value.should == "yup"
211
- end
212
-
213
- it "should return nil if the value is an empty string" do
214
- @resolve.setcode "/bin/foo"
215
- Facter::Util::Resolution.expects(:exec).once.returns ""
216
- @resolve.value.should be_nil
217
- end
218
- end
219
-
220
- describe "on non-windows systems" do
221
- before do
222
- given_a_configuration_of(:is_windows => false)
223
- end
75
+ it "returns the result of executing the code" do
76
+ resolution.setcode "/bin/foo"
77
+ Facter::Core::Execution.expects(:exec).once.with("/bin/foo").returns "yup"
224
78
 
225
- it "should return the result of executing the code" do
226
- @resolve.setcode "/bin/foo"
227
- Facter::Util::Resolution.expects(:exec).once.with("/bin/foo").returns "yup"
228
-
229
- @resolve.value.should == "yup"
230
- end
231
-
232
- it "should return nil if the value is an empty string" do
233
- @resolve.setcode "/bin/foo"
234
- Facter::Util::Resolution.expects(:exec).once.returns ""
235
- @resolve.value.should be_nil
236
- end
79
+ expect(resolution.value).to eq "yup"
237
80
  end
238
81
  end
239
82
 
240
83
  describe "and the code is a block" do
241
- it "should warn but not fail if the code fails" do
242
- @resolve.setcode { raise "feh" }
243
- Facter.expects(:warn)
244
- @resolve.value.should be_nil
245
- end
246
-
247
- it "should return the value returned by the block" do
248
- @resolve.setcode { "yayness" }
249
- @resolve.value.should == "yayness"
250
- end
251
-
252
- it "should return nil if the value is an empty string" do
253
- @resolve.setcode { "" }
254
- @resolve.value.should be_nil
255
- end
256
-
257
- it "should return nil if the value is an empty block" do
258
- @resolve.setcode { "" }
259
- @resolve.value.should be_nil
260
- end
261
-
262
- it "should use its limit method to determine the timeout, to avoid conflict when a 'timeout' method exists for some other reason" do
263
- @resolve.expects(:timeout).never
264
- @resolve.expects(:limit).returns "foo"
265
- Timeout.expects(:timeout).with("foo")
266
-
267
- @resolve.setcode { sleep 2; "raise This is a test"}
268
- @resolve.value
269
- end
270
-
271
- it "should timeout after the provided timeout" do
272
- Facter.expects(:warn)
273
- @resolve.timeout = 0.1
274
- @resolve.setcode { sleep 2; raise "This is a test" }
275
- Thread.expects(:new).yields
276
-
277
- @resolve.value.should be_nil
278
- end
279
-
280
- it "should waitall to avoid zombies if the timeout is exceeded" do
281
- Facter.stubs(:warn)
282
- @resolve.timeout = 0.1
283
- @resolve.setcode { sleep 2; raise "This is a test" }
284
-
285
- Thread.expects(:new).yields
286
- Process.expects(:waitall)
287
-
288
- @resolve.value
289
- end
290
- end
291
- end
292
-
293
- it "should return its value when converted to a string" do
294
- @resolve = Facter::Util::Resolution.new("yay")
295
- @resolve.expects(:value).returns "myval"
296
- @resolve.to_s.should == "myval"
297
- end
298
-
299
- it "should allow the adding of confines" do
300
- Facter::Util::Resolution.new("yay").should respond_to(:confine)
301
- end
302
-
303
- it "should provide a method for returning the number of confines" do
304
- @resolve = Facter::Util::Resolution.new("yay")
305
- @resolve.confine "one" => "foo", "two" => "fee"
306
- @resolve.weight.should == 2
307
- end
308
-
309
- it "should return 0 confines when no confines have been added" do
310
- Facter::Util::Resolution.new("yay").weight.should == 0
311
- end
312
-
313
- it "should provide a way to set the weight" do
314
- @resolve = Facter::Util::Resolution.new("yay")
315
- @resolve.has_weight(45)
316
- @resolve.weight.should == 45
317
- end
318
-
319
- it "should allow the weight to override the number of confines" do
320
- @resolve = Facter::Util::Resolution.new("yay")
321
- @resolve.confine "one" => "foo", "two" => "fee"
322
- @resolve.weight.should == 2
323
- @resolve.has_weight(45)
324
- @resolve.weight.should == 45
325
- end
326
-
327
- it "should have a method for determining if it is suitable" do
328
- Facter::Util::Resolution.new("yay").should respond_to(:suitable?)
329
- end
330
-
331
- describe "when adding confines" do
332
- before do
333
- @resolve = Facter::Util::Resolution.new("yay")
334
- end
335
-
336
- it "should accept a hash of fact names and values" do
337
- lambda { @resolve.confine :one => "two" }.should_not raise_error
338
- end
339
-
340
- it "should create a Util::Confine instance for every argument in the provided hash" do
341
- Facter::Util::Confine.expects(:new).with("one", "foo")
342
- Facter::Util::Confine.expects(:new).with("two", "fee")
343
-
344
- @resolve.confine "one" => "foo", "two" => "fee"
345
- end
346
-
347
- end
348
-
349
- describe "when determining suitability" do
350
- before do
351
- @resolve = Facter::Util::Resolution.new("yay")
352
- end
353
-
354
- it "should always be suitable if no confines have been added" do
355
- @resolve.should be_suitable
356
- end
357
-
358
- it "should be unsuitable if any provided confines return false" do
359
- confine1 = mock 'confine1', :true? => true
360
- confine2 = mock 'confine2', :true? => false
361
- Facter::Util::Confine.expects(:new).times(2).returns(confine1).then.returns(confine2)
362
- @resolve.confine :one => :two, :three => :four
363
-
364
- @resolve.should_not be_suitable
365
- end
366
-
367
- it "should be suitable if all provided confines return true" do
368
- confine1 = mock 'confine1', :true? => true
369
- confine2 = mock 'confine2', :true? => true
370
- Facter::Util::Confine.expects(:new).times(2).returns(confine1).then.returns(confine2)
371
- @resolve.confine :one => :two, :three => :four
372
-
373
- @resolve.should be_suitable
374
- end
375
- end
376
-
377
- it "should have a class method for executing code" do
378
- Facter::Util::Resolution.should respond_to(:exec)
379
- end
380
-
381
- # taken from puppet: spec/unit/util_spec.rb
382
- describe "#absolute_path?" do
383
- context "when run on unix", :as_platform => :posix do
384
- %w[/ /foo /foo/../bar //foo //Server/Foo/Bar //?/C:/foo/bar /\Server/Foo /foo//bar/baz].each do |path|
385
- it "should return true for #{path}" do
386
- Facter::Util::Resolution.should be_absolute_path(path)
387
- end
388
- end
389
-
390
- %w[. ./foo \foo C:/foo \\Server\Foo\Bar \\?\C:\foo\bar \/?/foo\bar \/Server/foo foo//bar/baz].each do |path|
391
- it "should return false for #{path}" do
392
- Facter::Util::Resolution.should_not be_absolute_path(path)
393
- end
394
- end
395
- end
396
-
397
- context "when run on windows", :as_platform => :windows do
398
- %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|
399
- it "should return true for #{path}" do
400
- Facter::Util::Resolution.should be_absolute_path(path)
401
- end
402
- end
403
-
404
- %w[/ . ./foo \foo /foo /foo/../bar //foo C:foo/bar foo//bar/baz].each do |path|
405
- it "should return false for #{path}" do
406
- Facter::Util::Resolution.should_not be_absolute_path(path)
407
- end
84
+ it "returns the value returned by the block" do
85
+ resolution.setcode { "yayness" }
86
+ expect(resolution.value).to eq "yayness"
408
87
  end
409
88
  end
410
89
  end
411
90
 
412
- describe "#search_paths" do
413
- context "on windows", :as_platform => :windows do
414
- it "should use the PATH environment variable to determine locations" do
415
- ENV.expects(:[]).with('PATH').returns 'C:\Windows;C:\Windows\System32'
416
- Facter::Util::Resolution.search_paths.should == %w{C:\Windows C:\Windows\System32}
417
- end
418
- end
419
-
420
- context "on posix", :as_platform => :posix do
421
- it "should use the PATH environment variable plus /sbin and /usr/sbin on unix" do
422
- ENV.expects(:[]).with('PATH').returns "/bin:/usr/bin"
423
- Facter::Util::Resolution.search_paths.should == %w{/bin /usr/bin /sbin /usr/sbin}
424
- end
91
+ describe "setting options" do
92
+ it "can set the value" do
93
+ resolution.set_options(:value => 'something')
94
+ expect(resolution.value).to eq 'something'
425
95
  end
426
- end
427
-
428
- describe "#which" do
429
- context "when run on posix", :as_platform => :posix do
430
- before :each do
431
- Facter::Util::Resolution.stubs(:search_paths).returns [ '/bin', '/sbin', '/usr/sbin']
432
- end
433
-
434
- context "and provided with an absolute path" do
435
- it "should return the binary if executable" do
436
- File.expects(:executable?).with('/opt/foo').returns true
437
- Facter::Util::Resolution.which('/opt/foo').should == '/opt/foo'
438
- end
439
-
440
- it "should return nil if the binary is not executable" do
441
- File.expects(:executable?).with('/opt/foo').returns false
442
- Facter::Util::Resolution.which('/opt/foo').should be_nil
443
- end
444
- end
445
96
 
446
- context "and not provided with an absolute path" do
447
- it "should return the absolute path if found" do
448
- File.expects(:executable?).with('/bin/foo').returns false
449
- File.expects(:executable?).with('/sbin/foo').returns true
450
- File.expects(:executable?).with('/usr/sbin/foo').never
451
- Facter::Util::Resolution.which('foo').should == '/sbin/foo'
452
- end
453
-
454
- it "should return nil if not found" do
455
- File.expects(:executable?).with('/bin/foo').returns false
456
- File.expects(:executable?).with('/sbin/foo').returns false
457
- File.expects(:executable?).with('/usr/sbin/foo').returns false
458
- Facter::Util::Resolution.which('foo').should be_nil
459
- end
460
- end
97
+ it "can set the timeout" do
98
+ resolution.set_options(:timeout => 314)
99
+ expect(resolution.limit).to eq 314
461
100
  end
462
101
 
463
- context "when run on windows", :as_platform => :windows do
464
- before :each do
465
- Facter::Util::Resolution.stubs(:search_paths).returns ['C:\Windows\system32', 'C:\Windows', 'C:\Windows\System32\Wbem' ]
466
- ENV.stubs(:[]).with('PATHEXT').returns nil
467
- end
468
-
469
- context "and provided with an absolute path" do
470
- it "should return the binary if executable" do
471
- File.expects(:executable?).with('C:\Tools\foo.exe').returns true
472
- File.expects(:executable?).with('\\\\remote\dir\foo.exe').returns true
473
- Facter::Util::Resolution.which('C:\Tools\foo.exe').should == 'C:\Tools\foo.exe'
474
- Facter::Util::Resolution.which('\\\\remote\dir\foo.exe').should == '\\\\remote\dir\foo.exe'
475
- end
476
-
477
- it "should return the binary with added extension if executable" do
478
- ['.COM', '.BAT', '.CMD', '' ].each do |ext|
479
- File.stubs(:executable?).with('C:\Windows\system32\netsh'+ext).returns false
480
- end
481
- File.expects(:executable?).with('C:\Windows\system32\netsh.EXE').returns true
482
-
483
- Facter.expects(:warnonce).with('Using Facter::Util::Resolution.which with an absolute path like C:\\Windows\\system32\\netsh but no fileextension is deprecated. Please add the correct extension (.EXE)')
484
- Facter::Util::Resolution.which('C:\Windows\system32\netsh').should == 'C:\Windows\system32\netsh.EXE'
485
- end
486
-
487
- it "should return nil if the binary is not executable" do
488
- File.expects(:executable?).with('C:\Tools\foo.exe').returns false
489
- File.expects(:executable?).with('\\\\remote\dir\foo.exe').returns false
490
- Facter::Util::Resolution.which('C:\Tools\foo.exe').should be_nil
491
- Facter::Util::Resolution.which('\\\\remote\dir\foo.exe').should be_nil
492
- end
493
- end
494
-
495
- context "and not provided with an absolute path" do
496
- it "should return the absolute path if found" do
497
- File.expects(:executable?).with('C:\Windows\system32\foo.exe').returns false
498
- File.expects(:executable?).with('C:\Windows\foo.exe').returns true
499
- File.expects(:executable?).with('C:\Windows\System32\Wbem\foo.exe').never
500
- Facter::Util::Resolution.which('foo.exe').should == 'C:\Windows\foo.exe'
501
- end
502
-
503
- it "should return the absolute path with file extension if found" do
504
- ['.COM', '.EXE', '.BAT', '.CMD', '' ].each do |ext|
505
- File.stubs(:executable?).with('C:\Windows\system32\foo'+ext).returns false
506
- File.stubs(:executable?).with('C:\Windows\System32\Wbem\foo'+ext).returns false
507
- end
508
- ['.COM', '.BAT', '.CMD', '' ].each do |ext|
509
- File.stubs(:executable?).with('C:\Windows\foo'+ext).returns false
510
- end
511
- File.stubs(:executable?).with('C:\Windows\foo.EXE').returns true
512
-
513
- Facter::Util::Resolution.which('foo').should == 'C:\Windows\foo.EXE'
514
- end
515
-
516
- it "should return nil if not found" do
517
- File.expects(:executable?).with('C:\Windows\system32\foo.exe').returns false
518
- File.expects(:executable?).with('C:\Windows\foo.exe').returns false
519
- File.expects(:executable?).with('C:\Windows\System32\Wbem\foo.exe').returns false
520
- Facter::Util::Resolution.which('foo.exe').should be_nil
521
- end
522
- end
102
+ it "can set the weight" do
103
+ resolution.set_options(:weight => 27)
104
+ expect(resolution.weight).to eq 27
523
105
  end
524
106
 
525
- describe "#expand_command" do
526
- context "on windows", :as_platform => :windows do
527
- it "should expand binary" do
528
- Facter::Util::Resolution.expects(:which).with('cmd').returns 'C:\Windows\System32\cmd'
529
- Facter::Util::Resolution.expand_command(
530
- 'cmd /c echo foo > C:\bar'
531
- ).should == 'C:\Windows\System32\cmd /c echo foo > C:\bar'
532
- end
533
-
534
- it "should expand double quoted binary" do
535
- Facter::Util::Resolution.expects(:which).with('my foo').returns 'C:\My Tools\my foo.exe'
536
- Facter::Util::Resolution.expand_command('"my foo" /a /b').should == '"C:\My Tools\my foo.exe" /a /b'
537
- end
538
-
539
- it "should not expand single quoted binary" do
540
- Facter::Util::Resolution.expects(:which).with('\'C:\My').returns nil
541
- Facter::Util::Resolution.expand_command('\'C:\My Tools\foo.exe\' /a /b').should be_nil
542
- end
543
-
544
- it "should quote expanded binary if found in path with spaces" do
545
- Facter::Util::Resolution.expects(:which).with('foo').returns 'C:\My Tools\foo.exe'
546
- Facter::Util::Resolution.expand_command('foo /a /b').should == '"C:\My Tools\foo.exe" /a /b'
547
- end
548
-
549
- it "should return nil if not found" do
550
- Facter::Util::Resolution.expects(:which).with('foo').returns nil
551
- Facter::Util::Resolution.expand_command('foo /a | stuff >> /dev/null').should be_nil
552
- end
553
- end
554
-
555
- context "on unix", :as_platform => :posix do
556
- it "should expand binary" do
557
- Facter::Util::Resolution.expects(:which).with('foo').returns '/bin/foo'
558
- Facter::Util::Resolution.expand_command('foo -a | stuff >> /dev/null').should == '/bin/foo -a | stuff >> /dev/null'
559
- end
560
-
561
- it "should expand double quoted binary" do
562
- Facter::Util::Resolution.expects(:which).with('/tmp/my foo').returns '/tmp/my foo'
563
- Facter::Util::Resolution.expand_command(%q{"/tmp/my foo" bar}).should == %q{"/tmp/my foo" bar}
564
- end
565
-
566
- it "should expand single quoted binary" do
567
- Facter::Util::Resolution.expects(:which).with('my foo').returns '/home/bob/my path/my foo'
568
- Facter::Util::Resolution.expand_command(%q{'my foo' -a}).should == %q{'/home/bob/my path/my foo' -a}
569
- end
570
-
571
- it "should quote expanded binary if found in path with spaces" do
572
- Facter::Util::Resolution.expects(:which).with('foo.sh').returns '/home/bob/my tools/foo.sh'
573
- Facter::Util::Resolution.expand_command('foo.sh /a /b').should == %q{'/home/bob/my tools/foo.sh' /a /b}
574
- end
575
-
576
- it "should return nil if not found" do
577
- Facter::Util::Resolution.expects(:which).with('foo').returns nil
578
- Facter::Util::Resolution.expand_command('foo -a | stuff >> /dev/null').should be_nil
579
- end
580
- end
107
+ it "fails on unhandled options" do
108
+ expect do
109
+ resolution.set_options(:foo => 'bar')
110
+ end.to raise_error(ArgumentError, /Invalid resolution options.*foo/)
581
111
  end
582
-
583
112
  end
584
113
 
585
- # It's not possible, AFAICT, to mock %x{}, so I can't really test this bit.
586
- describe "when executing code" do
587
- # set up some command strings, making sure we get the right version for both unix and windows
588
- echo_command = Facter::Util::Config.is_windows? ? 'cmd.exe /c "echo foo"' : 'echo foo'
589
- echo_env_var_command = Facter::Util::Config.is_windows? ? 'cmd.exe /c "echo %%%s%%"' : 'echo $%s'
590
-
591
- it "should deprecate the interpreter parameter" do
592
- Facter.expects(:warnonce).with("The interpreter parameter to 'exec' is deprecated and will be removed in a future version.")
593
- Facter::Util::Resolution.exec("/something", "/bin/perl")
594
- end
595
-
596
- # execute a simple echo command
597
- it "should execute the binary" do
598
- Facter::Util::Resolution.exec(echo_command).should == "foo"
599
- end
600
-
601
- it "should override the LANG environment variable" do
602
- Facter::Util::Resolution.exec(echo_env_var_command % 'LANG').should == "C"
603
- end
604
-
605
- it "should respect other overridden environment variables" do
606
- Facter::Util::Resolution.with_env( {"FOO" => "foo"} ) do
607
- Facter::Util::Resolution.exec(echo_env_var_command % 'FOO').should == "foo"
608
- end
609
- end
610
-
611
- it "should restore overridden LANG environment variable after execution" do
612
- # we're going to call with_env in a nested fashion, to make sure that the environment gets restored properly
613
- # at each level
614
- Facter::Util::Resolution.with_env( {"LANG" => "foo"} ) do
615
- # Resolution.exec always overrides 'LANG' for its own execution scope
616
- Facter::Util::Resolution.exec(echo_env_var_command % 'LANG').should == "C"
617
- # But after 'exec' completes, we should see our value restored
618
- ENV['LANG'].should == "foo"
619
- # Now we'll do a nested call to with_env
620
- Facter::Util::Resolution.with_env( {"LANG" => "bar"} ) do
621
- # During 'exec' it should still be 'C'
622
- Facter::Util::Resolution.exec(echo_env_var_command % 'LANG').should == "C"
623
- # After exec it should be restored to our current value for this level of the nesting...
624
- ENV['LANG'].should == "bar"
625
- end
626
- # Now we've dropped out of one level of nesting,
627
- ENV['LANG'].should == "foo"
628
- # Call exec one more time just for kicks
629
- Facter::Util::Resolution.exec(echo_env_var_command % 'LANG').should == "C"
630
- # One last check at our current nesting level.
631
- ENV['LANG'].should == "foo"
632
- end
114
+ describe "evaluating" do
115
+ it "evaluates the block in the context of the given resolution" do
116
+ subject.expects(:has_weight).with(5)
117
+ subject.evaluate { has_weight(5) }
633
118
  end
634
119
 
635
- context "when run on unix", :as_platform => :posix do
636
- context "binary is present" do
637
- it "should run the command if path to binary is absolute" do
638
- Facter::Util::Resolution.expects(:expand_command).with('/usr/bin/uname -m').returns('/usr/bin/uname -m')
639
- Facter::Util::Resolution.expects(:`).with('/usr/bin/uname -m').returns 'x86_64'
640
- Facter::Util::Resolution.exec('/usr/bin/uname -m').should == 'x86_64'
641
- end
642
-
643
- it "should run the expanded command if path to binary not absolute" do
644
- Facter::Util::Resolution.expects(:expand_command).with('uname -m').returns('/usr/bin/uname -m')
645
- Facter::Util::Resolution.expects(:`).with('/usr/bin/uname -m').returns 'x86_64'
646
- Facter::Util::Resolution.exec('uname -m').should == 'x86_64'
647
- end
120
+ it "raises a warning if the resolution is evaluated twice" do
121
+ Facter.expects(:warn).with do |msg|
122
+ expect(msg).to match /Already evaluated foo at.*reevaluating anyways/
648
123
  end
649
124
 
650
- context "binary is not present" do
651
- it "should not run the command if path to binary is absolute" do
652
- Facter::Util::Resolution.expects(:expand_command).with('/usr/bin/uname -m').returns nil
653
- Facter::Util::Resolution.expects(:`).with('/usr/bin/uname -m').never
654
- Facter::Util::Resolution.exec('/usr/bin/uname -m').should be_nil
655
- end
656
- it "should not run the command if path to binary is not absolute" do
657
- Facter::Util::Resolution.expects(:expand_command).with('uname -m').returns nil
658
- Facter::Util::Resolution.expects(:`).with('uname -m').never
659
- Facter::Util::Resolution.exec('uname -m').should be_nil
660
- end
661
- end
662
- end
663
-
664
- context "when run on windows", :as_platform => :windows do
665
- context "binary is present" do
666
- it "should run the command if path to binary is absolute" do
667
- Facter::Util::Resolution.expects(:expand_command).with(%q{C:\Windows\foo.exe /a /b}).returns(%q{C:\Windows\foo.exe /a /b})
668
- Facter::Util::Resolution.expects(:`).with(%q{C:\Windows\foo.exe /a /b}).returns 'bar'
669
- Facter::Util::Resolution.exec(%q{C:\Windows\foo.exe /a /b}).should == 'bar'
670
- end
671
-
672
- it "should run the expanded command if path to binary not absolute" do
673
- Facter::Util::Resolution.expects(:expand_command).with(%q{foo.exe /a /b}).returns(%q{C:\Windows\foo.exe /a /b})
674
- Facter::Util::Resolution.expects(:`).with(%q{C:\Windows\foo.exe /a /b}).returns 'bar'
675
- Facter::Util::Resolution.exec(%q{foo.exe /a /b}).should == 'bar'
676
- end
677
- end
678
-
679
- context "binary is not present" do
680
- it "should not run the command if path to binary is absolute" do
681
- Facter::Util::Resolution.expects(:expand_command).with(%q{C:\Windows\foo.exe /a /b}).returns nil
682
- Facter::Util::Resolution.expects(:`).with(%q{C:\Windows\foo.exe /a /b}).never
683
- Facter::Util::Resolution.exec(%q{C:\Windows\foo.exe /a /b}).should be_nil
684
- end
685
- it "should try to run the command and return output of a shell-builtin" do
686
- Facter::Util::Resolution.expects(:expand_command).with(%q{echo foo}).returns nil
687
- Facter::Util::Resolution.expects(:`).with(%q{echo foo}).returns 'foo'
688
- Facter.expects(:warnonce).with 'Using Facter::Util::Resolution.exec with a shell built-in is deprecated. Most built-ins can be replaced with native ruby commands. If you really have to run a built-in, pass "cmd /c your_builtin" as a command (command responsible for this message was "echo foo")'
689
- Facter::Util::Resolution.exec(%q{echo foo}).should == 'foo'
690
- end
691
- it "should try to run the command and return nil if not shell-builtin" do
692
- Facter::Util::Resolution.expects(:expand_command).with(%q{echo foo}).returns nil
693
- Facter::Util::Resolution.stubs(:`).with(%q{echo foo}).raises Errno::ENOENT, 'some_error_message'
694
- Facter.expects(:warnonce).never
695
- Facter::Util::Resolution.exec(%q{echo foo}).should be_nil
696
- end
697
- end
125
+ subject.evaluate { }
126
+ subject.evaluate { }
698
127
  end
699
128
  end
700
129
  end