chef 11.10.4-x86-mingw32 → 11.12.0.alpha.1-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +6 -6
  3. data/README.md +1 -1
  4. data/lib/chef/api_client.rb +1 -3
  5. data/lib/chef/application.rb +2 -1
  6. data/lib/chef/application/client.rb +11 -1
  7. data/lib/chef/client.rb +24 -9
  8. data/lib/chef/cookbook/syntax_check.rb +107 -6
  9. data/lib/chef/dsl/reboot_pending.rb +61 -0
  10. data/lib/chef/exceptions.rb +12 -1
  11. data/lib/chef/formatters/error_descriptor.rb +1 -1
  12. data/lib/chef/http/remote_request_id.rb +46 -0
  13. data/lib/chef/knife/bootstrap.rb +1 -1
  14. data/lib/chef/knife/bootstrap/README.md +12 -0
  15. data/lib/chef/knife/bootstrap/chef-full.erb +3 -0
  16. data/lib/chef/knife/client_create.rb +6 -0
  17. data/lib/chef/knife/client_delete.rb +15 -1
  18. data/lib/chef/knife/raw.rb +1 -0
  19. data/lib/chef/node.rb +1 -1
  20. data/lib/chef/node/attribute_collections.rb +8 -1
  21. data/lib/chef/node/immutable_collections.rb +8 -1
  22. data/lib/chef/provider/deploy.rb +1 -1
  23. data/lib/chef/provider/group.rb +1 -1
  24. data/lib/chef/provider/ifconfig/debian.rb +19 -8
  25. data/lib/chef/provider/ohai.rb +6 -5
  26. data/lib/chef/provider/service/macosx.rb +68 -14
  27. data/lib/chef/recipe.rb +2 -0
  28. data/lib/chef/request_id.rb +37 -0
  29. data/lib/chef/resource.rb +2 -0
  30. data/lib/chef/resource_reporter.rb +7 -4
  31. data/lib/chef/rest.rb +5 -1
  32. data/lib/chef/run_status.rb +4 -1
  33. data/lib/chef/server_api.rb +3 -1
  34. data/lib/chef/version.rb +2 -2
  35. data/spec/functional/dsl/reboot_pending_spec.rb +118 -0
  36. data/spec/functional/resource/base.rb +1 -3
  37. data/spec/functional/resource/deploy_revision_spec.rb +192 -1
  38. data/spec/functional/resource/git_spec.rb +1 -1
  39. data/spec/functional/resource/ohai_spec.rb +65 -0
  40. data/spec/functional/resource/registry_spec.rb +4 -5
  41. data/spec/integration/client/client_spec.rb +14 -0
  42. data/spec/spec_helper.rb +1 -2
  43. data/spec/support/shared/functional/windows_script.rb +1 -2
  44. data/spec/unit/api_client_spec.rb +46 -0
  45. data/spec/unit/client_spec.rb +345 -229
  46. data/spec/unit/cookbook/syntax_check_spec.rb +0 -1
  47. data/spec/unit/dsl/reboot_pending_spec.rb +100 -0
  48. data/spec/unit/knife/client_create_spec.rb +29 -1
  49. data/spec/unit/knife/client_delete_spec.rb +44 -1
  50. data/spec/unit/knife_spec.rb +55 -0
  51. data/spec/unit/node/attribute_spec.rb +7 -0
  52. data/spec/unit/node/immutable_collections_spec.rb +5 -1
  53. data/spec/unit/provider/group_spec.rb +5 -0
  54. data/spec/unit/provider/ifconfig/debian_spec.rb +251 -24
  55. data/spec/unit/provider/ohai_spec.rb +2 -3
  56. data/spec/unit/provider/service/macosx_spec.rb +29 -11
  57. data/spec/unit/resource_reporter_spec.rb +1 -1
  58. data/spec/unit/rest_spec.rb +38 -13
  59. metadata +151 -216
@@ -21,6 +21,7 @@ require 'chef/mixin/params_validate'
21
21
  require 'chef/dsl/platform_introspection'
22
22
  require 'chef/dsl/data_query'
23
23
  require 'chef/dsl/registry_helper'
