gorgon 0.4.5 → 0.5.0.rc1
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/.gitignore +4 -1
- data/lib/gorgon/originator.rb +6 -1
- data/lib/gorgon/progress_bar_view.rb +1 -1
- data/lib/gorgon/rsync_daemon.rb +59 -0
- data/lib/gorgon/source_tree_syncer.rb +1 -1
- data/lib/gorgon/unknown_runner.rb +9 -9
- data/lib/gorgon/version.rb +1 -1
- data/spec/originator_spec.rb +23 -1
- data/spec/rsync_daemon_spec.rb +75 -0
- data/spec/source_tree_syncer_spec.rb +0 -18
- metadata +8 -12
data/.gitignore
CHANGED
data/lib/gorgon/originator.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'gorgon/job_state'
|
|
|
4
4
|
require 'gorgon/progress_bar_view'
|
|
5
5
|
require 'gorgon/originator_logger'
|
|
6
6
|
require 'gorgon/failures_printer'
|
|
7
|
+
require 'gorgon/rsync_daemon'
|
|
7
8
|
|
|
8
9
|
require 'awesome_print'
|
|
9
10
|
require 'etc'
|
|
@@ -14,6 +15,7 @@ class Originator
|
|
|
14
15
|
|
|
15
16
|
def initialize
|
|
16
17
|
@configuration = nil
|
|
18
|
+
@rsync_daemon = RsyncDaemon.new
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def originate
|
|
@@ -44,11 +46,13 @@ class Originator
|
|
|
44
46
|
@job_state.cancel
|
|
45
47
|
|
|
46
48
|
@protocol.disconnect
|
|
49
|
+
@rsync_daemon.stop
|
|
47
50
|
end
|
|
48
51
|
|
|
49
52
|
def publish
|
|
50
53
|
@logger = OriginatorLogger.new configuration[:originator_log_file]
|
|
51
54
|
@protocol = OriginatorProtocol.new @logger
|
|
55
|
+
@rsync_daemon.start
|
|
52
56
|
|
|
53
57
|
EventMachine.run do
|
|
54
58
|
@logger.log "Connecting..."
|
|
@@ -72,6 +76,7 @@ class Originator
|
|
|
72
76
|
if @job_state.is_job_complete?
|
|
73
77
|
@logger.log "Job is done"
|
|
74
78
|
@protocol.disconnect
|
|
79
|
+
@rsync_daemon.stop
|
|
75
80
|
end
|
|
76
81
|
end
|
|
77
82
|
|
|
@@ -123,7 +128,7 @@ class Originator
|
|
|
123
128
|
def job_definition
|
|
124
129
|
job_config = configuration[:job]
|
|
125
130
|
if !job_config.has_key?(:source_tree_path)
|
|
126
|
-
job_config[:source_tree_path] = "
|
|
131
|
+
job_config[:source_tree_path] = "rsync://#{local_ip_addr}:43434/src"
|
|
127
132
|
end
|
|
128
133
|
JobDefinition.new(configuration[:job])
|
|
129
134
|
end
|
|
@@ -66,7 +66,7 @@ private
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def output_gorgon_crash_message payload
|
|
69
|
-
$stderr.puts "\nA #{'crash'.red}
|
|
69
|
+
$stderr.puts "\nA #{'crash'.red} occurred at '#{payload[:hostname].colorize Colors::HOST}':"
|
|
70
70
|
$stderr.puts payload[:stdout].yellow unless payload[:stdout].to_s.strip.length == 0
|
|
71
71
|
$stderr.puts payload[:stderr].yellow unless payload[:stderr].to_s.strip.length == 0
|
|
72
72
|
if @progress_bar.nil?
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require "tmpdir"
|
|
2
|
+
|
|
3
|
+
class RsyncDaemon
|
|
4
|
+
#for now, creates a readonly rsync daemon for the current directory on the mountpath "src"
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@project_directory = Dir.pwd
|
|
8
|
+
@started = false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def start
|
|
12
|
+
return if @started
|
|
13
|
+
@tmpdir = Dir.mktmpdir("gorgon")
|
|
14
|
+
success = nil
|
|
15
|
+
Dir.chdir(@tmpdir) do
|
|
16
|
+
File.write("rsyncd.conf", rsyncd_config_string(@project_directory))
|
|
17
|
+
|
|
18
|
+
success = Kernel.system("rsync --daemon --config rsyncd.conf")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if success
|
|
22
|
+
@started = true
|
|
23
|
+
return true
|
|
24
|
+
else
|
|
25
|
+
return false
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def stop
|
|
30
|
+
return unless @started
|
|
31
|
+
|
|
32
|
+
success = nil
|
|
33
|
+
Dir.chdir(@tmpdir) do
|
|
34
|
+
pid = File.read("rsync.pid")
|
|
35
|
+
success = Kernel.system("kill #{pid}")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
if success
|
|
39
|
+
@started = false
|
|
40
|
+
return true
|
|
41
|
+
else
|
|
42
|
+
return false
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def rsyncd_config_string(shared_dir)
|
|
49
|
+
return <<-EOF
|
|
50
|
+
port = 43434
|
|
51
|
+
pid file = rsync.pid
|
|
52
|
+
|
|
53
|
+
[src]
|
|
54
|
+
path = #{@project_directory}
|
|
55
|
+
read only = true
|
|
56
|
+
use chroot = false
|
|
57
|
+
EOF
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -5,7 +5,7 @@ class SourceTreeSyncer
|
|
|
5
5
|
attr_reader :sys_command, :output, :errors
|
|
6
6
|
|
|
7
7
|
SYS_COMMAND = 'rsync'
|
|
8
|
-
OPTS = "-azr --timeout=5
|
|
8
|
+
OPTS = "-azr --timeout=5"
|
|
9
9
|
EXCLUDE_OPT = "--exclude"
|
|
10
10
|
|
|
11
11
|
def initialize source_tree_path
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
class UnknownRunner
|
|
2
|
+
UNKNOWN_FRAMEWORK_MSG = "Unknown Test Framework. Gorgon only supports Test::Unit, MiniTest, and RSpec"
|
|
3
|
+
def self.run_file(filename)
|
|
4
|
+
raise UNKNOWN_FRAMEWORK_MSG
|
|
5
|
+
end
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
def self.runner
|
|
8
|
+
:unknown_framework
|
|
9
|
+
end
|
|
10
|
+
end
|
data/lib/gorgon/version.rb
CHANGED
data/spec/originator_spec.rb
CHANGED
|
@@ -10,9 +10,11 @@ describe Originator do
|
|
|
10
10
|
:add_observer => nil)}
|
|
11
11
|
let(:progress_bar_view){ stub("Progress Bar View", :show => nil)}
|
|
12
12
|
let(:originator_logger){ stub("Originator Logger", :log => nil, :log_message => nil)}
|
|
13
|
+
let(:rsync_daemon) { stub("Rsync Daemon", :start => true, :stop => true)}
|
|
13
14
|
|
|
14
15
|
before do
|
|
15
16
|
OriginatorLogger.stub(:new).and_return originator_logger
|
|
17
|
+
RsyncDaemon.stub(:new).and_return rsync_daemon
|
|
16
18
|
@originator = Originator.new
|
|
17
19
|
end
|
|
18
20
|
|
|
@@ -34,6 +36,12 @@ describe Originator do
|
|
|
34
36
|
progress_bar_view.should_receive(:show)
|
|
35
37
|
@originator.publish
|
|
36
38
|
end
|
|
39
|
+
|
|
40
|
+
it "starts the rsync daemon" do
|
|
41
|
+
rsync_daemon.should_receive(:start)
|
|
42
|
+
|
|
43
|
+
@originator.publish
|
|
44
|
+
end
|
|
37
45
|
end
|
|
38
46
|
|
|
39
47
|
describe "#cancel_job" do
|
|
@@ -54,6 +62,13 @@ describe Originator do
|
|
|
54
62
|
@originator.publish
|
|
55
63
|
@originator.cancel_job
|
|
56
64
|
end
|
|
65
|
+
|
|
66
|
+
it "stops the rsync daemon" do
|
|
67
|
+
rsync_daemon.should_receive(:stop)
|
|
68
|
+
|
|
69
|
+
@originator.publish
|
|
70
|
+
@originator.cancel_job
|
|
71
|
+
end
|
|
57
72
|
end
|
|
58
73
|
|
|
59
74
|
describe "#cleanup_if_job_complete" do
|
|
@@ -73,6 +88,13 @@ describe Originator do
|
|
|
73
88
|
protocol.should_receive(:disconnect)
|
|
74
89
|
@originator.cleanup_if_job_complete
|
|
75
90
|
end
|
|
91
|
+
|
|
92
|
+
it "stops the rsync daemon" do
|
|
93
|
+
job_state.stub!(:is_job_complete?).and_return true
|
|
94
|
+
rsync_daemon.should_receive(:stop)
|
|
95
|
+
|
|
96
|
+
@originator.cleanup_if_job_complete
|
|
97
|
+
end
|
|
76
98
|
end
|
|
77
99
|
|
|
78
100
|
describe "#handle_reply" do
|
|
@@ -123,7 +145,7 @@ describe Originator do
|
|
|
123
145
|
it "builds source_tree_path if it was not specified in the configuration" do
|
|
124
146
|
@originator.stub!(:configuration).and_return({:job => {}})
|
|
125
147
|
UDPSocket.any_instance.stub(:addr).and_return(["1.1.1.1"])
|
|
126
|
-
@originator.job_definition.source_tree_path.should == "
|
|
148
|
+
@originator.job_definition.source_tree_path.should == "rsync://1.1.1.1:43434/src"
|
|
127
149
|
end
|
|
128
150
|
|
|
129
151
|
it "returns source_tree_path specified in configuration if it is present" do
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'gorgon/rsync_daemon'
|
|
2
|
+
|
|
3
|
+
describe RsyncDaemon do
|
|
4
|
+
before(:each) do
|
|
5
|
+
Kernel.stub(:system => true)
|
|
6
|
+
Dir.stub(:mktmpdir => "loltmpdir", :pwd => "/lol/hax")
|
|
7
|
+
Dir.stub(:chdir).and_yield
|
|
8
|
+
File.stub(:write => 100, :read => "12345")
|
|
9
|
+
@r = RsyncDaemon.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "starts the rsync daemon" do
|
|
13
|
+
Kernel.should_receive(:system).with("rsync --daemon --config rsyncd.conf")
|
|
14
|
+
|
|
15
|
+
@r.start
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "creates a temporary directory for the configuration and pid files" do
|
|
19
|
+
Dir.should_receive(:mktmpdir).with("gorgon").and_return("loltmpdir")
|
|
20
|
+
Dir.should_receive(:chdir).with("loltmpdir")
|
|
21
|
+
|
|
22
|
+
@r.start
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "writes the config file" do
|
|
26
|
+
valid_config = <<-EOF
|
|
27
|
+
port = 43434
|
|
28
|
+
pid file = rsync.pid
|
|
29
|
+
|
|
30
|
+
[src]
|
|
31
|
+
path = /lol/hax
|
|
32
|
+
read only = true
|
|
33
|
+
use chroot = false
|
|
34
|
+
EOF
|
|
35
|
+
File.should_receive(:write).with("rsyncd.conf", valid_config)
|
|
36
|
+
|
|
37
|
+
@r.start
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "reports when an error has prevented startup" do
|
|
41
|
+
Kernel.should_receive(:system).and_return(false)
|
|
42
|
+
|
|
43
|
+
@r.start.should == false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "only starts once" do
|
|
47
|
+
Kernel.should_receive(:system).once
|
|
48
|
+
|
|
49
|
+
@r.start
|
|
50
|
+
@r.start
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "stops the rsync daemon" do
|
|
54
|
+
@r.start
|
|
55
|
+
|
|
56
|
+
File.should_receive(:read).with("rsync.pid").and_return("12345")
|
|
57
|
+
Kernel.should_receive(:system).with("kill 12345")
|
|
58
|
+
|
|
59
|
+
@r.stop
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "only tries to stop if the daemon is started" do
|
|
63
|
+
Kernel.should_not_receive(:system)
|
|
64
|
+
|
|
65
|
+
@r.stop
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "can be restarted" do
|
|
69
|
+
Kernel.should_receive(:system).exactly(3).times
|
|
70
|
+
|
|
71
|
+
@r.start
|
|
72
|
+
@r.stop
|
|
73
|
+
@r.start
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -57,24 +57,6 @@ describe SourceTreeSyncer.new("") do
|
|
|
57
57
|
@syncer.sync
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
it "use NumberOfPasswordPrompts 0 as ssh option to avoid password prompts that will hang the listener" do
|
|
61
|
-
opt = /--rsh='ssh .*-o NumberOfPasswordPrompts=0.*'/
|
|
62
|
-
Open4.should_receive(:popen4).with(opt)
|
|
63
|
-
@syncer.sync
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it "set UserKnownHostsFile to /dev/null so we avoid hosts id changes and eavesdropping warnings in futures connections" do
|
|
67
|
-
opt = /ssh .*-o UserKnownHostsFile=\/dev\/null/
|
|
68
|
-
Open4.should_receive(:popen4).with(opt)
|
|
69
|
-
@syncer.sync
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
it "set StrictHostKeyChecking to 'no' to avoid confirmation prompt of connection to unkown host" do
|
|
73
|
-
opt = /ssh .*-o StrictHostKeyChecking=no/
|
|
74
|
-
Open4.should_receive(:popen4).with(opt)
|
|
75
|
-
@syncer.sync
|
|
76
|
-
end
|
|
77
|
-
|
|
78
60
|
it "uses io timeout to avoid listener hanging forever in case rsync asks for any input" do
|
|
79
61
|
opt = /--timeout=5/
|
|
80
62
|
Open4.should_receive(:popen4).with(opt)
|
metadata
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gorgon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.5.0.rc1
|
|
5
|
+
prerelease: 6
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Justin Fitzsimmons
|
|
@@ -13,7 +13,7 @@ authors:
|
|
|
13
13
|
autorequire:
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
|
-
date: 2013-10-
|
|
16
|
+
date: 2013-10-31 00:00:00.000000000 Z
|
|
17
17
|
dependencies:
|
|
18
18
|
- !ruby/object:Gem::Dependency
|
|
19
19
|
name: rake
|
|
@@ -237,6 +237,7 @@ files:
|
|
|
237
237
|
- lib/gorgon/pipe_forker.rb
|
|
238
238
|
- lib/gorgon/progress_bar_view.rb
|
|
239
239
|
- lib/gorgon/rspec_runner.rb
|
|
240
|
+
- lib/gorgon/rsync_daemon.rb
|
|
240
241
|
- lib/gorgon/settings/files_content.rb
|
|
241
242
|
- lib/gorgon/settings/initial_files_creator.rb
|
|
242
243
|
- lib/gorgon/settings/rails_project_files_content.rb
|
|
@@ -265,6 +266,7 @@ files:
|
|
|
265
266
|
- spec/pipe_forker_spec.rb
|
|
266
267
|
- spec/progress_bar_view_spec.rb
|
|
267
268
|
- spec/rspec_runner_spec.rb
|
|
269
|
+
- spec/rsync_daemon_spec.rb
|
|
268
270
|
- spec/source_tree_syncer_spec.rb
|
|
269
271
|
- spec/unknown_runner_spec.rb
|
|
270
272
|
- spec/worker_manager_spec.rb
|
|
@@ -281,21 +283,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
281
283
|
- - ! '>='
|
|
282
284
|
- !ruby/object:Gem::Version
|
|
283
285
|
version: '0'
|
|
284
|
-
segments:
|
|
285
|
-
- 0
|
|
286
|
-
hash: 2798141738488026768
|
|
287
286
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
288
287
|
none: false
|
|
289
288
|
requirements:
|
|
290
|
-
- - ! '
|
|
289
|
+
- - ! '>'
|
|
291
290
|
- !ruby/object:Gem::Version
|
|
292
|
-
version:
|
|
293
|
-
segments:
|
|
294
|
-
- 0
|
|
295
|
-
hash: 2798141738488026768
|
|
291
|
+
version: 1.3.1
|
|
296
292
|
requirements: []
|
|
297
293
|
rubyforge_project: gorgon
|
|
298
|
-
rubygems_version: 1.8.
|
|
294
|
+
rubygems_version: 1.8.24
|
|
299
295
|
signing_key:
|
|
300
296
|
specification_version: 3
|
|
301
297
|
summary: Distributed testing for ruby with centralized management
|