vagrant-conoha 0.1.0

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 (109) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rubocop.yml +35 -0
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +19 -0
  6. data/LICENSE +23 -0
  7. data/Rakefile +25 -0
  8. data/Vagrantfile +71 -0
  9. data/dummy.box +0 -0
  10. data/example_box/README.md +13 -0
  11. data/example_box/metadata.json +3 -0
  12. data/functional_tests/Vagrantfile +58 -0
  13. data/functional_tests/keys/vagrant-openstack +27 -0
  14. data/functional_tests/keys/vagrant-openstack.pub +1 -0
  15. data/functional_tests/run_tests.sh +142 -0
  16. data/lib/vagrant-conoha.rb +29 -0
  17. data/lib/vagrant-conoha/action.rb +227 -0
  18. data/lib/vagrant-conoha/action/abstract_action.rb +22 -0
  19. data/lib/vagrant-conoha/action/connect_openstack.rb +60 -0
  20. data/lib/vagrant-conoha/action/create_server.rb +154 -0
  21. data/lib/vagrant-conoha/action/create_stack.rb +68 -0
  22. data/lib/vagrant-conoha/action/delete_server.rb +53 -0
  23. data/lib/vagrant-conoha/action/delete_stack.rb +73 -0
  24. data/lib/vagrant-conoha/action/message.rb +19 -0
  25. data/lib/vagrant-conoha/action/provision.rb +60 -0
  26. data/lib/vagrant-conoha/action/read_ssh_info.rb +72 -0
  27. data/lib/vagrant-conoha/action/read_state.rb +43 -0
  28. data/lib/vagrant-conoha/action/resume.rb +24 -0
  29. data/lib/vagrant-conoha/action/start_server.rb +24 -0
  30. data/lib/vagrant-conoha/action/stop_server.rb +25 -0
  31. data/lib/vagrant-conoha/action/suspend.rb +24 -0
  32. data/lib/vagrant-conoha/action/sync_folders.rb +129 -0
  33. data/lib/vagrant-conoha/action/wait_accessible.rb +61 -0
  34. data/lib/vagrant-conoha/action/wait_active.rb +33 -0
  35. data/lib/vagrant-conoha/action/wait_stop.rb +33 -0
  36. data/lib/vagrant-conoha/catalog/openstack_catalog.rb +67 -0
  37. data/lib/vagrant-conoha/client/cinder.rb +39 -0
  38. data/lib/vagrant-conoha/client/domain.rb +159 -0
  39. data/lib/vagrant-conoha/client/glance.rb +65 -0
  40. data/lib/vagrant-conoha/client/heat.rb +49 -0
  41. data/lib/vagrant-conoha/client/http_utils.rb +116 -0
  42. data/lib/vagrant-conoha/client/keystone.rb +77 -0
  43. data/lib/vagrant-conoha/client/neutron.rb +48 -0
  44. data/lib/vagrant-conoha/client/nova.rb +212 -0
  45. data/lib/vagrant-conoha/client/openstack.rb +59 -0
  46. data/lib/vagrant-conoha/client/request_logger.rb +23 -0
  47. data/lib/vagrant-conoha/client/rest_utils.rb +25 -0
  48. data/lib/vagrant-conoha/command/abstract_command.rb +51 -0
  49. data/lib/vagrant-conoha/command/flavor_list.rb +24 -0
  50. data/lib/vagrant-conoha/command/image_list.rb +29 -0
  51. data/lib/vagrant-conoha/command/main.rb +51 -0
  52. data/lib/vagrant-conoha/command/network_list.rb +25 -0
  53. data/lib/vagrant-conoha/command/openstack_command.rb +16 -0
  54. data/lib/vagrant-conoha/command/reset.rb +20 -0
  55. data/lib/vagrant-conoha/command/subnet_list.rb +22 -0
  56. data/lib/vagrant-conoha/command/utils.rb +22 -0
  57. data/lib/vagrant-conoha/command/volume_list.rb +25 -0
  58. data/lib/vagrant-conoha/config.rb +390 -0
  59. data/lib/vagrant-conoha/config/http.rb +39 -0
  60. data/lib/vagrant-conoha/config_resolver.rb +285 -0
  61. data/lib/vagrant-conoha/errors.rb +187 -0
  62. data/lib/vagrant-conoha/logging.rb +39 -0
  63. data/lib/vagrant-conoha/plugin.rb +48 -0
  64. data/lib/vagrant-conoha/provider.rb +50 -0
  65. data/lib/vagrant-conoha/utils.rb +26 -0
  66. data/lib/vagrant-conoha/version.rb +15 -0
  67. data/lib/vagrant-conoha/version_checker.rb +76 -0
  68. data/locales/en.yml +393 -0
  69. data/spec/vagrant-conoha/action/connect_openstack_spec.rb +695 -0
  70. data/spec/vagrant-conoha/action/create_server_spec.rb +225 -0
  71. data/spec/vagrant-conoha/action/create_stack_spec.rb +99 -0
  72. data/spec/vagrant-conoha/action/delete_server_spec.rb +89 -0
  73. data/spec/vagrant-conoha/action/delete_stack_spec.rb +63 -0
  74. data/spec/vagrant-conoha/action/message_spec.rb +33 -0
  75. data/spec/vagrant-conoha/action/provision_spec.rb +104 -0
  76. data/spec/vagrant-conoha/action/read_ssh_info_spec.rb +190 -0
  77. data/spec/vagrant-conoha/action/read_state_spec.rb +81 -0
  78. data/spec/vagrant-conoha/action/resume_server_spec.rb +49 -0
  79. data/spec/vagrant-conoha/action/start_server_spec.rb +49 -0
  80. data/spec/vagrant-conoha/action/stop_server_spec.rb +49 -0
  81. data/spec/vagrant-conoha/action/suspend_server_spec.rb +49 -0
  82. data/spec/vagrant-conoha/action/sync_folders_spec.rb +155 -0
  83. data/spec/vagrant-conoha/action/wait_accessible_spec.rb +67 -0
  84. data/spec/vagrant-conoha/action/wait_active_spec.rb +53 -0
  85. data/spec/vagrant-conoha/action/wait_stop_spec.rb +53 -0
  86. data/spec/vagrant-conoha/action_spec.rb +120 -0
  87. data/spec/vagrant-conoha/client/cinder_spec.rb +127 -0
  88. data/spec/vagrant-conoha/client/glance_spec.rb +143 -0
  89. data/spec/vagrant-conoha/client/heat_spec.rb +128 -0
  90. data/spec/vagrant-conoha/client/keystone_spec.rb +150 -0
  91. data/spec/vagrant-conoha/client/neutron_spec.rb +171 -0
  92. data/spec/vagrant-conoha/client/nova_spec.rb +757 -0
  93. data/spec/vagrant-conoha/client/utils_spec.rb +176 -0
  94. data/spec/vagrant-conoha/command/flavor_list_spec.rb +43 -0
  95. data/spec/vagrant-conoha/command/image_list_spec.rb +95 -0
  96. data/spec/vagrant-conoha/command/network_list_spec.rb +65 -0
  97. data/spec/vagrant-conoha/command/reset_spec.rb +24 -0
  98. data/spec/vagrant-conoha/command/subnet_list_spec.rb +45 -0
  99. data/spec/vagrant-conoha/command/volume_list_spec.rb +40 -0
  100. data/spec/vagrant-conoha/config_resolver_spec.rb +860 -0
  101. data/spec/vagrant-conoha/config_spec.rb +373 -0
  102. data/spec/vagrant-conoha/e2e_spec.rb.save +27 -0
  103. data/spec/vagrant-conoha/provider_spec.rb +13 -0
  104. data/spec/vagrant-conoha/spec_helper.rb +37 -0
  105. data/spec/vagrant-conoha/utils_spec.rb +129 -0
  106. data/spec/vagrant-conoha/version_checker_spec.rb +39 -0
  107. data/stackrc +25 -0
  108. data/vagrant-conoha.gemspec +32 -0
  109. metadata +343 -0
