chef 11.12.0.alpha.1 → 11.12.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/api_client/registration.rb +46 -9
  3. data/lib/chef/application.rb +1 -0
  4. data/lib/chef/application/client.rb +25 -24
  5. data/lib/chef/client.rb +34 -0
  6. data/lib/chef/config.rb +11 -0
  7. data/lib/chef/cookbook/chefignore.rb +10 -2
  8. data/lib/chef/cookbook/metadata.rb +31 -3
  9. data/lib/chef/cookbook/synchronizer.rb +2 -2
  10. data/lib/chef/cookbook/syntax_check.rb +4 -4
  11. data/lib/chef/encrypted_data_bag_item.rb +37 -1
  12. data/lib/chef/exceptions.rb +1 -0
  13. data/lib/chef/guard_interpreter/default_guard_interpreter.rb +42 -0
  14. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +122 -0
  15. data/lib/chef/http.rb +0 -1
  16. data/lib/chef/http/decompressor.rb +7 -4
  17. data/lib/chef/http/simple.rb +5 -0
  18. data/lib/chef/http/validate_content_length.rb +28 -12
  19. data/lib/chef/knife.rb +1 -0
  20. data/lib/chef/knife/client_bulk_delete.rb +48 -9
  21. data/lib/chef/knife/client_delete.rb +4 -4
  22. data/lib/chef/knife/cookbook_bulk_delete.rb +1 -1
  23. data/lib/chef/knife/cookbook_upload.rb +17 -7
  24. data/lib/chef/knife/core/bootstrap_context.rb +1 -1
  25. data/lib/chef/knife/core/ui.rb +42 -5
  26. data/lib/chef/knife/node_run_list_add.rb +31 -2
  27. data/lib/chef/knife/ssh.rb +44 -31
  28. data/lib/chef/knife/ssl_check.rb +213 -0
  29. data/lib/chef/knife/ssl_fetch.rb +145 -0
  30. data/lib/chef/mixin/deep_merge.rb +13 -5
  31. data/lib/chef/mixin/shell_out.rb +9 -3
  32. data/lib/chef/node.rb +23 -4
  33. data/lib/chef/node/immutable_collections.rb +32 -0
  34. data/lib/chef/platform/provider_mapping.rb +21 -18
  35. data/lib/chef/platform/query_helpers.rb +10 -2
  36. data/lib/chef/policy_builder/expand_node_object.rb +3 -6
  37. data/lib/chef/provider/cron.rb +25 -3
  38. data/lib/chef/provider/mount/mount.rb +1 -1
  39. data/lib/chef/provider/package/dpkg.rb +2 -1
  40. data/lib/chef/provider/package/windows.rb +80 -0
  41. data/lib/chef/provider/package/windows/msi.rb +69 -0
  42. data/lib/chef/provider/powershell_script.rb +19 -6
  43. data/lib/chef/provider/service/solaris.rb +11 -7
  44. data/lib/chef/resource.rb +18 -5
  45. data/lib/chef/resource/conditional.rb +20 -7
  46. data/lib/chef/resource/cron.rb +18 -2
  47. data/lib/chef/resource/execute.rb +0 -2
  48. data/lib/chef/resource/powershell_script.rb +23 -1
  49. data/lib/chef/resource/script.rb +25 -0
  50. data/lib/chef/resource/subversion.rb +4 -0
  51. data/lib/chef/resource/windows_package.rb +79 -0
  52. data/lib/chef/resource/windows_script.rb +0 -5
  53. data/lib/chef/resources.rb +1 -0
  54. data/lib/chef/rest.rb +6 -1
  55. data/lib/chef/run_context.rb +22 -2
  56. data/lib/chef/run_context/cookbook_compiler.rb +12 -0
  57. data/lib/chef/util/editor.rb +92 -0
  58. data/lib/chef/util/file_edit.rb +22 -54
  59. data/lib/chef/version.rb +2 -2
  60. data/lib/chef/win32/api/installer.rb +166 -0
  61. data/lib/chef/win32/version.rb +8 -0
  62. data/spec/data/standalone_cookbook/Gemfile +1 -0
  63. data/spec/data/standalone_cookbook/chefignore +9 -0
  64. data/spec/data/standalone_cookbook/recipes/default.rb +3 -0
  65. data/spec/data/standalone_cookbook/vendor/bundle/ruby/2.0.0/gems/multi_json-1.9.0/lib/multi_json.rb +1 -0
  66. data/spec/functional/resource/powershell_spec.rb +262 -1
  67. data/spec/functional/win32/versions_spec.rb +3 -3
  68. data/spec/integration/knife/chefignore_spec.rb +1 -2
  69. data/spec/integration/knife/raw_spec.rb +8 -13
  70. data/spec/integration/knife/redirection_spec.rb +6 -14
  71. data/spec/integration/solo/solo_spec.rb +19 -0
  72. data/spec/support/shared/functional/windows_script.rb +1 -1
  73. data/spec/support/shared/integration/app_server_support.rb +42 -0
  74. data/spec/support/shared/integration/integration_helper.rb +1 -0
  75. data/spec/support/shared/unit/script_resource.rb +38 -0
  76. data/spec/unit/api_client/registration_spec.rb +109 -38
  77. data/spec/unit/application/client_spec.rb +48 -1
  78. data/spec/unit/cookbook/chefignore_spec.rb +10 -0
  79. data/spec/unit/cookbook/metadata_spec.rb +45 -1
  80. data/spec/unit/cookbook/syntax_check_spec.rb +28 -0
  81. data/spec/unit/cookbook_spec.rb +0 -10
  82. data/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb +56 -0
  83. data/spec/unit/http/simple_spec.rb +32 -0
  84. data/spec/unit/http/validate_content_length_spec.rb +187 -0
  85. data/spec/unit/knife/bootstrap_spec.rb +13 -4
  86. data/spec/unit/knife/client_bulk_delete_spec.rb +123 -38
  87. data/spec/unit/knife/client_delete_spec.rb +4 -4
  88. data/spec/unit/knife/cookbook_upload_spec.rb +181 -88
  89. data/spec/unit/knife/core/bootstrap_context_spec.rb +11 -1
  90. data/spec/unit/knife/core/ui_spec.rb +109 -38
  91. data/spec/unit/knife/node_run_list_add_spec.rb +24 -1
  92. data/spec/unit/knife/ssh_spec.rb +17 -6
  93. data/spec/unit/knife/ssl_check_spec.rb +187 -0
  94. data/spec/unit/knife/ssl_fetch_spec.rb +151 -0
  95. data/spec/unit/mixin/deep_merge_spec.rb +17 -0
  96. data/spec/unit/node/immutable_collections_spec.rb +55 -0
  97. data/spec/unit/node_spec.rb +9 -0
  98. data/spec/unit/platform/query_helpers_spec.rb +32 -0
  99. data/spec/unit/platform_spec.rb +193 -175
  100. data/spec/unit/policy_builder/expand_node_object_spec.rb +1 -1
  101. data/spec/unit/provider/cron_spec.rb +175 -1
  102. data/spec/unit/provider/mount/mount_spec.rb +33 -3
  103. data/spec/unit/provider/package/dpkg_spec.rb +4 -0
  104. data/spec/unit/provider/package/windows/msi_spec.rb +60 -0
  105. data/spec/unit/provider/package/windows_spec.rb +80 -0
  106. data/spec/unit/provider/service/macosx_spec.rb +3 -3
  107. data/spec/unit/provider/service/solaris_smf_service_spec.rb +35 -10
  108. data/spec/unit/pure_application_spec.rb +32 -0
  109. data/spec/unit/recipe_spec.rb +4 -0
  110. data/spec/unit/resource/conditional_spec.rb +13 -12
  111. data/spec/unit/resource/cron_spec.rb +7 -2
  112. data/spec/unit/resource/powershell_spec.rb +85 -2
  113. data/spec/unit/resource/subversion_spec.rb +5 -0
  114. data/spec/unit/resource/windows_package_spec.rb +74 -0
  115. data/spec/unit/resource_spec.rb +23 -1
  116. data/spec/unit/rest_spec.rb +15 -0
  117. data/spec/unit/run_context/cookbook_compiler_spec.rb +12 -0
  118. data/spec/unit/run_context_spec.rb +7 -0
  119. data/spec/unit/util/editor_spec.rb +152 -0
  120. data/spec/unit/util/file_edit_spec.rb +37 -1
  121. metadata +41 -30
