sunshine 1.2.0 → 1.2.1
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.
- data/History.txt +26 -0
- data/Manifest.txt +1 -0
- data/bin/sunshine +8 -1
- data/lib/commands/list.rb +11 -6
- data/lib/commands/restart.rb +6 -5
- data/lib/commands/rm.rb +6 -5
- data/lib/commands/script.rb +5 -4
- data/lib/commands/start.rb +7 -6
- data/lib/commands/stop.rb +6 -5
- data/lib/sunshine.rb +68 -50
- data/lib/sunshine/app.rb +269 -55
- data/lib/sunshine/daemon.rb +72 -18
- data/lib/sunshine/dependency_lib.rb +0 -2
- data/lib/sunshine/exceptions.rb +35 -17
- data/lib/sunshine/package_managers/apt.rb +1 -1
- data/lib/sunshine/package_managers/dependency.rb +0 -5
- data/lib/sunshine/package_managers/yum.rb +1 -1
- data/lib/sunshine/remote_shell.rb +21 -5
- data/lib/sunshine/repo.rb +5 -6
- data/lib/sunshine/repos/rsync_repo.rb +1 -1
- data/lib/sunshine/server_app.rb +146 -14
- data/lib/sunshine/shell.rb +49 -24
- data/lib/sunshine/trap_stack.rb +54 -0
- data/templates/nginx/nginx.conf.erb +24 -0
- data/test/helper_methods.rb +1 -1
- data/test/unit/test_app.rb +48 -6
- data/test/unit/test_daemon.rb +3 -3
- data/test/unit/test_nginx.rb +7 -4
- data/test/unit/test_server.rb +6 -6
- data/test/unit/test_server_app.rb +107 -9
- metadata +8 -7
data/lib/sunshine/shell.rb
CHANGED
@@ -7,13 +7,23 @@ module Sunshine
|
|
7
7
|
|
8
8
|
include Open4
|
9
9
|
|
10
|
-
class TimeoutError < CriticalDeployError; end
|
11
|
-
|
12
10
|
LOCAL_USER = `whoami`.chomp
|
13
11
|
LOCAL_HOST = `hostname`.chomp
|
14
12
|
|
15
|
-
|
16
|
-
|
13
|
+
class << self
|
14
|
+
# The message to match in stderr to determine logging in has failed.
|
15
|
+
# Defaults to:
|
16
|
+
# /^Sorry, try again./
|
17
|
+
attr_accessor :sudo_failed_matcher
|
18
|
+
|
19
|
+
# The message to match in stderr to determine a password is required.
|
20
|
+
# Defaults to:
|
21
|
+
# /^Password:/
|
22
|
+
attr_accessor :sudo_prompt_matcher
|
23
|
+
end
|
24
|
+
|
25
|
+
self.sudo_failed_matcher = /^Sorry, try again./
|
26
|
+
self.sudo_prompt_matcher = /^Password:/
|
17
27
|
|
18
28
|
attr_reader :user, :host, :password, :input, :output, :mutex
|
19
29
|
attr_accessor :env, :sudo, :timeout
|
@@ -33,8 +43,6 @@ module Sunshine
|
|
33
43
|
|
34
44
|
@timeout = options[:timeout] || Sunshine.timeout
|
35
45
|
|
36
|
-
@cmd_activity = nil
|
37
|
-
|
38
46
|
@mutex = nil
|
39
47
|
end
|
40
48
|
|
@@ -73,6 +81,14 @@ module Sunshine
|
|
73
81
|
end
|
74
82
|
|
75
83
|
|
84
|
+
##
|
85
|
+
# Prompt the user to make a choice.
|
86
|
+
|
87
|
+
def choose &block
|
88
|
+
sync{ @input.choose(&block) }
|
89
|
+
end
|
90
|
+
|
91
|
+
|
76
92
|
##
|
77
93
|
# Close the output IO. (Required by the Logger class)
|
78
94
|
|
@@ -133,6 +149,21 @@ module Sunshine
|
|
133
149
|
end
|
134
150
|
|
135
151
|
|
152
|
+
##
|
153
|
+
# Start an interactive shell with preset permissions and env.
|
154
|
+
# Optionally pass a command to be run first.
|
155
|
+
|
156
|
+
def tty! cmd=nil
|
157
|
+
sync do
|
158
|
+
cmd = [cmd, "sh -il"].compact.join " && "
|
159
|
+
pid = fork do
|
160
|
+
exec sudo_cmd(env_cmd(cmd)).to_a.join(" ")
|
161
|
+
end
|
162
|
+
Process.waitpid pid
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
|
136
167
|
##
|
137
168
|
# Write a file. Compatibility method with RemoteShell.
|
138
169
|
|
@@ -237,7 +268,7 @@ module Sunshine
|
|
237
268
|
##
|
238
269
|
# Returns true if command was run successfully, otherwise returns false.
|
239
270
|
|
240
|
-
def
|
271
|
+
def system cmd, options=nil
|
241
272
|
call(cmd, options) && true rescue false
|
242
273
|
end
|
243
274
|
|
@@ -245,20 +276,12 @@ module Sunshine
|
|
245
276
|
##
|
246
277
|
# Checks if timeout occurred.
|
247
278
|
|
248
|
-
def timed_out? start_time
|
279
|
+
def timed_out? start_time, max_time=@timeout
|
249
280
|
return unless max_time
|
250
281
|
Time.now.to_i - start_time.to_i > max_time
|
251
282
|
end
|
252
283
|
|
253
284
|
|
254
|
-
##
|
255
|
-
# Update the time of the last command activity
|
256
|
-
|
257
|
-
def update_timeout
|
258
|
-
@cmd_activity = Time.now
|
259
|
-
end
|
260
|
-
|
261
|
-
|
262
285
|
##
|
263
286
|
# Execute a block while setting the shell's mutex.
|
264
287
|
# Sets the mutex to its original value on exit.
|
@@ -319,7 +342,9 @@ module Sunshine
|
|
319
342
|
log_methods = {out => :debug, err => :error}
|
320
343
|
|
321
344
|
result, status = process_streams(pid, out, err) do |stream, data|
|
322
|
-
stream_name = stream == out
|
345
|
+
stream_name = :out if stream == out
|
346
|
+
stream_name = :err if stream == err
|
347
|
+
stream_name = :inn if stream == inn
|
323
348
|
|
324
349
|
|
325
350
|
# User blocks should run with sync threads to avoid badness.
|
@@ -353,18 +378,18 @@ module Sunshine
|
|
353
378
|
private
|
354
379
|
|
355
380
|
def raise_command_failed(status, cmd)
|
356
|
-
|
357
|
-
|
381
|
+
err = CmdError.new status.exitstatus, [*cmd].join(" ")
|
382
|
+
raise err
|
358
383
|
end
|
359
384
|
|
360
385
|
|
361
386
|
def password_required? stream_name, data
|
362
|
-
stream_name == :err && data =~
|
387
|
+
stream_name == :err && data =~ Shell.sudo_prompt_matcher
|
363
388
|
end
|
364
389
|
|
365
390
|
|
366
391
|
def send_password_to_stream inn, data
|
367
|
-
prompt_for_password if data =~
|
392
|
+
prompt_for_password if data =~ Shell.sudo_failed_matcher
|
368
393
|
inn.puts @password || prompt_for_password
|
369
394
|
end
|
370
395
|
|
@@ -380,7 +405,7 @@ module Sunshine
|
|
380
405
|
|
381
406
|
def process_streams pid, *streams
|
382
407
|
result = Hash.new{|h,k| h[k] = []}
|
383
|
-
|
408
|
+
start_time = Time.now
|
384
409
|
|
385
410
|
# Handle process termination ourselves
|
386
411
|
status = nil
|
@@ -392,13 +417,13 @@ module Sunshine
|
|
392
417
|
# don't busy loop
|
393
418
|
selected, = select streams, nil, nil, 0.1
|
394
419
|
|
395
|
-
raise TimeoutError if timed_out?
|
420
|
+
raise TimeoutError if timed_out? start_time
|
396
421
|
|
397
422
|
next if selected.nil? or selected.empty?
|
398
423
|
|
399
424
|
selected.each do |stream|
|
400
425
|
|
401
|
-
|
426
|
+
start_time = Time.now
|
402
427
|
|
403
428
|
if stream.eof? then
|
404
429
|
streams.delete stream if status # we've quit, so no more writing
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Sunshine
|
2
|
+
|
3
|
+
##
|
4
|
+
# The TrapStack class handles setting multiple trap blocks as a stack.
|
5
|
+
# Once a trap block is triggered, it gets popped off the stack.
|
6
|
+
|
7
|
+
class TrapStack
|
8
|
+
|
9
|
+
##
|
10
|
+
# Adds an INT signal trap with its description on the stack.
|
11
|
+
# Returns a trap_item Array.
|
12
|
+
|
13
|
+
def self.add_trap desc=nil, &block
|
14
|
+
@trap_stack.unshift [desc, block]
|
15
|
+
@trap_stack.first
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
##
|
21
|
+
# Call a trap item and display it's message.
|
22
|
+
|
23
|
+
def self.call_trap trap_item
|
24
|
+
return unless trap_item
|
25
|
+
|
26
|
+
msg, trap_block = trap_item
|
27
|
+
|
28
|
+
yield msg if block_given?
|
29
|
+
|
30
|
+
trap_block.call
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
##
|
35
|
+
# Remove a trap_item from the stack.
|
36
|
+
|
37
|
+
def self.delete_trap trap_item
|
38
|
+
@trap_stack.delete trap_item
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
##
|
43
|
+
# Sets the default trap.
|
44
|
+
|
45
|
+
def self.trap_signal sig, &block
|
46
|
+
@trap_stack = []
|
47
|
+
|
48
|
+
trap sig do
|
49
|
+
call_trap @trap_stack.shift, &block
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -25,7 +25,31 @@ http {
|
|
25
25
|
client_body_temp_path <%= darwin ? '/var/tmp/nginx' : '/dev/shm' %>;
|
26
26
|
proxy_temp_path <%= darwin ? '/var/tmp/nginx' : '/dev/shm' %>;
|
27
27
|
|
28
|
+
<%
|
29
|
+
mime_types = "#{File.dirname(shell.call("which nginx"))}/../conf/mime.types"
|
30
|
+
|
31
|
+
if shell.file? mime_types
|
32
|
+
-%>
|
28
33
|
include <%= File.dirname shell.call("which nginx") %>/../conf/mime.types;
|
34
|
+
|
35
|
+
<% else -%>
|
36
|
+
|
37
|
+
types {
|
38
|
+
application/x-plist plist;
|
39
|
+
application/json json;
|
40
|
+
image/gif gif;
|
41
|
+
image/jpeg jpg;
|
42
|
+
image/png png;
|
43
|
+
image/x-icon ico;
|
44
|
+
text/css css;
|
45
|
+
text/html html;
|
46
|
+
text/plain bob;
|
47
|
+
text/plain txt;
|
48
|
+
application/vnd.android.package-archive apk;
|
49
|
+
}
|
50
|
+
|
51
|
+
<% end -%>
|
52
|
+
|
29
53
|
default_type application/octet-stream;
|
30
54
|
|
31
55
|
log_format sunshine '$remote_addr - $remote_user [$time_local] '
|
data/test/helper_methods.rb
CHANGED
@@ -123,7 +123,7 @@ fi
|
|
123
123
|
"--rsync-path='#{ path }' "
|
124
124
|
end
|
125
125
|
|
126
|
-
rsync_cmd = "rsync -
|
126
|
+
rsync_cmd = "rsync -azrP #{rsync_path}-e \"ssh #{ds.ssh_flags.join(' ')}\""
|
127
127
|
|
128
128
|
error_msg = "No such command in remote_shell log [#{ds.host}]\n#{rsync_cmd}"
|
129
129
|
error_msg << "#{from.inspect} #{to.inspect}"
|
data/test/unit/test_app.rb
CHANGED
@@ -26,6 +26,7 @@ class TestApp < Test::Unit::TestCase
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def teardown
|
29
|
+
Sunshine.exclude_paths.clear
|
29
30
|
FileUtils.rm_rf @tmpdir
|
30
31
|
end
|
31
32
|
|
@@ -159,8 +160,7 @@ class TestApp < Test::Unit::TestCase
|
|
159
160
|
|
160
161
|
def test_app_deploy_error_handling
|
161
162
|
[ MockError,
|
162
|
-
Sunshine::
|
163
|
-
Sunshine::FatalDeployError ].each do |error|
|
163
|
+
Sunshine::DeployError ].each do |error|
|
164
164
|
|
165
165
|
begin
|
166
166
|
app = Sunshine::App.deploy @config do |app|
|
@@ -277,9 +277,51 @@ class TestApp < Test::Unit::TestCase
|
|
277
277
|
end
|
278
278
|
|
279
279
|
|
280
|
+
def test_checkout_local_codebase
|
281
|
+
tmp_path = File.join Sunshine::TMP_DIR, "#{@app.name}_checkout"
|
282
|
+
@app.repo.extend MockObject
|
283
|
+
@app.repo.mock :checkout_to, :args => [tmp_path],
|
284
|
+
:return => {:test => "scm info"}
|
285
|
+
|
286
|
+
@app.each do |sa|
|
287
|
+
sa.mock :upload_codebase
|
288
|
+
end
|
289
|
+
|
290
|
+
@app.checkout_codebase :copy => true
|
291
|
+
|
292
|
+
@app.each do |sa|
|
293
|
+
assert sa.method_called?(:upload_codebase,
|
294
|
+
:args => [tmp_path, {:test => "scm info", :exclude => []}])
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
def test_checkout_local_codebase_with_exludes
|
300
|
+
Sunshine.exclude_paths.concat ["path1/", "path2/"]
|
301
|
+
|
302
|
+
tmp_path = File.join Sunshine::TMP_DIR, "#{@app.name}_checkout"
|
303
|
+
@app.repo.extend MockObject
|
304
|
+
|
305
|
+
@app.repo.mock :checkout_to, :args => [tmp_path],
|
306
|
+
:return => {:test => "scm info"}
|
307
|
+
|
308
|
+
@app.each do |sa|
|
309
|
+
sa.mock :upload_codebase
|
310
|
+
end
|
311
|
+
|
312
|
+
@app.checkout_codebase :copy => true, :exclude => ["path3/", "path4/"]
|
313
|
+
|
314
|
+
@app.each do |sa|
|
315
|
+
assert sa.method_called?(:upload_codebase,
|
316
|
+
:args => [tmp_path, {:test => "scm info",
|
317
|
+
:exclude => ["path1/", "path2/", "path3/", "path4/"]}])
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
|
280
322
|
def test_deployed?
|
281
323
|
set_mock_response_for @app, 0,
|
282
|
-
"cat #{@app.
|
324
|
+
"cat #{@app.root_path}/info" => [:out,
|
283
325
|
"---\n:deploy_name: '#{@app.deploy_name}'"]
|
284
326
|
|
285
327
|
deployed = @app.deployed?
|
@@ -437,7 +479,7 @@ class TestApp < Test::Unit::TestCase
|
|
437
479
|
returned_dirs = %w{old_deploy1 old_deploy2 old_deploy3 main_deploy}
|
438
480
|
old_deploys = returned_dirs[0..-2].map{|d| "#{@app.deploys_path}/#{d}"}
|
439
481
|
|
440
|
-
list_cmd = "ls -
|
482
|
+
list_cmd = "ls -rc1 #{@app.deploys_path}"
|
441
483
|
rm_cmd = "rm -rf #{old_deploys.join(" ")}"
|
442
484
|
|
443
485
|
set_mock_response_for @app, 0,
|
@@ -500,7 +542,7 @@ class TestApp < Test::Unit::TestCase
|
|
500
542
|
|
501
543
|
@app.threaded_each do |server_app|
|
502
544
|
if server_app.shell.host == err_host
|
503
|
-
raise Sunshine::
|
545
|
+
raise Sunshine::DeployError, server_app.shell.host
|
504
546
|
else
|
505
547
|
finished = finished.next
|
506
548
|
end
|
@@ -508,7 +550,7 @@ class TestApp < Test::Unit::TestCase
|
|
508
550
|
|
509
551
|
raise "Didn't raise threaded error when it should have"
|
510
552
|
|
511
|
-
rescue Sunshine::
|
553
|
+
rescue Sunshine::DeployError => e
|
512
554
|
host = @app.server_apps.first.shell.host
|
513
555
|
|
514
556
|
assert_equal host, e.message
|
data/test/unit/test_daemon.rb
CHANGED
@@ -17,9 +17,9 @@ class TestDaemon < Test::Unit::TestCase
|
|
17
17
|
|
18
18
|
begin
|
19
19
|
daemon.start_cmd
|
20
|
-
raise "Should have thrown
|
21
|
-
rescue Sunshine::
|
22
|
-
assert_equal "
|
20
|
+
raise "Should have thrown DaemonError but didn't :("
|
21
|
+
rescue Sunshine::DaemonError => e
|
22
|
+
assert_equal "start_cmd undefined for daemon", e.message
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
data/test/unit/test_nginx.rb
CHANGED
@@ -87,13 +87,16 @@ class TestNginx < Test::Unit::TestCase
|
|
87
87
|
## Helper methods
|
88
88
|
|
89
89
|
def start_cmd svr
|
90
|
-
"#{svr.bin} -c #{svr.config_file_path}"
|
90
|
+
svr.exit_on_failure "#{svr.bin} -c #{svr.config_file_path}", 10,
|
91
|
+
"Could not start #{svr.name} for #{svr.app.name}"
|
91
92
|
end
|
92
93
|
|
93
94
|
|
94
95
|
def stop_cmd svr
|
95
|
-
"test -f #{svr.pid} && kill -#{svr.sigkill} $(cat #{svr.pid}) && "+
|
96
|
-
|
97
|
-
|
96
|
+
cmd = "test -f #{svr.pid} && kill -#{svr.sigkill} $(cat #{svr.pid}) && "+
|
97
|
+
"sleep 1 && rm -f #{svr.pid}"
|
98
|
+
|
99
|
+
svr.exit_on_failure cmd, 11,
|
100
|
+
"Could not kill #{svr.name} pid for #{svr.app.name}"
|
98
101
|
end
|
99
102
|
end
|
data/test/unit/test_server.rb
CHANGED
@@ -69,7 +69,7 @@ class TestServer < Test::Unit::TestCase
|
|
69
69
|
assert sa.method_called?(:install_deps, :args => ["rainbows"])
|
70
70
|
|
71
71
|
assert server.method_called?(:configure_remote_dirs, :args => [sa.shell])
|
72
|
-
assert server.method_called?(:
|
72
|
+
assert server.method_called?(:chown_log_files, :args => [sa.shell])
|
73
73
|
assert server.method_called?(:upload_config_files, :args => [sa.shell])
|
74
74
|
end
|
75
75
|
|
@@ -121,7 +121,7 @@ class TestServer < Test::Unit::TestCase
|
|
121
121
|
|
122
122
|
server.start do |sa|
|
123
123
|
assert_equal @server_app, sa
|
124
|
-
assert_ssh_call server.
|
124
|
+
assert_ssh_call server._start_cmd, sa.shell, :sudo => true
|
125
125
|
end
|
126
126
|
|
127
127
|
assert server.method_called?(:setup)
|
@@ -135,7 +135,7 @@ class TestServer < Test::Unit::TestCase
|
|
135
135
|
|
136
136
|
server.start do |sa|
|
137
137
|
assert_equal @server_app, sa
|
138
|
-
assert_ssh_call server.
|
138
|
+
assert_ssh_call server._start_cmd, sa.shell, :sudo => true
|
139
139
|
end
|
140
140
|
|
141
141
|
assert !server.method_called?(:setup)
|
@@ -147,7 +147,7 @@ class TestServer < Test::Unit::TestCase
|
|
147
147
|
|
148
148
|
server.stop do |sa|
|
149
149
|
assert_equal @server_app, sa
|
150
|
-
assert_ssh_call server.
|
150
|
+
assert_ssh_call server._stop_cmd, sa.shell, :sudo => true
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
@@ -157,7 +157,7 @@ class TestServer < Test::Unit::TestCase
|
|
157
157
|
|
158
158
|
server.restart do |sa|
|
159
159
|
assert_equal @server_app, sa
|
160
|
-
assert_ssh_call server.
|
160
|
+
assert_ssh_call server._restart_cmd, sa.shell, :sudo => true
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
@@ -181,7 +181,7 @@ class TestServer < Test::Unit::TestCase
|
|
181
181
|
|
182
182
|
server.restart do |sa|
|
183
183
|
assert_equal @server_app, sa
|
184
|
-
assert_ssh_call server.
|
184
|
+
assert_ssh_call server._restart_cmd, sa.shell, :sudo => true
|
185
185
|
end
|
186
186
|
|
187
187
|
assert server.method_called?(:setup)
|
@@ -15,6 +15,27 @@ class TestServerApp < Test::Unit::TestCase
|
|
15
15
|
end
|
16
16
|
|
17
17
|
|
18
|
+
def test_from_info_file
|
19
|
+
info_data = @sa.get_deploy_info.to_yaml
|
20
|
+
@sa.shell.mock :call, :args => "cat info/path", :return => info_data
|
21
|
+
|
22
|
+
server_app = Sunshine::ServerApp.from_info_file "info/path", @sa.shell
|
23
|
+
|
24
|
+
assert_equal @sa.root_path, server_app.root_path
|
25
|
+
assert_equal @sa.checkout_path, server_app.checkout_path
|
26
|
+
assert_equal @sa.current_path, server_app.current_path
|
27
|
+
assert_equal @sa.deploys_path, server_app.deploys_path
|
28
|
+
assert_equal @sa.log_path, server_app.log_path
|
29
|
+
assert_equal @sa.shared_path, server_app.shared_path
|
30
|
+
assert_equal @sa.scripts_path, server_app.scripts_path
|
31
|
+
assert_equal @sa.roles, server_app.roles
|
32
|
+
|
33
|
+
assert_equal @sa.shell.env, server_app.shell_env
|
34
|
+
assert_equal @sa.name, server_app.name
|
35
|
+
assert_equal @sa.deploy_name, server_app.deploy_name
|
36
|
+
end
|
37
|
+
|
38
|
+
|
18
39
|
def test_init
|
19
40
|
default_info = {:ports => {}}
|
20
41
|
assert_equal default_info, @sa.info
|
@@ -119,7 +140,7 @@ class TestServerApp < Test::Unit::TestCase
|
|
119
140
|
deploy_details = {:item => "thing"}
|
120
141
|
other_details = {:key => "value"}
|
121
142
|
|
122
|
-
@sa.shell.mock :call, :args => ["cat #{@sa.
|
143
|
+
@sa.shell.mock :call, :args => ["cat #{@sa.root_path}/info"],
|
123
144
|
:return => other_details.to_yaml
|
124
145
|
|
125
146
|
@sa.instance_variable_set "@deploy_details", deploy_details
|
@@ -158,8 +179,11 @@ class TestServerApp < Test::Unit::TestCase
|
|
158
179
|
:deployed_as => @sa.shell.call("whoami"),
|
159
180
|
:deployed_by => Sunshine.shell.user,
|
160
181
|
:deploy_name => File.basename(@app.checkout_path),
|
182
|
+
:name => @sa.name,
|
183
|
+
:env => @sa.shell_env,
|
161
184
|
:roles => @sa.roles,
|
162
|
-
:path => @app.root_path
|
185
|
+
:path => @app.root_path,
|
186
|
+
:sunshine_version => Sunshine::VERSION
|
163
187
|
}.merge @sa.info
|
164
188
|
|
165
189
|
deploy_info = @sa.get_deploy_info
|
@@ -204,7 +228,7 @@ class TestServerApp < Test::Unit::TestCase
|
|
204
228
|
@sa.install_deps nginx_dep, :type => Sunshine::Gem
|
205
229
|
raise "Didn't raise missing dependency when it should have."
|
206
230
|
|
207
|
-
rescue Sunshine::
|
231
|
+
rescue Sunshine::MissingDependency => e
|
208
232
|
assert_equal "No dependency 'nginx' [Sunshine::Gem]", e.message
|
209
233
|
end
|
210
234
|
|
@@ -257,7 +281,7 @@ class TestServerApp < Test::Unit::TestCase
|
|
257
281
|
deploys = %w{ploy1 ploy2 ploy3 ploy4 ploy5}
|
258
282
|
|
259
283
|
@sa.shell.mock :call,
|
260
|
-
:args => ["ls -
|
284
|
+
:args => ["ls -rc1 #{@app.deploys_path}"],
|
261
285
|
:return => "#{deploys.join("\n")}\n"
|
262
286
|
|
263
287
|
removed = deploys[0..1].map{|d| "#{@app.deploys_path}/#{d}"}
|
@@ -330,6 +354,32 @@ class TestServerApp < Test::Unit::TestCase
|
|
330
354
|
end
|
331
355
|
|
332
356
|
|
357
|
+
def test_running?
|
358
|
+
set_mock_response_for @sa, 0,
|
359
|
+
"#{@sa.root_path}/status" => [:out, "THE SYSTEM OK!"]
|
360
|
+
|
361
|
+
assert_equal true, @sa.running?
|
362
|
+
end
|
363
|
+
|
364
|
+
|
365
|
+
def test_not_running?
|
366
|
+
set_mock_response_for @sa, 13,
|
367
|
+
"#{@sa.root_path}/status" => [:err, "THE SYSTEM IS DOWN!"]
|
368
|
+
|
369
|
+
assert_equal false, @sa.running?
|
370
|
+
end
|
371
|
+
|
372
|
+
|
373
|
+
def test_errored_running?
|
374
|
+
set_mock_response_for @sa, 1,
|
375
|
+
"#{@sa.root_path}/status" => [:err, "KABLAM!"]
|
376
|
+
|
377
|
+
assert_raises Sunshine::CmdError do
|
378
|
+
@sa.running?
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
|
333
383
|
def test_sass
|
334
384
|
sass_files = %w{file1 file2 file3}
|
335
385
|
|
@@ -426,6 +476,50 @@ class TestServerApp < Test::Unit::TestCase
|
|
426
476
|
end
|
427
477
|
|
428
478
|
|
479
|
+
def test_upload_codebase
|
480
|
+
@sa.shell.mock(:upload)
|
481
|
+
|
482
|
+
@sa.upload_codebase "tmp/thing/", :test_scm => "info"
|
483
|
+
assert_equal({:test_scm => "info"} , @sa.info[:scm])
|
484
|
+
assert @sa.shell.method_called?(
|
485
|
+
:upload, :args => ["tmp/thing/", @sa.checkout_path,
|
486
|
+
{:flags => ["--exclude .svn/","--exclude .git/"]}])
|
487
|
+
end
|
488
|
+
|
489
|
+
|
490
|
+
def test_upload_codebase_with_exclude
|
491
|
+
@sa.shell.mock(:upload)
|
492
|
+
|
493
|
+
@sa.upload_codebase "tmp/thing/",
|
494
|
+
:test_scm => "info",
|
495
|
+
:exclude => "bad/path/"
|
496
|
+
|
497
|
+
assert_equal({:test_scm => "info"} , @sa.info[:scm])
|
498
|
+
assert @sa.shell.method_called?(
|
499
|
+
:upload, :args => ["tmp/thing/", @sa.checkout_path,
|
500
|
+
{:flags => ["--exclude bad/path/",
|
501
|
+
"--exclude .svn/",
|
502
|
+
"--exclude .git/"]}])
|
503
|
+
end
|
504
|
+
|
505
|
+
|
506
|
+
def test_upload_codebase_with_excludes
|
507
|
+
@sa.shell.mock(:upload)
|
508
|
+
|
509
|
+
@sa.upload_codebase "tmp/thing/",
|
510
|
+
:test_scm => "info",
|
511
|
+
:exclude => ["bad/path/", "other/exclude/"]
|
512
|
+
|
513
|
+
assert_equal({:test_scm => "info"} , @sa.info[:scm])
|
514
|
+
assert @sa.shell.method_called?(
|
515
|
+
:upload, :args => ["tmp/thing/", @sa.checkout_path,
|
516
|
+
{:flags => ["--exclude bad/path/",
|
517
|
+
"--exclude other/exclude/",
|
518
|
+
"--exclude .svn/",
|
519
|
+
"--exclude .git/"]}])
|
520
|
+
end
|
521
|
+
|
522
|
+
|
429
523
|
def test_write_script
|
430
524
|
@sa.shell.mock :file?, :return => false
|
431
525
|
|
@@ -435,10 +529,19 @@ class TestServerApp < Test::Unit::TestCase
|
|
435
529
|
"script contents", {:flags => "--chmod=ugo=rwx"}]
|
436
530
|
|
437
531
|
assert @sa.shell.method_called?(:make_file, :args => args)
|
532
|
+
end
|
533
|
+
|
534
|
+
|
535
|
+
def test_symlink_scripts_to_root
|
536
|
+
@sa.shell.mock :call,
|
537
|
+
:args => ["ls -1 #{@sa.scripts_path}"],
|
538
|
+
:return => "script_name\n"
|
438
539
|
|
439
540
|
args = ["#{@app.scripts_path}/script_name",
|
440
541
|
"#{@app.root_path}/script_name"]
|
441
542
|
|
543
|
+
@sa.symlink_scripts_to_root
|
544
|
+
|
442
545
|
assert @sa.shell.method_called?(:symlink, :args => args)
|
443
546
|
end
|
444
547
|
|
@@ -452,10 +555,5 @@ class TestServerApp < Test::Unit::TestCase
|
|
452
555
|
"script contents", {:flags => "--chmod=ugo=rwx"}]
|
453
556
|
|
454
557
|
assert !@sa.shell.method_called?(:make_file, :args => args)
|
455
|
-
|
456
|
-
args = ["#{@app.scripts_path}/script_name",
|
457
|
-
"#{@app.root_path}/script_name"]
|
458
|
-
|
459
|
-
assert @sa.shell.method_called?(:symlink, :args => args)
|
460
558
|
end
|
461
559
|
end
|