@@ -0,0 +1,49 @@
1
+ require 'vagrant-conoha/spec_helper'
2
+
3
+ describe VagrantPlugins::ConoHa::Action::StartServer do
4
+ let(:nova) do
5
+ double('nova').tap do |nova|
6
+ nova.stub(:start_server)
7
+ end
8
+ end
9
+
10
+ let(:env) do
11
+ {}.tap do |env|
12
+ env[:ui] = double('ui').tap do |ui|
13
+ ui.stub(:info).with(anything)
14
+ ui.stub(:error).with(anything)
15
+ end
16
+ env[:openstack_client] = double('openstack_client').tap do |os|
17
+ os.stub(:nova) { nova }
18
+ end
19
+ env[:machine] = OpenStruct.new
20
+ end
21
+ end
22
+
23
+ let(:app) do
24
+ double('app').tap do |app|
25
+ app.stub(:call).with(anything)
26
+ end
27
+ end
28
+
29
+ describe 'call' do
30
+ context 'when server id is present' do
31
+ it 'starts the server' do
32
+ env[:machine].id = 'server_id'
33
+ expect(nova).to receive(:start_server).with(env, 'server_id')
34
+ expect(app).to receive(:call)
35
+ @action = StartServer.new(app, nil)
36
+ @action.call(env)
37
+ end
38
+ end
39
+ context 'when server id is not present' do
40
+ it 'does nothing' do
41
+ env[:machine].id = nil
42
+ expect(nova).to_not receive(:start_server)
43
+ expect(app).to receive(:call)
44
+ @action = StartServer.new(app, nil)
45
+ @action.call(env)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,49 @@
1
+ require 'vagrant-conoha/spec_helper'
2
+
3
+ describe VagrantPlugins::ConoHa::Action::StopServer do
4
+ let(:nova) do
5
+ double('nova').tap do |nova|
6
+ nova.stub(:stop_server)
7
+ end
8
+ end
9
+
10
+ let(:env) do
11
+ {}.tap do |env|
12
+ env[:ui] = double('ui').tap do |ui|
13
+ ui.stub(:info).with(anything)
14
+ ui.stub(:error).with(anything)
15
+ end
16
+ env[:openstack_client] = double('openstack_client').tap do |os|
17
+ os.stub(:nova) { nova }
18
+ end
19
+ env[:machine] = OpenStruct.new
20
+ end
21
+ end
22
+
23
+ let(:app) do
24
+ double('app').tap do |app|
25
+ app.stub(:call).with(anything)
26
+ end
27
+ end
28
+
29
+ describe 'call' do
30
+ context 'when server id is present' do
31
+ it 'stops the server' do
32
+ env[:machine].id = 'server_id'
33
+ expect(nova).to receive(:stop_server).with(env, 'server_id')
34
+ expect(app).to receive(:call)
35
+ @action = StopServer.new(app, nil)
36
+ @action.call(env)
37
+ end
38
+ end
39
+ context 'when server id is not present' do
40
+ it 'does nothing' do
41
+ env[:machine].id = nil
42
+ expect(nova).to_not receive(:stop_server)
43
+ expect(app).to receive(:call)
44
+ @action = StopServer.new(app, nil)
45
+ @action.call(env)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,49 @@
1
+ require 'vagrant-conoha/spec_helper'
2
+
3
+ describe VagrantPlugins::ConoHa::Action::Suspend do
4
+ let(:nova) do
5
+ double('nova').tap do |nova|
6
+ nova.stub(:suspend_server)
7
+ end
8
+ end
9
+
10
+ let(:env) do
11
+ {}.tap do |env|
12
+ env[:ui] = double('ui').tap do |ui|
13
+ ui.stub(:info).with(anything)
14
+ ui.stub(:error).with(anything)
15
+ end
16
+ env[:openstack_client] = double('openstack_client').tap do |os|
17
+ os.stub(:nova) { nova }
18
+ end
19
+ env[:machine] = OpenStruct.new
20
+ end
21
+ end
22
+
23
+ let(:app) do
24
+ double('app').tap do |app|
25
+ app.stub(:call).with(anything)
26
+ end
27
+ end
28
+
29
+ describe 'call' do
30
+ context 'when server id is present' do
31
+ it 'starts the server' do
32
+ env[:machine].id = 'server_id'
33
+ expect(nova).to receive(:suspend_server).with(env, 'server_id')
34
+ expect(app).to receive(:call)
35
+ @action = Suspend.new(app, nil)
36
+ @action.call(env)
37
+ end
38
+ end
39
+ context 'when server id is not present' do
40
+ it 'does nothing' do
41
+ env[:machine].id = nil
42
+ expect(nova).to_not receive(:suspend_server)
43
+ expect(app).to receive(:call)
44
+ @action = Suspend.new(app, nil)
45
+ @action.call(env)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,155 @@
1
+ require 'vagrant-conoha/spec_helper'
2
+ require 'log4r'
3
+ require 'rbconfig'
4
+ require 'vagrant/util/subprocess'
5
+
6
+ include VagrantPlugins::ConoHa::Action
7
+
8
+ describe VagrantPlugins::ConoHa::Action::SyncFolders do
9
+ let(:app) do
10
+ double('app').tap do |app|
11
+ app.stub(:call).with(anything)
12
+ end
13
+ end
14
+
15
+ let(:vm) do
16
+ double('vm').tap do |vm|
17
+ vm.stub(:synced_folders) { { '/vagrant' => { hostpath: '/home/john/vagrant', guestpath: '/vagrant' } } }
18
+ end
19
+ end
20
+
21
+ let(:provider_config) do
22
+ double('provider_config').tap do |c|
23
+ c.stub(:rsync_includes) { nil }
24
+ c.stub(:ssh_disabled) { false }
25
+ c.stub(:rsync_ignore_files) { ['.gitignore'] }
26
+ end
27
+ end
28
+
29
+ let(:communicate) do
30
+ double('communicate').tap do |c|
31
+ c.stub(:sudo)
32
+ end
33
+ end
34
+
35
+ let(:env) do
36
+ {}.tap do |env|
37
+ env[:ui] = double('ui').tap do |ui|
38
+ ui.stub(:info).with(anything)
39
+ ui.stub(:error).with(anything)
40
+ end
41
+ env[:openstack_client] = double('openstack_client').tap do |os|
42
+ os.stub(:nova) { nova }
43
+ end
44
+ env[:machine] = OpenStruct.new.tap do |m|
45
+ m.ssh_info = {
46
+ username: 'user',
47
+ port: '23',
48
+ host: '1.2.3.4',
49
+ private_key_path: '/tmp/key.pem'
50
+ }
51
+ m.provider_config = provider_config
52
+ m.config = double('config').tap do |c|
53
+ c.stub(:vm) { vm }
54
+ end
55
+ m.communicate = communicate
56
+ end
57
+ env[:root_path] = '.'
58
+ end
59
+ end
60
+
61
+ before :each do
62
+ @action = SyncFolders.new(app, nil)
63
+ end
64
+
65
+ describe 'call' do
66
+ context 'sync method is set to none and ssh_disabled is false' do
67
+ it 'does not sync folders' do
68
+ Vagrant::Util::Subprocess.stub(:execute)
69
+ provider_config.stub(:sync_method) { 'none' }
70
+ provider_config.stub(:ssh_disabled) { false }
71
+ expect(Vagrant::Util::Subprocess).to_not receive :execute
72
+ @action.call(env)
73
+ end
74
+ end
75
+ context 'sync method is set to none and ssh_disabled is true' do
76
+ it 'does not sync folders' do
77
+ Vagrant::Util::Subprocess.stub(:execute)
78
+ provider_config.stub(:sync_method) { 'none' }
79
+ provider_config.stub(:ssh_disabled) { true }
80
+ expect(Vagrant::Util::Subprocess).to_not receive :execute
81
+ @action.call(env)
82
+ end
83
+ end
84
+ context 'sync method is set to rsync and ssh_disabled is true' do
85
+ it 'does not sync folders' do
86
+ Vagrant::Util::Subprocess.stub(:execute)
87
+ provider_config.stub(:sync_method) { 'rsync' }
88
+ provider_config.stub(:ssh_disabled) { true }
89
+ expect(Vagrant::Util::Subprocess).to_not receive :execute
90
+ @action.call(env)
91
+ end
92
+ end
93
+ context 'sync method is set to rsync and ssh_disabled is false' do
94
+ it 'runs a rsync command' do
95
+ provider_config.stub(:sync_method) { 'rsync' }
96
+ Vagrant::Util::Subprocess.stub(:execute) do
97
+ OpenStruct.new.tap do |r|
98
+ r.exit_code = 0
99
+ r.stderr = nil
100
+ end
101
+ end
102
+ expected_command = ['rsync',
103
+ '--verbose',
104
+ '--archive',
105
+ '-z',
106
+ '--cvs-exclude',
107
+ '--exclude',
108
+ '.hg/',
109
+ '--exclude',
110
+ '.git/',
111
+ '--chmod',
112
+ 'ugo=rwX',
113
+ '-e',
114
+ "ssh -p 23 -o StrictHostKeyChecking=no -i '/tmp/key.pem' ",
115
+ '/home/john/vagrant/',
116
+ 'user@1.2.3.4:/vagrant',
117
+ '--exclude-from',
118
+ './.gitignore']
119
+ expect(communicate).to receive(:sudo).with "mkdir -p '/vagrant'"
120
+ expect(communicate).to receive(:sudo).with "chown -R user '/vagrant'"
121
+ expect(Vagrant::Util::Subprocess).to receive(:execute).with(*expected_command)
122
+ @action.call(env)
123
+ end
124
+ end
125
+ context 'rsync command returns a non zero status code' do
126
+ it 'raise an error' do
127
+ provider_config.stub(:sync_method) { 'rsync' }
128
+ Vagrant::Util::Subprocess.stub(:execute) do
129
+ OpenStruct.new.tap do |r|
130
+ r.exit_code = 1
131
+ r.stderr = 'Fatal error'
132
+ end
133
+ end
134
+ expect(Vagrant::Util::Subprocess).to receive(:execute)
135
+ expect { @action.call(env) }.to raise_error Errors::RsyncError
136
+ end
137
+ end
138
+ context 'sync method value is not valid' do
139
+ it 'raise an error' do
140
+ provider_config.stub(:sync_method) { 'nfs' }
141
+ expect { @action.call(env) }.to raise_error Errors::SyncMethodError
142
+ end
143
+ end
144
+ end
145
+
146
+ describe 'convert_path_to_windows_format' do
147
+ context 'hostpath in starting with C:/ ' do
148
+ it 'returns hostpath starting with /cygdrive/c/ and in downcase' do
149
+ RsyncFolders.send(:public, *RsyncFolders.private_instance_methods)
150
+ action = RsyncFolders.new(app, nil)
151
+ expect(action.add_cygdrive_prefix_to_path('C:/Directory')).to eq '/cygdrive/c/directory'
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,67 @@
1
+ require 'vagrant-conoha/spec_helper'
2
+
3
+ describe VagrantPlugins::ConoHa::Action::WaitForServerToBeAccessible do
4
+ let(:config) do
5
+ double('config')
6
+ end
7
+
8
+ let(:env) do
9
+ {}.tap do |env|
10
+ env[:ui] = double('ui')
11
+ env[:ui].stub(:info).with(anything)
12
+ env[:ui].stub(:error).with(anything)
13
+ env[:machine] = double('machine').tap do |m|
14
+ m.stub(:provider_config) { config }
15
+ end
16
+ end
17
+ end
18
+
19
+ let(:resolver) do
20
+ double('resolver').tap do |r|
21
+ r.stub(:resolve_floating_ip).with(anything) { '1.2.3.4' }
22
+ end
23
+ end
24
+
25
+ let(:ssh) do
26
+ double('shh')
27
+ end
28
+
29
+ let(:app) do
30
+ double('app').tap do |app|
31
+ app.stub(:call).with(anything)
32
+ end
33
+ end
34
+
35
+ class SSHMock
36
+ def initialize(*exit_codes)
37
+ @times = 0
38
+ @exit_codes = exit_codes
39
+ end
40
+
41
+ def call(env)
42
+ env[:ssh_run_exit_status] = @exit_codes[@times]
43
+ @times += 1
44
+ end
45
+ end
46
+
47
+ describe 'call' do
48
+ context 'when server is not yet reachable' do
49
+ it 'retry until server is reachable' do
50
+ config.stub(:ssh_timeout) { 2 }
51
+ expect(app).to receive(:call)
52
+
53
+ @action = WaitForServerToBeAccessible.new(app, nil, resolver, SSHMock.new(1, 0))
54
+ @action.call(env)
55
+ end
56
+ end
57
+ context 'when server is not yet reachable after timeout' do
58
+ it 'raise an error' do
59
+ config.stub(:ssh_timeout) { 1 }
60
+ expect(app).should_not_receive(:call)
61
+
62
+ @action = WaitForServerToBeAccessible.new(app, nil, resolver, SSHMock.new(1, 1))
63
+ expect { @action.call(env) }.to raise_error Errors::SshUnavailable
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,53 @@
1
+ require 'vagrant-conoha/spec_helper'
2
+
3
+ describe VagrantPlugins::ConoHa::Action::WaitForServerToBeActive do
4
+ let(:nova) do
5
+ double('nova')
6
+ end
7
+
8
+ let(:config) do
9
+ double('config')
10
+ end
11
+
12
+ let(:env) do
13
+ {}.tap do |env|
14
+ env[:ui] = double('ui').tap do |ui|
15
+ ui.stub(:info).with(anything)
16
+ ui.stub(:error).with(anything)
17
+ end
18
+ env[:openstack_client] = double('openstack_client').tap do |os|
19
+ os.stub(:nova) { nova }
20
+ end
21
+ env[:machine] = OpenStruct.new.tap do |m|
22
+ m.provider_config = config
23
+ m.id = 'server_id'
24
+ end
25
+ end
26
+ end
27
+
28
+ let(:app) do
29
+ double('app').tap do |app|
30
+ app.stub(:call).with(anything)
31
+ end
32
+ end
33
+
34
+ describe 'call' do
35
+ context 'when server is not yet active' do
36
+ it 'become active after one retry' do
37
+ nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, 'status' => 'ACTIVE')
38
+ expect(nova).to receive(:get_server_details).with(env, 'server_id').exactly(2).times
39
+ expect(app).to receive(:call)
40
+ config.stub(:server_active_timeout) { 5 }
41
+ @action = WaitForServerToBeActive.new(app, nil, 1)
42
+ @action.call(env)
43
+ end
44
+ it 'timeout after one retry' do
45
+ nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, 'status' => 'BUILD')
46
+ expect(nova).to receive(:get_server_details).with(env, 'server_id').at_least(2).times
47
+ config.stub(:server_active_timeout) { 2 }
48
+ @action = WaitForServerToBeActive.new(app, nil, 1)
49
+ expect { @action.call(env) }.to raise_error Errors::Timeout
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,53 @@
1
+ require 'vagrant-conoha/spec_helper'
2
+
3
+ describe VagrantPlugins::ConoHa::Action::WaitForServerToStop do
4
+ let(:nova) do
5
+ double('nova')
6
+ end
7
+
8
+ let(:config) do
9
+ double('config')
10
+ end
11
+
12
+ let(:env) do
13
+ {}.tap do |env|
14
+ env[:ui] = double('ui').tap do |ui|
15
+ ui.stub(:info).with(anything)
16
+ ui.stub(:error).with(anything)
17
+ end
18
+ env[:openstack_client] = double('openstack_client').tap do |os|
19
+ os.stub(:nova) { nova }
20
+ end
21
+ env[:machine] = OpenStruct.new.tap do |m|
22
+ m.provider_config = config
23
+ m.id = 'server_id'
24
+ end
25
+ end
26
+ end
27
+
28
+ let(:app) do
29
+ double('app').tap do |app|
30
+ app.stub(:call).with(anything)
31
+ end
32
+ end
33
+
34
+ describe 'call' do
35
+ context 'when server is active' do
36
+ it 'become shutoff after one retry' do
37
+ nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, 'status' => 'SHUTOFF')
38
+ expect(nova).to receive(:get_server_details).with(env, 'server_id').exactly(2).times
39
+ expect(app).to receive(:call)
40
+ config.stub(:server_stop_timeout) { 5 }
41
+ @action = WaitForServerToStop.new(app, nil, 1)
42
+ @action.call(env)
43
+ end
44
+ it 'timeout after one retry' do
45
+ nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, 'status' => 'ACTIVE')
46
+ expect(nova).to receive(:get_server_details).with(env, 'server_id').at_least(2).times
47
+ config.stub(:server_stop_timeout) { 2 }
48
+ @action = WaitForServerToStop.new(app, nil, 1)
49
+ expect { @action.call(env) }.to raise_error Errors::Timeout
50
+ end
51
+ end
52
+ end
53
+ end