@@ -244,7 +244,7 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
244
244
 
245
245
  it "sets the override run_list on the node" do
246
246
  expect(node.run_list).to eq([override_runlist])
247
- expect(policy_builder.original_runlist).to eq(primary_runlist)
247
+ expect(node.primary_runlist).to eq(primary_runlist)
248
248
  end
249
249
 
250
250
  it "reports that a temporary policy is being used" do
@@ -19,15 +19,137 @@
19
19
  require 'spec_helper'
20
20
 
21
21
  describe Chef::Provider::Cron do
22
+ describe "when with special time string" do
23
+ before do
24
+ @node = Chef::Node.new
25
+ @events = Chef::EventDispatch::Dispatcher.new
26
+ @run_context = Chef::RunContext.new(@node, {}, @events)
27
+
28
+ @new_resource = Chef::Resource::Cron.new("cronhole some stuff", @run_context)
29
+ @new_resource.user "root"
30
+ @new_resource.minute "30"
31
+ @new_resource.command "/bin/true"
32
+ @new_resource.time :reboot
33
+ @provider = Chef::Provider::Cron.new(@new_resource, @run_context)
34
+ end
35
+
36
+ context "with a matching entry in the user's crontab" do
37
+ before :each do
38
+ @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
39
+ 0 2 * * * /some/other/command
40
+
41
+ # Chef Name: cronhole some stuff
42
+ @reboot /bin/true param1 param2
43
+ # Chef Name: something else
44
+ 2 * 1 * * /bin/false
45
+
46
+ # Another comment
47
+ CRONTAB
48
+ end
49
+
50
+ it "should set cron_exists" do
51
+ @provider.load_current_resource
52
+ @provider.cron_exists.should == true
53
+ @provider.cron_empty.should == false
54
+ end
55
+
56
+ it "should pull the details out of the cron line" do
57
+ cron = @provider.load_current_resource
58
+ cron.time.should == :reboot
59
+ cron.command.should == '/bin/true param1 param2'
60
+ end
61
+
62
+ it "should pull env vars out" do
63
+ @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
64
+ 0 2 * * * /some/other/command
65
+
66
+ # Chef Name: cronhole some stuff
67
+ MAILTO=foo@example.com
68
+ SHELL=/bin/foosh
69
+ PATH=/bin:/foo
70
+ HOME=/home/foo
71
+ @reboot /bin/true param1 param2
72
+ # Chef Name: something else
73
+ 2 * 1 * * /bin/false
74
+
75
+ # Another comment
76
+ CRONTAB
77
+ cron = @provider.load_current_resource
78
+ cron.mailto.should == 'foo@example.com'
79
+ cron.shell.should == '/bin/foosh'
80
+ cron.path.should == '/bin:/foo'
81
+ cron.home.should == '/home/foo'
82
+ cron.time.should == :reboot
83
+ cron.command.should == '/bin/true param1 param2'
84
+ end
85
+
86
+ it "should parse and load generic and standard environment variables from cron entry" do
87
+ @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
88
+ # Chef Name: cronhole some stuff
89
+ MAILTO=warn@example.com
90
+ TEST=lol
91
+ FLAG=1
92
+ @reboot /bin/true
93
+ CRONTAB
94
+ cron = @provider.load_current_resource
95
+
96
+ cron.mailto.should == "warn@example.com"
97
+ cron.environment.should == {"TEST" => "lol", "FLAG" => "1"}
98
+ end
99
+
100
+ it "should not break with variables that match the cron resource internals" do
101
+ @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
102
+ # Chef Name: cronhole some stuff
103
+ MINUTE=40
104
+ REBOOT=midnight
105
+ TEST=lol
106
+ ENVIRONMENT=production
107
+ @reboot /bin/true
108
+ CRONTAB
109
+ cron = @provider.load_current_resource
110
+
111
+ cron.time.should == :reboot
112
+ cron.environment.should == {"MINUTE" => "40", "REBOOT" => "midnight", "TEST" => "lol", "ENVIRONMENT" => "production"}
113
+ end
114
+
115
+ it "should report the match" do
116
+ Chef::Log.should_receive(:debug).with("Found cron '#{@new_resource.name}'")
117
+ @provider.load_current_resource
118
+ end
119
+
120
+ describe "action_create" do
121
+ before :each do
122
+ @provider.stub!(:write_crontab)
123
+ @provider.stub!(:read_crontab).and_return(nil)
124
+ end
125
+
126
+ context "when there is no existing crontab" do
127
+ before :each do
128
+ @provider.cron_exists = false
129
+ @provider.cron_empty = true
130
+ end
131
+
132
+ it "should create a crontab with the entry" do
133
+ @provider.should_receive(:write_crontab).with(<<-ENDCRON)
134
+ # Chef Name: cronhole some stuff
135
+ @reboot /bin/true
136
+ ENDCRON
137
+ @provider.run_action(:create)
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+
22
144
  before do