24
+ require 'chef/dsl/reboot_pending'
24
25
  require 'chef/mixin/convert_to_class_name'
25
26
  require 'chef/resource/conditional'
26
27
  require 'chef/resource/conditional_action_not_nothing'
@@ -125,6 +126,7 @@ F
125
126
  include Chef::Mixin::ParamsValidate
126
127
  include Chef::DSL::PlatformIntrospection
127
128
  include Chef::DSL::RegistryHelper
129
+ include Chef::DSL::RebootPending
128
130
  include Chef::Mixin::ConvertToClassName
129
131
  include Chef::Mixin::Deprecation
130
132
 
@@ -107,7 +107,6 @@ class Chef
107
107
  @pending_update = nil
108
108
  @status = "success"
109
109
  @exception = nil
110
- @run_id = SecureRandom.uuid
111
110
  @rest_client = rest_client
112
111
  @error_descriptions = {}
113
112
  end
@@ -118,7 +117,7 @@ class Chef
118
117
  if reporting_enabled?
119
118
  begin
120
119
  resource_history_url = "reports/nodes/#{node_name}/runs"
121
- server_response = @rest_client.post_rest(resource_history_url, {:action => :start, :run_id => @run_id,
120
+ server_response = @rest_client.post_rest(resource_history_url, {:action => :start, :run_id => run_id,
122
121
  :start_time => start_time.to_s}, headers)
123
122
  rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
124
123
  handle_error_starting_run(e, resource_history_url)
@@ -158,6 +157,10 @@ class Chef
158
157
  @reporting_enabled = false
159
158
  end
160
159
 
160
+ def run_id
161
+ @run_status.run_id
162
+ end
163
+
161
164
  def resource_current_state_loaded(new_resource, action, current_resource)
162
165
  unless nested_resource?(new_resource)
163
166
  @pending_update = ResourceReport.new_with_current_state(new_resource, action, current_resource)
@@ -214,8 +217,8 @@ class Chef
214
217
  def post_reporting_data
215
218
  if reporting_enabled?
216
219
  run_data = prepare_run_data
217
- resource_history_url = "reports/nodes/#{node_name}/runs/#{@run_id}"
218
- Chef::Log.info("Sending resource update report (run-id: #{@run_id})")
220
+ resource_history_url = "reports/nodes/#{node_name}/runs/#{run_id}"
221
+ Chef::Log.info("Sending resource update report (run-id: #{run_id})")
219
222
  Chef::Log.debug run_data.inspect
220
223
  compressed_data = encode_gzip(run_data.to_json)
221
224
  begin
@@ -36,6 +36,7 @@ require 'chef/http/validate_content_length'
36
36
  require 'chef/config'
37
37
  require 'chef/exceptions'
38
38
  require 'chef/platform/query_helpers'
39
+ require 'chef/http/remote_request_id'
39
40
 
40
41
  class Chef
41
42
  # == Chef::REST
@@ -62,6 +63,7 @@ class Chef
62
63
 
63
64
  @decompressor = Decompressor.new(options)
64
65
  @authenticator = Authenticator.new(options)
66
+ @request_id = RemoteRequestID.new(options)
65
67
 
66
68
  @middlewares << ValidateContentLength.new(options)
67
69
  @middlewares << JSONInput.new(options)
@@ -69,6 +71,8 @@ class Chef
69
71
  @middlewares << CookieManager.new(options)
70
72
  @middlewares << @decompressor
71
73
  @middlewares << @authenticator
74
+ @middlewares << @request_id
75
+
72
76
  end
73
77
 
74
78
  def signing_key_filename
@@ -132,7 +136,7 @@ class Chef
132
136
  def raw_http_request(method, path, headers, data)
133
137
  url = create_url(path)
134
138
  method, url, headers, data = @authenticator.handle_request(method, url, headers, data)
135
-
139
+ method, url, headers, data = @request_id.handle_request(method, url, headers, data)
136
140
  response, rest_request, return_value = send_http_request(method, url, headers, data)
137
141
  response.error! unless success_response?(response)
138
142
  return_value
@@ -37,6 +37,8 @@ class Chef::RunStatus
37
37
 
38
38
  attr_writer :exception
39
39
 
40
+ attr_accessor :run_id
41
+
40
42
  def initialize(node, events)
41
43
  @node = node
42
44
  @events = events
@@ -112,7 +114,8 @@ class Chef::RunStatus
112
114
  :all_resources => all_resources,
113
115
  :updated_resources => updated_resources,
114
116
  :exception => formatted_exception,
115
- :backtrace => backtrace}
117
+ :backtrace => backtrace,
118
+ :run_id => run_id}
116
119
  end
