gorgon 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/.gitignore +2 -0
- data/.ruby-version +1 -1
- data/Gemfile.lock +1 -1
- data/gorgon.json.sample +1 -1
- data/lib/gorgon/originator.rb +7 -1
- data/lib/gorgon/runtime_file_reader.rb +26 -0
- data/lib/gorgon/runtime_recorder.rb +36 -0
- data/lib/gorgon/version.rb +1 -1
- data/lib/gorgon/worker.rb +10 -6
- data/spec/runtime_file_reader_spec.rb +49 -0
- data/spec/runtime_recorder_spec.rb +79 -0
- data/tutorial.md +2 -2
- metadata +17 -13
- data/spec/acceptance/run_tests_spec.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZGExZTQwNzZlNWEwNDY4YTc0MmUxMDhhYWY4N2MwOTUxMjgyMDg2Mw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZWQyNTdlYmQ2MDBjMGU0ZWY0MmMwZWRkYzg2NjJlYjQxNDZlMzc4Yg==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Y2RiYjRjNjYyOTY2ODM5MmQ1MjJiMGRiNGVlMWNkY2E2NWE4YTk3ZTE5N2I2
|
10
|
+
MWFkNWIxNWU0ZDQ3MDY5M2IyN2Y4NzNhYjgyZTBhODVjN2U0NTU0ZmZiYTUz
|
11
|
+
MGNmZDUyZWQ1YWI4YjdiZDU0MDhhZTc3ZmMyZWRjYjc3ZjdmMTc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MjY5ZjUxYTMyNDA4Yjg1OGMwOGZjODA5MDE1NGUxYjg0NGJjY2M1Mzk0ZTYw
|
14
|
+
ZmQxZDhlZTQwMjUzM2JhMzdhYjAzZDIyYzFmMWI2MGUwYmM1N2RlYjhhYjc4
|
15
|
+
YzhkZWEzYjIxZTg5NWI4OTYwNDJkYWRjY2IwZjczNjZjOGE1ZjU=
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-1.9.3-
|
1
|
+
ruby-1.9.3-p551
|
data/Gemfile.lock
CHANGED
data/gorgon.json.sample
CHANGED
data/lib/gorgon/originator.rb
CHANGED
@@ -8,6 +8,8 @@ require 'gorgon/failures_printer'
|
|
8
8
|
require 'gorgon/source_tree_syncer'
|
9
9
|
require 'gorgon/shutdown_manager'
|
10
10
|
require 'gorgon/callback_handler'
|
11
|
+
require 'gorgon/runtime_recorder'
|
12
|
+
require 'gorgon/runtime_file_reader'
|
11
13
|
|
12
14
|
require 'awesome_print'
|
13
15
|
require 'etc'
|
@@ -135,6 +137,7 @@ class Originator
|
|
135
137
|
|
136
138
|
def create_job_state_and_observers
|
137
139
|
@job_state = JobState.new files.count
|
140
|
+
RuntimeRecorder.new @job_state, configuration[:runtime_file]
|
138
141
|
@progress_bar_view = ProgressBarView.new @job_state
|
139
142
|
@progress_bar_view.show
|
140
143
|
FailuresPrinter.new @job_state
|
@@ -149,9 +152,12 @@ class Originator
|
|
149
152
|
end
|
150
153
|
|
151
154
|
def files
|
152
|
-
@files
|
155
|
+
return @files unless @files.nil?
|
156
|
+
current_files = configuration[:files].reduce([]) do |memo, obj|
|
153
157
|
memo.concat(Dir[obj])
|
154
158
|
end.uniq
|
159
|
+
runtime_file_reader = RuntimeFileReader.new configuration[:runtime_file]
|
160
|
+
@files = runtime_file_reader.sorted_files(current_files)
|
155
161
|
end
|
156
162
|
|
157
163
|
def job_definition
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'yajl'
|
2
|
+
|
3
|
+
class RuntimeFileReader
|
4
|
+
|
5
|
+
def initialize(runtime_filename)
|
6
|
+
@runtime_filename = runtime_filename || ""
|
7
|
+
end
|
8
|
+
|
9
|
+
def old_files
|
10
|
+
@old_files ||= unless File.file?(@runtime_filename)
|
11
|
+
[]
|
12
|
+
else
|
13
|
+
File.open(@runtime_filename, 'r') do |f|
|
14
|
+
parser = Yajl::Parser.new
|
15
|
+
hash = parser.parse(f)
|
16
|
+
hash.nil? ? [] : hash.keys
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def sorted_files(current_files = [])
|
22
|
+
(self.old_files+current_files).uniq - (self.old_files-current_files)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'yajl'
|
2
|
+
|
3
|
+
class RuntimeRecorder
|
4
|
+
attr_accessor :records
|
5
|
+
|
6
|
+
def initialize(job_state, runtime_filename)
|
7
|
+
@records = {}
|
8
|
+
@job_state = job_state
|
9
|
+
@job_state.add_observer(self)
|
10
|
+
@runtime_filename = runtime_filename || ""
|
11
|
+
end
|
12
|
+
|
13
|
+
def update payload
|
14
|
+
@records[payload[:filename]] = payload[:runtime] if payload[:action] == "finish"
|
15
|
+
self.write_records_to_file if @job_state.is_job_complete?
|
16
|
+
end
|
17
|
+
|
18
|
+
def write_records_to_file
|
19
|
+
return if @runtime_filename.empty?
|
20
|
+
make_directories
|
21
|
+
@records = Hash[@records.sort_by{|filename, runtime| -1*runtime}]
|
22
|
+
File.open(@runtime_filename, 'w') do |f|
|
23
|
+
f.write(Yajl::Encoder.encode(@records, pretty: true))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def make_directories
|
31
|
+
dirname = File.dirname(@runtime_filename)
|
32
|
+
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
data/lib/gorgon/version.rb
CHANGED
data/lib/gorgon/worker.rb
CHANGED
@@ -7,6 +7,7 @@ require 'gorgon/job_definition'
|
|
7
7
|
require "uuidtools"
|
8
8
|
require "awesome_print"
|
9
9
|
require "socket"
|
10
|
+
require "benchmark"
|
10
11
|
|
11
12
|
module TestRunner
|
12
13
|
def self.run_file filename, test_runner
|
@@ -92,9 +93,12 @@ class Worker
|
|
92
93
|
@amqp.start_worker @file_queue_name, @reply_exchange_name do |queue, exchange|
|
93
94
|
while filename = queue.pop
|
94
95
|
exchange.publish make_start_message(filename)
|
95
|
-
log "Running '#{filename}'"
|
96
|
-
test_results = run_file(
|
97
|
-
|
96
|
+
log "Running '#{filename}' with Worker: #{@worker_id}"
|
97
|
+
test_results = nil # needed so run_file() inside the Benchmark will use this
|
98
|
+
runtime = Benchmark.realtime do
|
99
|
+
test_results = run_file(filename)
|
100
|
+
end
|
101
|
+
exchange.publish make_finish_message(filename, test_results, runtime)
|
98
102
|
end
|
99
103
|
end
|
100
104
|
rescue Exception => e
|
@@ -142,11 +146,11 @@ class Worker
|
|
142
146
|
end
|
143
147
|
|
144
148
|
def make_start_message(filename)
|
145
|
-
{:
|
149
|
+
{action: :start, hostname: Socket.gethostname, worker_id: @worker_id, filename: filename}
|
146
150
|
end
|
147
151
|
|
148
|
-
def make_finish_message(filename, results)
|
149
|
-
{:
|
152
|
+
def make_finish_message(filename, results, runtime)
|
153
|
+
{action: :finish, hostname: Socket.gethostname, worker_id: @worker_id, filename: filename, runtime: runtime}.merge(results)
|
150
154
|
end
|
151
155
|
|
152
156
|
def require_runner_code_for framework
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'gorgon/runtime_file_reader'
|
2
|
+
require 'yajl'
|
3
|
+
|
4
|
+
describe RuntimeFileReader do
|
5
|
+
|
6
|
+
describe "#old_files" do
|
7
|
+
let(:runtime_filename){ "runtime_file.json" }
|
8
|
+
|
9
|
+
it "should read runtime_file" do
|
10
|
+
File.stub(:file?).and_return(true)
|
11
|
+
runtime_file_reader = RuntimeFileReader.new(runtime_filename)
|
12
|
+
File.should_receive(:open).with(runtime_filename, 'r')
|
13
|
+
runtime_file_reader.old_files
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return empty array if runtime_file is invalid" do
|
17
|
+
File.should_receive(:file?).and_return(false)
|
18
|
+
runtime_file_reader = RuntimeFileReader.new(runtime_filename)
|
19
|
+
File.should_not_receive(:open)
|
20
|
+
runtime_file_reader.old_files
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe "#sorted_files" do
|
26
|
+
let (:old_files){ [ "old_a.rb", "old_b.rb", "old_c.rb"] }
|
27
|
+
|
28
|
+
before do
|
29
|
+
@runtime_file_reader = RuntimeFileReader.new "runtime_file.json"
|
30
|
+
@runtime_file_reader.stub(:old_files).and_return old_files
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should include new files at the end" do
|
34
|
+
current_spec_files = ["new_a.rb", "old_b.rb", "old_a.rb", "new_b.rb", "old_c.rb"]
|
35
|
+
sorted_files = @runtime_file_reader.sorted_files(current_spec_files)
|
36
|
+
expect(sorted_files.first(sorted_files.size-2)).to eq(old_files)
|
37
|
+
expect(sorted_files.last(2)).to eq(["new_a.rb", "new_b.rb"])
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should remove old files that are not in current files" do
|
41
|
+
current_spec_files = ["new_a.rb", "old_a.rb", "old_c.rb"]
|
42
|
+
sorted_files = @runtime_file_reader.sorted_files(current_spec_files)
|
43
|
+
expect(sorted_files.first(2)).to eq(["old_a.rb", "old_c.rb"])
|
44
|
+
expect(sorted_files.last(1)).to eq(["new_a.rb"])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'gorgon/job_state'
|
2
|
+
require 'gorgon/runtime_recorder'
|
3
|
+
require 'yajl'
|
4
|
+
|
5
|
+
describe RuntimeRecorder do
|
6
|
+
|
7
|
+
let (:runtime_filename){ "runtime_file.json" }
|
8
|
+
|
9
|
+
describe "#initialize" do
|
10
|
+
it "adds itself to observers of job_state and sets records as empty" do
|
11
|
+
job_state = JobState.new 1
|
12
|
+
job_state.should_receive(:add_observer)
|
13
|
+
runtime_recorder = RuntimeRecorder.new job_state, runtime_filename
|
14
|
+
expect(runtime_recorder.records).to eq({})
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
describe "#update" do
|
20
|
+
let(:payload){ {filename: "file_spec.rb", runtime: 1.23, action: "finish"} }
|
21
|
+
before do
|
22
|
+
@job_state = JobState.new 1
|
23
|
+
@runtime_recorder = RuntimeRecorder.new @job_state, nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should record if a file finished" do
|
27
|
+
expect(@runtime_recorder.records).to be_empty
|
28
|
+
@runtime_recorder.update(payload)
|
29
|
+
@runtime_recorder.records = { "file_spec.rb" => 1.23 }
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not record if a file is not finished" do
|
33
|
+
expect(@runtime_recorder.records).to be_empty
|
34
|
+
@runtime_recorder.update(payload.merge({action:"not_finish"}))
|
35
|
+
expect(@runtime_recorder.records).to be_empty
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should write to the file if job is completed" do
|
39
|
+
@job_state.stub(:is_job_complete?).and_return(true)
|
40
|
+
@runtime_recorder.should_receive(:write_records_to_file)
|
41
|
+
@runtime_recorder.update(payload)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should not write to the file if job is not completed" do
|
45
|
+
@job_state.stub(:is_job_complete?).and_return(false)
|
46
|
+
@runtime_recorder.should_not_receive(:write_records_to_file)
|
47
|
+
@runtime_recorder.update(payload)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
describe "#write_records_to_file" do
|
53
|
+
let(:sample_records){ {"zero.rb" => 0.23, "one.rb" => 1.23, "two.rb" => 2.23} }
|
54
|
+
|
55
|
+
before do
|
56
|
+
@job_state = JobState.new 1
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should not write if no file is given" do
|
60
|
+
runtime_recorder = RuntimeRecorder.new @job_state, nil
|
61
|
+
runtime_recorder.records = sample_records
|
62
|
+
file = mock('file')
|
63
|
+
File.should_not_receive(:open).and_yield(file)
|
64
|
+
file.should_not_receive(:write)
|
65
|
+
runtime_recorder.write_records_to_file
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should write sorted records to the given file" do
|
69
|
+
runtime_recorder = RuntimeRecorder.new @job_state, runtime_filename
|
70
|
+
runtime_recorder.records = sample_records
|
71
|
+
file = mock('file')
|
72
|
+
File.should_receive(:open).with(runtime_filename, 'w').and_yield(file)
|
73
|
+
file.should_receive(:write).with("{\n \"two.rb\": 2.23,\n \"one.rb\": 1.23,\n \"zero.rb\": 0.23\n}")
|
74
|
+
runtime_recorder.write_records_to_file
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
data/tutorial.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Gorgon Setup Tutorial
|
2
2
|
|
3
|
-
This is an example on how to setup [Gorgon](https://github.com/
|
3
|
+
This is an example on how to setup [Gorgon](https://github.com/nulogy/Gorgon). For this tutorial, we will use a version of a Rails app from [Ruby on Rails Tutorial](https://www.railstutorial.org/) by Michael Hartl.
|
4
4
|
|
5
5
|
### Setup the sample Rails app
|
6
6
|
|
@@ -68,7 +68,7 @@ To check if you have SSH access without password, running ```ssh localhost``` sh
|
|
68
68
|
1. Download a listener configuration sample:
|
69
69
|
|
70
70
|
```bash
|
71
|
-
wget https://raw.githubusercontent.com/
|
71
|
+
wget https://raw.githubusercontent.com/nulogy/Gorgon/master/gorgon_listener.json.sample
|
72
72
|
mv gorgon_listener.json.sample gorgon_listener.json
|
73
73
|
```
|
74
74
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gorgon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Fitzsimmons
|
@@ -12,34 +12,34 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-
|
15
|
+
date: 2014-12-28 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rake
|
19
19
|
requirement: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
|
-
- - '>='
|
21
|
+
- - ! '>='
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: '0'
|
24
24
|
type: :development
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
|
-
- - '>='
|
28
|
+
- - ! '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: '0'
|
31
31
|
- !ruby/object:Gem::Dependency
|
32
32
|
name: test-unit
|
33
33
|
requirement: !ruby/object:Gem::Requirement
|
34
34
|
requirements:
|
35
|
-
- - '>='
|
35
|
+
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: '0'
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
requirements:
|
42
|
-
- - '>='
|
42
|
+
- - ! '>='
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
version: '0'
|
45
45
|
- !ruby/object:Gem::Dependency
|
@@ -74,14 +74,14 @@ dependencies:
|
|
74
74
|
name: awesome_print
|
75
75
|
requirement: !ruby/object:Gem::Requirement
|
76
76
|
requirements:
|
77
|
-
- - '>='
|
77
|
+
- - ! '>='
|
78
78
|
- !ruby/object:Gem::Version
|
79
79
|
version: '0'
|
80
80
|
type: :runtime
|
81
81
|
prerelease: false
|
82
82
|
version_requirements: !ruby/object:Gem::Requirement
|
83
83
|
requirements:
|
84
|
-
- - '>='
|
84
|
+
- - ! '>='
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0'
|
87
87
|
- !ruby/object:Gem::Dependency
|
@@ -204,6 +204,8 @@ files:
|
|
204
204
|
- lib/gorgon/progress_bar_view.rb
|
205
205
|
- lib/gorgon/rspec_runner.rb
|
206
206
|
- lib/gorgon/rsync_daemon.rb
|
207
|
+
- lib/gorgon/runtime_file_reader.rb
|
208
|
+
- lib/gorgon/runtime_recorder.rb
|
207
209
|
- lib/gorgon/settings/files_content.rb
|
208
210
|
- lib/gorgon/settings/initial_files_creator.rb
|
209
211
|
- lib/gorgon/settings/rails_project_files_content.rb
|
@@ -271,7 +273,6 @@ files:
|
|
271
273
|
- lib/gorgon_bunny/lib/gorgon_bunny/version.rb
|
272
274
|
- lib/gorgon_bunny/lib/gorgon_bunny/versioned_delivery_tag.rb
|
273
275
|
- rsync_transport.md
|
274
|
-
- spec/acceptance/run_tests_spec.rb
|
275
276
|
- spec/acceptance_spec_helper.rb
|
276
277
|
- spec/callback_handler_spec.rb
|
277
278
|
- spec/crash_reporter_spec.rb
|
@@ -292,6 +293,8 @@ files:
|
|
292
293
|
- spec/progress_bar_view_spec.rb
|
293
294
|
- spec/rspec_runner_spec.rb
|
294
295
|
- spec/rsync_daemon_spec.rb
|
296
|
+
- spec/runtime_file_reader_spec.rb
|
297
|
+
- spec/runtime_recorder_spec.rb
|
295
298
|
- spec/shutdown_manager_spec.rb
|
296
299
|
- spec/source_tree_syncer_spec.rb
|
297
300
|
- spec/support/mock_app/.gitignore
|
@@ -359,22 +362,21 @@ require_paths:
|
|
359
362
|
- lib
|
360
363
|
required_ruby_version: !ruby/object:Gem::Requirement
|
361
364
|
requirements:
|
362
|
-
- - '>='
|
365
|
+
- - ! '>='
|
363
366
|
- !ruby/object:Gem::Version
|
364
367
|
version: '0'
|
365
368
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
366
369
|
requirements:
|
367
|
-
- - '>='
|
370
|
+
- - ! '>='
|
368
371
|
- !ruby/object:Gem::Version
|
369
372
|
version: '0'
|
370
373
|
requirements: []
|
371
374
|
rubyforge_project: gorgon
|
372
|
-
rubygems_version: 2.
|
375
|
+
rubygems_version: 2.4.3
|
373
376
|
signing_key:
|
374
377
|
specification_version: 4
|
375
378
|
summary: Distributed testing for ruby with centralized management
|
376
379
|
test_files:
|
377
|
-
- spec/acceptance/run_tests_spec.rb
|
378
380
|
- spec/acceptance_spec_helper.rb
|
379
381
|
- spec/callback_handler_spec.rb
|
380
382
|
- spec/crash_reporter_spec.rb
|
@@ -395,6 +397,8 @@ test_files:
|
|
395
397
|
- spec/progress_bar_view_spec.rb
|
396
398
|
- spec/rspec_runner_spec.rb
|
397
399
|
- spec/rsync_daemon_spec.rb
|
400
|
+
- spec/runtime_file_reader_spec.rb
|
401
|
+
- spec/runtime_recorder_spec.rb
|
398
402
|
- spec/shutdown_manager_spec.rb
|
399
403
|
- spec/source_tree_syncer_spec.rb
|
400
404
|
- spec/support/mock_app/.gitignore
|