vagrantup 0.5.2 → 0.5.3

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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -0
  3. data/CHANGELOG.md +48 -0
  4. data/Gemfile +16 -0
  5. data/Gemfile.lock +49 -0
  6. data/README.md +2 -2
  7. data/Rakefile +22 -0
  8. data/bin/.gitignore +0 -0
  9. data/lib/vagrant/provisioners/chef_solo.rb +1 -1
  10. data/lib/vagrant/util/template_renderer.rb +2 -2
  11. data/lib/vagrant/version.rb +1 -1
  12. data/templates/Vagrantfile.erb +1 -1
  13. data/templates/nfs/exports.erb +4 -2
  14. data/test/test_helper.rb +128 -0
  15. data/test/vagrant/action/box/destroy_test.rb +30 -0
  16. data/test/vagrant/action/box/download_test.rb +141 -0
  17. data/test/vagrant/action/box/package_test.rb +25 -0
  18. data/test/vagrant/action/box/unpackage_test.rb +103 -0
  19. data/test/vagrant/action/box/verify_test.rb +39 -0
  20. data/test/vagrant/action/builder_test.rb +218 -0
  21. data/test/vagrant/action/env/error_halt_test.rb +21 -0
  22. data/test/vagrant/action/env/set_test.rb +24 -0
  23. data/test/vagrant/action/environment_test.rb +45 -0
  24. data/test/vagrant/action/exception_catcher_test.rb +30 -0
  25. data/test/vagrant/action/general/package_test.rb +254 -0
  26. data/test/vagrant/action/vm/boot_test.rb +83 -0
  27. data/test/vagrant/action/vm/check_box_test.rb +48 -0
  28. data/test/vagrant/action/vm/check_guest_additions_test.rb +9 -0
  29. data/test/vagrant/action/vm/clean_machine_folder_test.rb +82 -0
  30. data/test/vagrant/action/vm/clear_forwarded_ports_test.rb +72 -0
  31. data/test/vagrant/action/vm/clear_nfs_exports_test.rb +22 -0
  32. data/test/vagrant/action/vm/clear_shared_folders_test.rb +49 -0
  33. data/test/vagrant/action/vm/customize_test.rb +29 -0
  34. data/test/vagrant/action/vm/destroy_test.rb +26 -0
  35. data/test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +46 -0
  36. data/test/vagrant/action/vm/disable_networks_test.rb +39 -0
  37. data/test/vagrant/action/vm/discard_state_test.rb +36 -0
  38. data/test/vagrant/action/vm/export_test.rb +135 -0
  39. data/test/vagrant/action/vm/forward_ports_helpers_test.rb +70 -0
  40. data/test/vagrant/action/vm/forward_ports_test.rb +191 -0
  41. data/test/vagrant/action/vm/halt_test.rb +69 -0
  42. data/test/vagrant/action/vm/import_test.rb +50 -0
  43. data/test/vagrant/action/vm/match_mac_address_test.rb +28 -0
  44. data/test/vagrant/action/vm/network_test.rb +246 -0
  45. data/test/vagrant/action/vm/nfs_helpers_test.rb +23 -0
  46. data/test/vagrant/action/vm/nfs_test.rb +269 -0
  47. data/test/vagrant/action/vm/package_test.rb +25 -0
  48. data/test/vagrant/action/vm/package_vagrantfile_test.rb +46 -0
  49. data/test/vagrant/action/vm/persist_test.rb +50 -0
  50. data/test/vagrant/action/vm/provision_test.rb +134 -0
  51. data/test/vagrant/action/vm/resume_test.rb +35 -0
  52. data/test/vagrant/action/vm/share_folders_test.rb +215 -0
  53. data/test/vagrant/action/vm/suspend_test.rb +35 -0
  54. data/test/vagrant/action_test.rb +111 -0
  55. data/test/vagrant/active_list_test.rb +173 -0
  56. data/test/vagrant/box_test.rb +166 -0
  57. data/test/vagrant/command_test.rb +53 -0
  58. data/test/vagrant/commands/base_test.rb +139 -0
  59. data/test/vagrant/commands/box/add_test.rb +34 -0
  60. data/test/vagrant/commands/box/list_test.rb +32 -0
  61. data/test/vagrant/commands/box/remove_test.rb +41 -0
  62. data/test/vagrant/commands/box/repackage_test.rb +52 -0
  63. data/test/vagrant/commands/destroy_test.rb +44 -0
  64. data/test/vagrant/commands/halt_test.rb +50 -0
  65. data/test/vagrant/commands/init_test.rb +71 -0
  66. data/test/vagrant/commands/package_test.rb +97 -0
  67. data/test/vagrant/commands/provision_test.rb +60 -0
  68. data/test/vagrant/commands/reload_test.rb +47 -0
  69. data/test/vagrant/commands/resume_test.rb +44 -0
  70. data/test/vagrant/commands/ssh_config_test.rb +77 -0
  71. data/test/vagrant/commands/ssh_test.rb +129 -0
  72. data/test/vagrant/commands/status_test.rb +40 -0
  73. data/test/vagrant/commands/suspend_test.rb +44 -0
  74. data/test/vagrant/commands/up_test.rb +49 -0
  75. data/test/vagrant/config_test.rb +307 -0
  76. data/test/vagrant/downloaders/base_test.rb +28 -0
  77. data/test/vagrant/downloaders/file_test.rb +33 -0
  78. data/test/vagrant/downloaders/http_test.rb +70 -0
  79. data/test/vagrant/environment_test.rb +770 -0
  80. data/test/vagrant/hosts/base_test.rb +46 -0
  81. data/test/vagrant/hosts/bsd_test.rb +56 -0
  82. data/test/vagrant/hosts/linux_test.rb +56 -0
  83. data/test/vagrant/provisioners/base_test.rb +36 -0
  84. data/test/vagrant/provisioners/chef_server_test.rb +182 -0
  85. data/test/vagrant/provisioners/chef_solo_test.rb +197 -0
  86. data/test/vagrant/provisioners/chef_test.rb +178 -0
  87. data/test/vagrant/ssh_session_test.rb +46 -0
  88. data/test/vagrant/ssh_test.rb +317 -0
  89. data/test/vagrant/systems/linux_test.rb +179 -0
  90. data/test/vagrant/util/busy_test.rb +106 -0
  91. data/test/vagrant/util/plain_logger_test.rb +17 -0
  92. data/test/vagrant/util/platform_test.rb +18 -0
  93. data/test/vagrant/util/resource_logger_test.rb +145 -0
  94. data/test/vagrant/util/stacked_proc_runner_test.rb +43 -0
  95. data/test/vagrant/util/template_renderer_test.rb +145 -0
  96. data/test/vagrant/util/translator_test.rb +61 -0
  97. data/test/vagrant/util_test.rb +27 -0
  98. data/test/vagrant/vm_test.rb +228 -0
  99. data/vagrant.gemspec +34 -0
  100. metadata +130 -9