117
120
 
118
121
  # Returns a string of the format "ExceptionClass: message" or +nil+ if no
@@ -22,6 +22,7 @@ require 'chef/http/cookie_manager'
22
22
  require 'chef/http/decompressor'
23
23
  require 'chef/http/json_input'
24
24
  require 'chef/http/json_output'
25
+ require 'chef/http/remote_request_id'
25
26
 
26
27
  class Chef
27
28
  class ServerAPI < Chef::HTTP
@@ -37,5 +38,6 @@ class Chef
37
38
  use Chef::HTTP::CookieManager
38
39
  use Chef::HTTP::Decompressor
39
40
  use Chef::HTTP::Authenticator
41
+ use Chef::HTTP::RemoteRequestID
40
42
  end
41
- end
43
+ end
@@ -1,4 +1,4 @@
1
- #rc
1
+ #
2
2
  # Author:: Daniel DeLeo (<dan@opscode.com>)
3
3
  # Copyright:: Copyright (c) 2010-2011 Opscode, Inc.
4
4
  # License:: Apache License, Version 2.0
@@ -17,7 +17,7 @@
17
17
 
18
18
  class Chef
19
19
  CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
20
- VERSION = '11.10.4'
20
+ VERSION = '11.12.0.alpha.1'
21
21
  end
22
22
 
23
23
  # NOTE: the Chef::Version class is defined in version_class.rb