23
145
  @node = Chef::Node.new
24
146
  @events = Chef::EventDispatch::Dispatcher.new
25
147
  @run_context = Chef::RunContext.new(@node, {}, @events)
148
+
26
149
  @new_resource = Chef::Resource::Cron.new("cronhole some stuff", @run_context)
27
150
  @new_resource.user "root"
28
151
  @new_resource.minute "30"
29
152
  @new_resource.command "/bin/true"
30
-
31
153
  @provider = Chef::Provider::Cron.new(@new_resource, @run_context)
32
154
  end
33
155
 
@@ -110,6 +232,7 @@ CRONTAB
110
232
  cron.day.should == '*'
111
233
  cron.month.should == '1'
112
234
  cron.weekday.should == '*'
235
+ cron.time.should == nil
113
236
  cron.command.should == '/bin/true param1 param2'
114
237
  end
115
238
 
@@ -138,6 +261,7 @@ CRONTAB
138
261
  cron.day.should == '*'
139
262
  cron.month.should == '1'
140
263
  cron.weekday.should == '*'
264
+ cron.time.should == nil
141
265
  cron.command.should == '/bin/true param1 param2'
142
266
  end
143
267
 
@@ -227,6 +351,7 @@ CRONTAB
227
351
  cron.day.should == '*'