@@ -0,0 +1,178 @@
1
+ require "test_helper"
2
+
3
+ class ChefProvisionerTest < Test::Unit::TestCase
4
+ setup do
5
+ @action_env = Vagrant::Action::Environment.new(mock_environment)
6
+ @action_env.env.vm = mock_vm
7
+
8
+ @action = Vagrant::Provisioners::Chef.new(@action_env)
9
+ @env = @action.env
10
+ @vm = @action.vm
11
+ end
12
+
13
+ context "preparing" do
14
+ should "error the environment" do
15
+ @action.prepare
16
+ assert @action_env.error?
17
+ assert_equal :chef_base_invalid_provisioner, @action_env.error.first
18
+ end
19
+ end
20
+
21
+ context "config" do
22
+ setup do
23
+ @config = Vagrant::Provisioners::Chef::ChefConfig.new
24
+ @config.run_list.clear
25
+ end
26
+
27
+ should "not include the 'json' key in the config dump" do
28
+ result = JSON.parse(@config.to_json)
29
+ assert !result.has_key?("json")
30
+ end
31
+
32
+ should "provide accessors to the run list" do
33
+ @config.run_list << "foo"
34
+ assert !@config.run_list.empty?
35
+ assert_equal ["foo"], @config.run_list
36
+ end
37
+
38
+ should "provide a writer for the run list" do
39
+ data = mock("data")
40
+
41
+ assert_nothing_raised {
42
+ @config.run_list = data
43
+ assert_equal data, @config.run_list
44
+ }
45
+ end
46
+
47
+ should "add a recipe to the run list" do
48
+ @config.add_recipe("foo")
49
+ assert_equal "recipe[foo]", @config.run_list[0]
50
+ end
51
+
52
+ should "not wrap the recipe in 'recipe[]' if it was in the name" do
53
+ @config.add_recipe("recipe[foo]")
54
+ assert_equal "recipe[foo]", @config.run_list[0]
55
+ end
56
+
57
+ should "add a role to the run list" do
58
+ @config.add_role("user")
59
+ assert_equal "role[user]", @config.run_list[0]
60
+ end
61
+
62
+ should "not wrap the role in 'role[]' if it was in the name" do
63
+ @config.add_role("role[user]")
64
+ assert_equal "role[user]", @config.run_list[0]
65
+ end
66
+ end
67
+
68
+ context "verifying binary" do
69
+ setup do
70
+ @ssh = mock("ssh")
71
+ @vm.ssh.stubs(:execute).yields(@ssh)
72
+ end
73
+
74
+ should "verify binary exists" do
75
+ binary = "foo"
76
+ @ssh.expects(:exec!).with("which #{binary}", :error_key => :chef_not_detected, :error_data => { :binary => binary }).once
77
+ @action.verify_binary(binary)
78
+ end
79
+ end
80
+ context "permissions on provisioning folder" do
81
+ should "create and chown the folder to the ssh user" do
82
+ ssh_seq = sequence("ssh_seq")
83
+ ssh = mock("ssh")
84
+ ssh.expects(:exec!).with("sudo mkdir -p #{@env.config.chef.provisioning_path}").once.in_sequence(ssh_seq)
85
+ ssh.expects(:exec!).with("sudo chown #{@env.config.ssh.username} #{@env.config.chef.provisioning_path}").once.in_sequence(ssh_seq)
86
+ @vm.ssh.expects(:execute).yields(ssh)
87
+ @action.chown_provisioning_folder
88
+ end
89
+ end
90
+
91
+ context "generating and uploading chef configuration file" do
92
+ setup do
93
+ @vm.ssh.stubs(:upload!)
94
+
95
+ @template = "template"
96
+ @filename = "foo.rb"
97
+
98
+ Vagrant::Util::TemplateRenderer.stubs(:render).returns("foo")
99
+ end
100
+
101
+ should "render and upload file" do
102
+ template_data = mock("data")
103
+ string_io = mock("string_io")
104
+ Vagrant::Util::TemplateRenderer.expects(:render).with(@template, anything).returns(template_data)
105
+ StringIO.expects(:new).with(template_data).returns(string_io)
106
+ File.expects(:join).with(@env.config.chef.provisioning_path, @filename).once.returns("bar")
107
+ @vm.ssh.expects(:upload!).with(string_io, "bar")
108
+
109
+ @action.setup_config(@template, @filename, {})
110
+ end
111
+
112
+ should "provide log level by default" do
113
+ Vagrant::Util::TemplateRenderer.expects(:render).returns("foo").with() do |template, vars|
114
+ assert vars.has_key?(:log_level)
115
+ assert_equal @env.config.chef.log_level.to_sym, vars[:log_level]
116
+ true
117
+ end
118
+
119
+ @action.setup_config(@template, @filename, {})
120
+ end
121
+
122
+ should "allow custom template variables" do
123
+ custom = {
124
+ :foo => "bar",
125
+ :int => 7
126
+ }
127
+
128
+ Vagrant::Util::TemplateRenderer.expects(:render).returns("foo").with() do |template, vars|
129
+ custom.each do |key, value|
130
+ assert vars.has_key?(key)
131
+ assert_equal value, vars[key]
132
+ end
133
+
134
+ true
135
+ end
136
+
137
+ @action.setup_config(@template, @filename, custom)
138
+ end
139
+ end
140
+
141
+ context "generating and uploading json" do
142
+ def assert_json
143
+ @vm.ssh.expects(:upload!).with do |json, path|
144
+ data = JSON.parse(json.read)
145
+ yield data
146
+ true
147
+ end
148
+
149
+ @action.setup_json
150
+ end
151
+
152
+ should "merge in the extra json specified in the config" do
153
+ @env.config.chef.json = { :foo => "BAR" }
154
+ assert_json do |data|
155
+ assert_equal "BAR", data["foo"]
156
+ end
157
+ end
158
+
159
+ should "add the directory as a special case to the JSON" do
160
+ assert_json do |data|
161
+ assert_equal @env.config.vm.shared_folders["v-root"][:guestpath], data["vagrant"]["directory"]
162
+ end
163
+ end
164
+
165
+ should "add the config to the JSON" do
166
+ assert_json do |data|
167
+ assert_equal @env.config.ssh.username, data["vagrant"]["config"]["ssh"]["username"]
168
+ end
169
+ end
170
+
171
+ should "upload a StringIO to dna.json" do
172
+ StringIO.expects(:new).with(anything).returns("bar")
173
+ File.expects(:join).with(@env.config.chef.provisioning_path, "dna.json").once.returns("baz")
174
+ @vm.ssh.expects(:upload!).with("bar", "baz").once
175
+ @action.setup_json
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,46 @@
1
+ require "test_helper"
2
+
3
+ class SshSessionTest < Test::Unit::TestCase
4
+ setup do
5
+ @session = mock("session")
6
+
7
+ @klass = Vagrant::SSH::Session
8
+ @instance = @klass.new(@session)
9
+ end
10
+
11
+ context "exec!" do
12
+ should "retry 5 times" do
13
+ @session.expects(:open_channel).times(5).raises(IOError)
14
+ assert_raises(IOError) {
15
+ @instance.exec!("foo")
16
+ }
17
+ end
18
+ end
19
+
20
+ context "checking exit status" do
21
+ should "raise an ActionException if its non-zero" do
22
+ assert_raises(Vagrant::Action::ActionException) {
23
+ @instance.check_exit_status(1, "foo")
24
+ }
25
+ end
26
+
27
+ should "raise the given exception if specified" do
28
+ options = {
29
+ :error_key => :foo,
30
+ :error_data => {}
31
+ }
32
+ result = Exception.new
33
+ Vagrant::Action::ActionException.expects(:new).with(options[:error_key], options[:error_data]).once.returns(result)
34
+
35
+ assert_raises(Exception) {
36
+ @instance.check_exit_status(1, "foo", options)
37
+ }
38
+ end
39
+
40
+ should "raise nothing if its zero" do
41
+ assert_nothing_raised {
42
+ @instance.check_exit_status(0, "foo")
43
+ }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,317 @@
1
+ require "test_helper"
2
+
3
+ class SshTest < Test::Unit::TestCase
4
+ def mock_ssh
5
+ @env = mock_environment do |config|
6
+ yield config if block_given?
7
+ end
8
+
9
+ @forwarded_ports = []
10
+ @network_adapters = []
11
+ @vm = mock("vm")
12
+ @vm.stubs(:network_adapters).returns(@network_adapters)
13
+
14
+ @env.stubs(:vm).returns(mock_vm(@env))
15
+ @env.vm.stubs(:vm).returns(@vm)
16
+
17
+ @ssh = Vagrant::SSH.new(@env)
18
+ end
19
+
20
+ setup do
21
+ VirtualBox.stubs(:version).returns("3.1.4")
22
+ end
23
+
24
+ context "connecting to external SSH" do
25
+ setup do
26
+ mock_ssh
27
+ @ssh.stubs(:check_key_permissions)
28
+ @ssh.stubs(:error_and_exit)
29
+ Kernel.stubs(:exec)
30
+
31
+ Vagrant::Util::Platform.stubs(:leopard?).returns(false)
32
+ end
33
+
34
+ should "check key permissions prior to exec" do
35
+ exec_seq = sequence("exec_seq")
36
+ @ssh.expects(:check_key_permissions).with(@env.config.ssh.private_key_path).once.in_sequence(exec_seq)
37
+ Kernel.expects(:exec).in_sequence(exec_seq)
38
+ @ssh.connect
39
+ end
40
+
41
+ should "call exec with defaults when no options are supplied" do
42
+ ssh_exec_expect(@ssh.port,
43
+ @env.config.ssh.private_key_path,
44
+ @env.config.ssh.username,
45
+ @env.config.ssh.host)
46
+ @ssh.connect
47
+ end
48
+
49
+ should "call exec with supplied params" do
50
+ args = {:username => 'bar', :private_key_path => 'baz', :host => 'bak', :port => 'bag'}
51
+ ssh_exec_expect(args[:port], args[:private_key_path], args[:username], args[:host])
52
+ @ssh.connect(args)
53
+ end
54
+
55
+ should "add forward agent option if enabled" do
56
+ @env.config.ssh.forward_agent = true
57
+ ssh_exec_expect(@ssh.port,
58
+ @env.config.ssh.private_key_path,
59
+ @env.config.ssh.username,
60
+ @env.config.ssh.host) do |args|
61
+ assert args =~ /-o ForwardAgent=yes/
62
+ end
63
+ @ssh.connect
64
+ end
65
+
66
+ context "on leopard" do
67
+ setup do
68
+ Vagrant::Util::Platform.stubs(:leopard?).returns(true)
69
+ end
70
+
71
+ should "fork, exec, and wait" do
72
+ pid = mock("pid")
73
+ @ssh.expects(:fork).once.returns(pid)
74
+ Process.expects(:wait).with(pid)
75
+
76
+ @ssh.connect
77
+ end
78
+ end
79
+
80
+ context "checking windows" do
81
+ should "error and exit if the platform is windows" do
82
+ Mario::Platform.expects(:windows?).returns(true)
83
+ @ssh.expects(:error_and_exit).with do |error_name, opts|
84
+ opts[:key_path] && opts[:ssh_port]
85
+ end
86
+ @ssh.connect
87
+ end
88
+
89
+ should "not error and exit if the platform is anything other that windows" do
90
+ Mario::Platform.expects(:windows?).returns(false)
91
+ @ssh.expects(:error_and_exit).never
92
+ @ssh.connect
93
+ end
94
+ end
95
+
96
+ def ssh_exec_expect(port, key_path, uname, host)
97
+ Kernel.expects(:exec).with() do |arg|
98
+ assert arg =~ /^ssh/
99
+ assert arg =~ /-p #{port}/
100
+ assert arg =~ /-i #{key_path}/
101
+ assert arg =~ /#{uname}@#{host}/
102
+ yield arg if block_given?
103
+ true
104
+ end
105
+ end
106
+ end
107
+
108
+ context "executing ssh commands" do
109
+ setup do
110
+ mock_ssh
111
+ @ssh.stubs(:check_key_permissions)
112
+ @ssh.stubs(:port).returns(80)
113
+ end
114
+
115
+ should "check key permissions then attempt to start connection" do
116
+ seq = sequence("seq")
117
+ @ssh.expects(:check_key_permissions).with(@env.config.ssh.private_key_path).once.in_sequence(seq)
118
+ Net::SSH.expects(:start).once.in_sequence(seq)
119
+ @ssh.execute
120
+ end
121
+
122
+ should "call net::ssh.start with the proper names" do
123
+ Net::SSH.expects(:start).once.with() do |host, username, opts|
124
+ assert_equal @env.config.ssh.host, host
125
+ assert_equal @env.config.ssh.username, username
126
+ assert_equal @ssh.port, opts[:port]
127
+ assert_equal [@env.config.ssh.private_key_path], opts[:keys]
128
+ true
129
+ end
130
+ @ssh.execute
131
+ end
132
+
133
+ should "forward agent if configured" do
134
+ @env.config.ssh.forward_agent = true
135
+ Net::SSH.expects(:start).once.with() do |host, username, opts|
136
+ assert opts[:forward_agent]
137
+ true
138
+ end
139
+
140
+ @ssh.execute
141
+ end
142
+
143
+ should "use custom host if set" do
144
+ @env.config.ssh.host = "foo"
145
+ Net::SSH.expects(:start).with(@env.config.ssh.host, @env.config.ssh.username, anything).once
146
+ @ssh.execute
147
+ end
148
+
149
+ should "yield an SSH session object" do
150
+ raw = mock("raw")
151
+ Net::SSH.expects(:start).yields(raw)
152
+ @ssh.execute do |ssh|
153
+ assert ssh.is_a?(Vagrant::SSH::Session)
154
+ assert_equal raw, ssh.session
155
+ end
156
+ end
157
+ end
158
+
159
+ context "SCPing files to the remote host" do
160
+ setup do
161
+ mock_ssh
162
+ end
163
+
164
+ should "use Vagrant::SSH execute to setup an SCP connection and upload" do
165
+ scp = mock("scp")
166
+ ssh = mock("ssh")
167
+ sess = mock("session")
168
+ ssh.stubs(:session).returns(sess)
169
+ scp.expects(:upload!).with("foo", "bar").once
170
+ Net::SCP.expects(:new).with(ssh.session).returns(scp).once
171
+ @ssh.expects(:execute).yields(ssh).once
172
+ @ssh.upload!("foo", "bar")
173
+ end
174
+
175
+ should "retry 5 times" do
176
+ @ssh.expects(:execute).times(5).raises(IOError)
177
+ assert_raises(IOError) {
178
+ @ssh.upload!("foo", "bar")
179
+ }
180
+ end
181
+ end
182
+
183
+ context "checking if host is up" do
184
+ setup do
185
+ mock_ssh
186
+ @ssh.stubs(:check_key_permissions)
187
+ end
188
+
189
+ should "return true if SSH connection works" do
190
+ Net::SSH.expects(:start).yields("success")
191
+ assert @ssh.up?
192
+ end
193
+
194
+ should "return false if SSH connection times out" do
195
+ Net::SSH.expects(:start)
196
+ assert !@ssh.up?
197
+ end
198
+
199
+ should "allow the thread the configured timeout time" do
200
+ @thread = mock("thread")
201
+ @thread.stubs(:[])
202
+ Thread.expects(:new).returns(@thread)
203
+ @thread.expects(:join).with(@env.config.ssh.timeout).once
204
+ @ssh.up?
205
+ end
206
+
207
+ should "return false if the connection is refused" do
208
+ Net::SSH.expects(:start).raises(Errno::ECONNREFUSED)
209
+ assert_nothing_raised {
210
+ assert !@ssh.up?
211
+ }
212
+ end
213
+
214
+ should "return false if the connection is dropped" do
215
+ Net::SSH.expects(:start).raises(Net::SSH::Disconnect)
216
+ assert_nothing_raised {
217
+ assert !@ssh.up?
218
+ }
219
+ end
220
+
221
+ should "specifity the timeout as an option to execute" do
222
+ @ssh.expects(:execute).with(:timeout => @env.config.ssh.timeout).yields(true)
223
+ assert @ssh.up?
224
+ end
225
+
226
+ should "error and exit if a Net::SSH::AuthenticationFailed is raised" do
227
+ @ssh.expects(:execute).raises(Net::SSH::AuthenticationFailed)
228
+ @ssh.expects(:error_and_exit).with(:vm_ssh_auth_failed).once
229
+ @ssh.up?
230
+ end
231
+ end
232
+
233
+ context "getting the ssh port" do
234
+ setup do
235
+ mock_ssh
236
+ end
237
+
238
+ should "return the port given in options if it exists" do
239
+ assert_equal "47", @ssh.port({ :port => "47" })
240
+ end
241
+ end
242
+
243
+ context "checking key permissions" do
244
+ setup do
245
+ mock_ssh
246
+ @ssh.stubs(:file_perms)
247
+
248
+ @key_path = "foo"
249
+
250
+
251
+ @stat = mock("stat")
252
+ @stat.stubs(:owned?).returns(true)
253
+ File.stubs(:stat).returns(@stat)
254
+
255
+ Mario::Platform.stubs(:windows?).returns(false)
256
+ end
257
+
258
+ should "do nothing if on windows" do
259
+ Mario::Platform.stubs(:windows?).returns(true)
260
+ File.expects(:stat).never
261
+ @ssh.check_key_permissions(@key_path)
262
+ end
263
+
264
+ should "do nothing if the user is not the owner" do
265
+ @stat.expects(:owned?).returns(false)
266
+ File.expects(:chmod).never
267
+ @ssh.check_key_permissions(@key_path)
268
+ end
269
+
270
+ should "do nothing if the file perms equal 600" do
271
+ @ssh.expects(:file_perms).with(@key_path).returns("600")
272
+ File.expects(:chmod).never
273
+ @ssh.check_key_permissions(@key_path)
274
+ end
275
+
276
+ should "chmod the file if the file perms aren't 600" do
277
+ perm_sequence = sequence("perm_seq")
278
+ @ssh.expects(:file_perms).returns("900").in_sequence(perm_sequence)
279
+ File.expects(:chmod).with(0600, @key_path).once.in_sequence(perm_sequence)
280
+ @ssh.expects(:file_perms).returns("600").in_sequence(perm_sequence)
281
+ @ssh.expects(:error_and_exit).never
282
+ @ssh.check_key_permissions(@key_path)
283
+ end
284
+
285
+ should "error and exit if the resulting chmod doesn't work" do
286
+ perm_sequence = sequence("perm_seq")
287
+ @ssh.expects(:file_perms).returns("900").in_sequence(perm_sequence)
288
+ File.expects(:chmod).with(0600, @key_path).once.in_sequence(perm_sequence)
289
+ @ssh.expects(:file_perms).returns("900").in_sequence(perm_sequence)
290
+ @ssh.expects(:error_and_exit).once.with(:ssh_bad_permissions, :key_path => @key_path).in_sequence(perm_sequence)
291
+ @ssh.check_key_permissions(@key_path)
292
+ end
293
+
294
+ should "error and exit if a bad file perm is raised" do
295
+ @ssh.expects(:file_perms).with(@key_path).returns("900")
296
+ File.expects(:chmod).raises(Errno::EPERM)
297
+ @ssh.expects(:error_and_exit).once.with(:ssh_bad_permissions, :key_path => @key_path)
298
+ @ssh.check_key_permissions(@key_path)
299
+ end
300
+ end
301
+
302
+ context "getting file permissions" do
303
+ setup do
304
+ mock_ssh
305
+ end
306
+
307
+ should "return the last 3 characters of the file mode" do
308
+ path = "foo"
309
+ mode = "10000foo"
310
+ stat = mock("stat")
311
+ File.expects(:stat).with(path).returns(stat)
312
+ stat.expects(:mode).returns(mode)
313
+ @ssh.expects(:sprintf).with("%o", mode).returns(mode)
314
+ assert_equal path, @ssh.file_perms(path)
315
+ end
316
+ end
317
+ end