@@ -0,0 +1,118 @@
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 "chef/dsl/reboot_pending"
20
+ require "chef/win32/registry"
21
+ require "spec_helper"
22
+
23
+ describe Chef::DSL::RebootPending, :windows_only do
24
+ def run_ohai
25
+ ohai = Ohai::System.new
26
+ # Would be nice to limit this to platform/kernel/arch etc for Ohai 7
27
+ ohai.all_plugins
28
+ node.consume_external_attrs(ohai.data,{})
29
+
30
+ ohai
31
+ end
32
+
33
+ def registry_safe?
34
+ !registry.value_exists?('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { :name => 'PendingFileRenameOperations' }) ||
35
+ !registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') ||
36
+ !registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired') ||
37
+ !registry.key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile')
38
+ end
39
+
40
+ let(:node) { Chef::Node.new }
41
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
42
+ let!(:ohai) { run_ohai } # Ensure we have necessary node data
43
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
44
+ let(:recipe) { Chef::Recipe.new("a windows cookbook", "the windows recipe", run_context) }
45
+ let(:registry) { Chef::Win32::Registry.new(run_context) }
46
+
47
+ describe "reboot_pending?" do
48
+
49
+ context "when there is nothing to indicate a reboot is pending" do
50
+ it { expect(recipe.reboot_pending?).to be_false }
51
+ end
52
+
53
+ describe 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations' do
54
+ it "returns true if the registry value exists" do
55
+ pending "Found existing registry keys" unless registry_safe?
56
+ registry.set_value('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager',
57
+ { :name => 'PendingFileRenameOperations', :type => :multi_string, :data => ['\??\C:\foo.txt|\??\C:\bar.txt'] })
58
+
59
+ expect(recipe.reboot_pending?).to be_true
60
+ end
61
+
62
+ after do
63
+ if registry_safe?
64
+ registry.delete_value('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { :name => 'PendingFileRenameOperations' })
65
+ end
66
+ end
67
+ end
68
+
69
+ describe 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' do
70
+ it "returns true if the registry key exists" do
71
+ pending "Found existing registry keys" unless registry_safe?
72
+ registry.create_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired', false)
73
+
74
+ expect(recipe.reboot_pending?).to be_true
75
+ end
76
+
77
+ after do
78
+ if registry_safe?
79
+ registry.delete_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired', false)
80
+ end
81
+ end
82
+ end
83
+
84
+ describe 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired' do
85
+ it "returns true if the registry key exists" do
86
+ pending "Permissions are limited to 'TrustedInstaller' by default"
87
+ pending "Found existing registry keys" unless registry_safe?
88
+ registry.create_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired', false)
89
+
90
+ expect(recipe.reboot_pending?).to be_true
91
+ end
92
+
93
+ after do
94
+ if registry_safe?
95
+ registry.delete_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired', false)
96
+ end
97
+ end
98
+ end
99
+
100
+ describe 'HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile\Flags' do
101
+ it "returns true if the registry key exists" do
102
+ pending "Found existing registry keys" unless registry_safe?
103
+ registry.create_key('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile', true)
104
+ registry.set_value('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile',
105
+ { :name => 'Flags', :type => :dword, :data => 3 })
106
+
107
+ expect(recipe.reboot_pending?).to be_true
108
+ end
109
+
110
+ after do
111
+ if registry_safe?
112
+ registry.delete_value('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile', { :name => 'Flags' })
113
+ registry.delete_key('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile', false)
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -22,9 +22,7 @@ def ohai
22
22
  # provider is platform-dependent, we need platform ohai data:
23
23
  @OHAI_SYSTEM ||= begin
24
24
  ohai = Ohai::System.new
25
- ohai.require_plugin("os")
26
- ohai.require_plugin("platform")
27
- ohai.require_plugin("passwd")
25
+ ohai.all_plugins("platform")
28
26
  ohai
29
27
  end
30
28
  end
@@ -45,7 +45,7 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
45
45
 
46
46
  before(:all) do
47
47
  @ohai = Ohai::System.new
48
- @ohai.require_plugin("os")
48
+ @ohai.all_plugins("os")
49
49
  end
50
50
 
51
51
  let(:node) do
@@ -78,6 +78,9 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
78
78
  # This is the third version
79
79
  let(:previous_rev) { "6d19a6dbecc8e37f5b2277345885c0c783eb8fb1" }
80
80
 
81
+ # This is the second version
82
+ let(:second_rev) { "0827e1b0e5043608ac0a824da5c558e252154ad0" }
83
+
81
84
  # This is the sixth version, it is on the "with-deploy-scripts" branch
82
85
  let(:rev_with_in_repo_callbacks) { "2404d015882659754bdb93ad6e4b4d3d02691a82" }
83
86
 
@@ -100,6 +103,7 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
100
103
 
101
104
  let(:basic_deploy_resource) do
102
105
  Chef::Resource::DeployRevision.new(deploy_directory, run_context).tap do |r|
106
+ r.name "deploy-revision-unit-test"
103
107
  r.repo git_bundle_repo
104
108
  r.symlink_before_migrate({})
105
109
  r.symlinks({})
@@ -127,6 +131,34 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
127
131
  end
128
132
  end
129
133
 
134
+ let(:deploy_to_previous_rev_again) do
135
+ basic_deploy_resource.dup.tap do |r|
136
+ r.revision(previous_rev)
137
+ r.restart_command shell_restart_command(:deploy_to_previous_rev_again)
138
+ end
139
+ end
140
+
141
+ let(:deploy_to_second_rev) do
142
+ basic_deploy_resource.dup.tap do |r|
143
+ r.revision(second_rev)
144
+ r.restart_command shell_restart_command(:deploy_to_second_rev)
145
+ end
146
+ end
147
+
148
+ let(:deploy_to_second_rev_again) do
149
+ basic_deploy_resource.dup.tap do |r|
150
+ r.revision(second_rev)
151
+ r.restart_command shell_restart_command(:deploy_to_second_rev_again)
152
+ end
153
+ end
154
+
155
+ let(:deploy_to_second_rev_again_again) do
156
+ basic_deploy_resource.dup.tap do |r|
157
+ r.revision(second_rev)
158
+ r.restart_command shell_restart_command(:deploy_to_second_rev_again_again)
159
+ end
160
+ end
161
+
130
162
  # Computes the full path for +path+ relative to the deploy directory
131
163
  def rel_path(path)
132
164
  File.expand_path(path, deploy_directory)
@@ -306,6 +338,165 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
306
338
  end
307
339
  end
308
340
 
341
+ describe "back to a previously deployed revision where resource rev == latest revision (explicit rollback)" do
342
+ before do
343
+ deploy_to_previous_rev.run_action(:deploy)
344
+ @previous_rev_all_releases = deploy_to_previous_rev.provider_for_action(:deploy).all_releases
345
+ deploy_to_latest_rev.run_action(:deploy)
346
+ @latest_rev_all_releases = deploy_to_latest_rev.provider_for_action(:deploy).all_releases
347
+ deploy_to_latest_rev_again.run_action(:rollback)
348
+ @previous_rev_again_all_releases = deploy_to_latest_rev_again.provider_for_action(:deploy).all_releases
349
+ end
350
+
351
+ the_app_is_deployed_at_revision(:previous_rev)
352
+
353
+ it "restarts the application after rolling back" do
354
+ actual_operations_order.should == %w[deploy_to_previous_rev deploy_to_latest_rev deploy_to_latest_rev_again]
355
+ end
356
+
357
+ it "is marked updated" do
358
+ deploy_to_latest_rev_again.should be_updated_by_last_action
359
+ end
360
+
361
+ it "deploys the right code" do
362
+ IO.read(rel_path("current/app/app.rb")).should include("this is the third version of the app")
363
+ end
364
+
365
+ it "all_releases after first deploy should have one entry" do
366
+ @previous_rev_all_releases.length.should == 1
367
+ end
368
+
369
+ it "all_releases after second deploy should have two entries" do
370
+ @latest_rev_all_releases.length.should == 2
371
+ end
372
+
373
+ it "all_releases after rollback should have one entry" do
374
+ @previous_rev_again_all_releases.length.should == 1
375
+ end
376
+
377
+ it "all_releases after rollback should be the same as after the first deploy" do
378
+ @previous_rev_again_all_releases.should == @previous_rev_all_releases
379
+ end
380
+
381
+ end
382
+
383
+ describe "back to a previously deployed revision where resource rev == previous revision (explicit rollback)" do
384
+ before do
385
+ deploy_to_previous_rev.run_action(:deploy)
386
+ @previous_rev_all_releases = deploy_to_previous_rev.provider_for_action(:deploy).all_releases
387
+ deploy_to_latest_rev.run_action(:deploy)
388
+ @latest_rev_all_releases = deploy_to_latest_rev.provider_for_action(:deploy).all_releases
389
+ deploy_to_previous_rev_again.run_action(:rollback)
390
+ # FIXME: only difference with previous test is using latest_rev_again insetad of previous_rev_again
391
+ @previous_rev_again_all_releases = deploy_to_latest_rev_again.provider_for_action(:deploy).all_releases
392
+ end
393
+
394
+ the_app_is_deployed_at_revision(:previous_rev)
395
+
396
+ it "restarts the application after rolling back" do
397
+ actual_operations_order.should == %w[deploy_to_previous_rev deploy_to_latest_rev deploy_to_previous_rev_again]
398
+ end
399
+
400
+ it "is marked updated" do
401
+ deploy_to_previous_rev_again.should be_updated_by_last_action
402
+ end
403
+
404
+ it "deploys the right code" do
405
+ IO.read(rel_path("current/app/app.rb")).should include("this is the third version of the app")
406
+ end
407
+
408
+ it "all_releases after first deploy should have one entry" do
409
+ @previous_rev_all_releases.length.should == 1
410
+ end
411
+
412
+ it "all_releases after second deploy should have two entries" do
413
+ @latest_rev_all_releases.length.should == 2
414
+ end
415
+
416
+ it "all_releases after rollback should have one entry" do
417
+ @previous_rev_again_all_releases.length.should == 1
418
+ end
419
+
420
+ it "all_releases after rollback should be the same as after the first deploy" do
421
+ @previous_rev_again_all_releases.should == @previous_rev_all_releases
422
+ end
423
+ end
424
+
425
+ describe "back to a previously deployed revision where resource rev == latest revision (explicit rollback)" do
426
+ before do
427
+ deploy_to_second_rev.run_action(:deploy)
428
+ @first_deploy_all_releases = deploy_to_second_rev.provider_for_action(:deploy).all_releases
429
+ deploy_to_previous_rev.run_action(:deploy)
430
+ @second_deploy_all_releases = deploy_to_previous_rev.provider_for_action(:deploy).all_releases
431
+ deploy_to_previous_rev_again.run_action(:rollback)
432
+ @third_deploy_all_releases = deploy_to_previous_rev_again.provider_for_action(:deploy).all_releases
433
+ deploy_to_latest_rev.run_action(:deploy)
434
+ @fourth_deploy_all_releases = deploy_to_latest_rev.provider_for_action(:deploy).all_releases
435
+ deploy_to_latest_rev_again.run_action(:rollback)
436
+ @fifth_deploy_all_releases = deploy_to_latest_rev_again.provider_for_action(:deploy).all_releases
437
+ end
438
+
439
+ the_app_is_deployed_at_revision(:second_rev)
440
+
441
+ it "restarts the application after rolling back" do
442
+ actual_operations_order.should == %w[deploy_to_second_rev deploy_to_previous_rev deploy_to_previous_rev_again deploy_to_latest_rev deploy_to_latest_rev_again]
443
+ end
444
+
445
+ it "is marked updated" do
446
+ deploy_to_latest_rev_again.should be_updated_by_last_action
447
+ end
448
+
449
+ it "deploys the right code" do
450
+ IO.read(rel_path("current/app/app.rb")).should include("this is the second version of the app")
451
+ end
452
+
453
+ it "all_releases after rollback should have one entry" do
454
+ @fifth_deploy_all_releases.length.should == 1
455
+ end
456
+
457
+ it "all_releases after rollback should be the same as after the first deploy" do
458
+ @fifth_deploy_all_releases.should == @first_deploy_all_releases
459
+ end
460
+ end
461
+
462
+ describe "back to a previously deployed revision where resource rev == latest revision (explicit rollback)" do
463
+ before do
464
+ deploy_to_second_rev.run_action(:deploy)
465
+ @first_deploy_all_releases = deploy_to_second_rev.provider_for_action(:deploy).all_releases
466
+ deploy_to_previous_rev.run_action(:deploy)
467
+ @second_deploy_all_releases = deploy_to_previous_rev.provider_for_action(:deploy).all_releases
468
+ deploy_to_second_rev_again.run_action(:rollback)
469
+ @third_deploy_all_releases = deploy_to_second_rev_again.provider_for_action(:deploy).all_releases
470
+ deploy_to_latest_rev.run_action(:deploy)
471
+ @fourth_deploy_all_releases = deploy_to_latest_rev.provider_for_action(:deploy).all_releases
472
+ deploy_to_second_rev_again_again.run_action(:rollback)
473
+ @fifth_deploy_all_releases = deploy_to_second_rev_again_again.provider_for_action(:deploy).all_releases
474
+ end
475
+
476
+ the_app_is_deployed_at_revision(:second_rev)
477
+
478
+ it "restarts the application after rolling back" do
479
+ actual_operations_order.should == %w[deploy_to_second_rev deploy_to_previous_rev deploy_to_second_rev_again deploy_to_latest_rev deploy_to_second_rev_again_again]
480
+ end
481
+
482
+ it "is marked updated" do
483
+ deploy_to_second_rev_again_again.should be_updated_by_last_action
484
+ end
485
+
486
+ it "deploys the right code" do
487
+ IO.read(rel_path("current/app/app.rb")).should include("this is the second version of the app")
488
+ end
489
+
490
+ it "all_releases after rollback should have one entry" do
491
+ @fifth_deploy_all_releases.length.should == 1
492
+ end
493
+
494
+ it "all_releases after rollback should be the same as after the first deploy" do
495
+ @fifth_deploy_all_releases.should == @first_deploy_all_releases
496
+ end
497
+
498
+ end
499
+
309
500
  # CHEF-3435
310
501
  describe "to a deploy_to path that does not yet exist" do
311
502