228
352
  cron.month.should == '*'
229
353
  cron.weekday.should == '*'
354
+ cron.time.should == nil
230
355
  cron.command.should == nil
231
356
  end
232
357
 
@@ -244,6 +369,7 @@ CRONTAB
244
369
  cron.day.should == '*'
245
370
  cron.month.should == '*'
246
371
  cron.weekday.should == '*'
372
+ cron.time.should == nil
247
373
  cron.command.should == nil
248
374
  end
249
375
 
@@ -265,6 +391,7 @@ CRONTAB
265
391
  cron.day.should == '*'
266
392
  cron.month.should == '*'
267
393
  cron.weekday.should == '*'
394
+ cron.time.should == nil
268
395
  cron.command.should == nil
269
396
  end
270
397
  end
@@ -286,6 +413,11 @@ CRONTAB
286
413
  end
287
414
  end
288
415
 
416
+ it "should return true if special time string doesn't match" do
417
+ @new_resource.send(:time, :reboot)
418
+ @provider.cron_different?.should eql(true)
419
+ end
420
+
289
421
  it "should return true if environment doesn't match" do
290
422
  @new_resource.environment "FOO" => "something_else"
291
423
  @provider.cron_different?.should eql(true)
@@ -833,4 +965,46 @@ MAILTO=foo@example.com
833
965
  end
834
966
 
835
967
  end
968
+
969
+ describe "weekday_in_crontab" do
970
+ context "when weekday is symbol" do
971
+ it "should return weekday in crontab format" do
972
+ @new_resource.weekday :wednesday
973
+ @provider.send(:weekday_in_crontab).should eq("3")
974
+ end
975
+
976
+ it "should raise an error with an unknown weekday" do
977
+ expect { @new_resource.weekday :caturday }.to raise_error(RangeError)
978
+ end
979
+ end
980
+
981
+ context "when weekday is a number in a string" do
982
+ it "should return the string" do
983
+ @new_resource.weekday "3"
984
+ @provider.send(:weekday_in_crontab).should eq("3")
985
+ end
986
+
987
+ it "should raise an error with an out of range number" do
988
+ expect { @new_resource.weekday "-1" }.to raise_error(RangeError)
989
+ end
990
+ end
991
+
992
+ context "when weekday is string with the name of the week" do
993
+ it "should return the string" do
994
+ @new_resource.weekday "mon"
995
+ @provider.send(:weekday_in_crontab).should eq("mon")
996
+ end
997
+ end
998
+
999
+ context "when weekday is an integer" do
1000
+ it "should return the integer" do
1001
+ @new_resource.weekday 1
1002
+ @provider.send(:weekday_in_crontab).should eq("1")
1003
+ end
1004
+
1005
+ it "should raise an error with an out of range integer" do
1006
+ expect { @new_resource.weekday 45 }.to raise_error(RangeError)
1007
+ end
1008
+ end
1009
+ end
836
1010
  end
@@ -131,12 +131,27 @@ describe Chef::Provider::Mount::Mount do
131
131
  end
132
132
 
133
133
  it "should set mounted true if the symlink target of the device is found in the mounts list" do
134
- target = "/dev/mapper/target"
134
+ # expand the target path to correct specs on Windows
135
+ target = ::File.expand_path('/dev/mapper/target')
136
+
137
+ ::File.stub(:symlink?).with("#{@new_resource.device}").and_return(true)
138
+ ::File.stub(:readlink).with("#{@new_resource.device}").and_return(target)
139
+
140
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => "#{target} on /tmp/foo type ext3 (rw)\n"))
141
+ @provider.load_current_resource()
142
+ @provider.current_resource.mounted.should be_true
143
+ end
144
+
145
+ it "should set mounted true if the symlink target of the device is relative and is found in the mounts list - CHEF-4957" do
146
+ target = "xsdz1"
147
+
148
+ # expand the target path to correct specs on Windows
149
+ absolute_target = ::File.expand_path("/dev/xsdz1")
135
150
 
136
151
  ::File.stub(:symlink?).with("#{@new_resource.device}").and_return(true)
137
152
  ::File.stub(:readlink).with("#{@new_resource.device}").and_return(target)
138
153
 
139
- @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => "/dev/mapper/target on /tmp/foo type ext3 (rw)\n"))
154
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => "#{absolute_target} on /tmp/foo type ext3 (rw)\n"))
140
155
  @provider.load_current_resource()
141
156
  @provider.current_resource.mounted.should be_true
142
157
  end
@@ -199,6 +214,20 @@ describe Chef::Provider::Mount::Mount do
199
214
  @provider.current_resource.enabled.should be_true
200
215
  end
201
216
 
217
+ it "should set enabled to true if the symlink target is relative and is in fstab - CHEF-4957" do
218
+ target = "xsdz1"
219
+
220
+ ::File.stub(:symlink?).with("#{@new_resource.device}").and_return(true)
221
+ ::File.stub(:readlink).with("#{@new_resource.device}").and_return(target)
222
+
223
+ fstab = "/dev/sdz1 /tmp/foo ext3 defaults 1 2\n"
224
+
225
+ ::File.stub(:foreach).with("/etc/fstab").and_yield fstab
226
+
227
+ @provider.load_current_resource
228
+ @provider.current_resource.enabled.should be_true
229
+ end
230
+
202
231
  it "should set enabled to false if the mount point is not in fstab" do
203
232
  fstab = "/dev/sdy1 #{@new_resource.mount_point} ext3 defaults 1 2\n"
204
233
  ::File.stub(:foreach).with("/etc/fstab").and_yield fstab
@@ -225,6 +254,7 @@ describe Chef::Provider::Mount::Mount do
225
254
  end
226
255
 
227
256
  it "should not mangle the mount options if the device in fstab is a symlink" do
257
+ # expand the target path to correct specs on Windows
228
258
  target = "/dev/mapper/target"
229
259
  options = "rw,noexec,noauto"
230
260
 
@@ -238,7 +268,7 @@ describe Chef::Provider::Mount::Mount do
238
268
  end
239
269
 
240
270
  it "should not mangle the mount options if the symlink target is in fstab" do
241
- target = "/dev/mapper/target"
271
+ target = ::File.expand_path("/dev/mapper/target")
242
272
  options = "rw,noexec,noauto"
243
273
 
244
274
  ::File.stub(:symlink?).with(@new_resource.device).and_return(true)
@@ -72,6 +72,10 @@ describe Chef::Provider::Package::Dpkg do
72
72
  it 'if distro-specific version provided' do
73
73
  check_version('1.11.4-1ubuntu1~lucid')
74
74
  end
75
+
76
+ it 'returns the version if an epoch is used' do
77
+ check_version('1:1.8.3-2')
78
+ end
75
79
  end
76
80
 
77
81
  it "gets the source package name from dpkg-deb correctly when the package name has `-', `+' or `.' characters" do
@@ -0,0 +1,60 @@
1
+ #
2
+ # Author:: Bryan McLellan <btm@loftninjas.org>
3
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+
21
+ describe Chef::Provider::Package::Windows::MSI, :windows_only do
22
+ let(:node) { double('Chef::Node') }
23
+ let(:events) { double('Chef::Events').as_null_object } # mock all the methods
24
+ let(:run_context) { double('Chef::RunContext', :node => node, :events => events) }
25
+ let(:new_resource) { Chef::Resource::WindowsPackage.new("calculator.msi") }
26
+ let(:provider) { Chef::Provider::Package::Windows::MSI.new(new_resource) }
27
+
28
+ describe "expand_options" do
29
+ it "returns an empty string if passed no options" do
30
+ expect(provider.expand_options(nil)).to eql ""
31
+ end
32
+
33
+ it "returns a string with a leading space if passed options" do
34
+ expect(provider.expand_options("--train nope --town no_way")).to eql(" --train nope --town no_way")
35
+ end
36
+ end
37
+
38
+ describe "installed_version" do
39
+ it "returns the installed version" do
40
+ provider.stub(:get_product_property).and_return("{23170F69-40C1-2702-0920-000001000000}")
41
+ provider.stub(:get_installed_version).with("{23170F69-40C1-2702-0920-000001000000}").and_return("3.14159.1337.42")
42
+ expect(provider.installed_version).to eql("3.14159.1337.42")
43
+ end
44
+ end
45
+
46
+ describe "package_version" do
47
+ it "returns the version of a package" do
48
+ provider.stub(:get_product_property).with(/calculator.msi$/, "ProductVersion").and_return(42)
49
+ expect(provider.package_version).to eql(42)
50
+ end
51
+ end
52
+
53
+ describe "install_package" do
54
+ # calls shell_out!
55
+ end
56
+
57
+ describe "remove_package" do
58
+ # calls shell_out!
59
+ end
60
+ end
@@ -0,0 +1,80 @@
1
+ #
2
+ # Author:: Bryan McLellan <btm@loftninjas.org>
3
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+
21
+ describe Chef::Provider::Package::Windows, :windows_only do
22
+ let(:node) { double('Chef::Node') }
23
+ let(:events) { double('Chef::Events').as_null_object } # mock all the methods
24
+ let(:run_context) { double('Chef::RunContext', :node => node, :events => events) }
25
+ let(:new_resource) { Chef::Resource::WindowsPackage.new("calculator.msi") }
26
+ let(:provider) { Chef::Provider::Package::Windows.new(new_resource, run_context) }
27
+
28
+ describe "load_current_resource" do
29
+ before(:each) do
30
+ provider.stub(:package_provider).and_return(double('package_provider',
31
+ :installed_version => "1.0", :package_version => "2.0"))
32
+ end
33
+
34
+ it "creates a current resource with the name of the new resource" do
35
+ provider.load_current_resource
36
+ expect(provider.current_resource).to be_a(Chef::Resource::WindowsPackage)
37
+ expect(provider.current_resource.name).to eql("calculator.msi")
38
+ end
39
+
40
+ it "sets the current version if the package is installed" do
41
+ provider.load_current_resource
42
+ expect(provider.current_resource.version).to eql("1.0")
43
+ end
44
+
45
+ it "sets the version to be installed" do
46
+ provider.load_current_resource
47
+ expect(provider.new_resource.version).to eql("2.0")
48
+ end
49
+ end
50
+
51
+ describe "package_provider" do
52
+ it "sets the package provider to MSI if the the installer type is :msi" do
53
+ provider.stub(:installer_type).and_return(:msi)
54
+ expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::MSI)
55
+ end
56
+
57
+ it "raises an error if the installer_type is unknown" do
58
+ provider.stub(:installer_type).and_return(:apt_for_windows)
59
+ expect { provider.package_provider }.to raise_error
60
+ end
61
+ end
62
+
63
+ describe "installer_type" do
64
+ it "it returns @installer_type if it is set" do
65
+ provider.new_resource.installer_type("downeaster")
66
+ expect(provider.installer_type).to eql("downeaster")
67
+ end
68
+
69
+ it "sets installer_type to msi if the source ends in .msi" do
70
+ provider.new_resource.source("microsoft_installer.msi")
71
+ expect(provider.installer_type).to eql(:msi)
72
+ end
73
+
74
+ it "raises an error if it cannot determine the installer type" do
75
+ provider.new_resource.installer_type(nil)
76
+ provider.new_resource.source("tomfoolery.now")
77
+ expect { provider.installer_type }.to raise_error(ArgumentError)
78
+ end
79
+ end
80
+ end