gorgon 0.8.1 → 0.8.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: eef07ed03530c2480e46991f18ffaedcb485dd2e
4
- data.tar.gz: 69d4d71b43c58958eafbb489e9fea40aac62eea1
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZGExZTQwNzZlNWEwNDY4YTc0MmUxMDhhYWY4N2MwOTUxMjgyMDg2Mw==
5
+ data.tar.gz: !binary |-
6
+ ZWQyNTdlYmQ2MDBjMGU0ZWY0MmMwZWRkYzg2NjJlYjQxNDZlMzc4Yg==
5
7
  SHA512:
6
- metadata.gz: e546e88bc56e0e7d91a87691246d0ba555fdacb344f0cc832c968ce0f07599db929123061da6b6608f3d27cf7d754c82655153a193a0b9e0ca226d632841d397
7
- data.tar.gz: fc1d646ada5533fdd070a7cdaeabdf61a3219f8edca3150fe69aabe62afebbea33c257515692bb1847133f6a1f9ecd470b0388b80554621cb05571d6ec831705
8
+ metadata.gz: !binary |-
9
+ Y2RiYjRjNjYyOTY2ODM5MmQ1MjJiMGRiNGVlMWNkY2E2NWE4YTk3ZTE5N2I2
10
+ MWFkNWIxNWU0ZDQ3MDY5M2IyN2Y4NzNhYjgyZTBhODVjN2U0NTU0ZmZiYTUz
11
+ MGNmZDUyZWQ1YWI4YjdiZDU0MDhhZTc3ZmMyZWRjYjc3ZjdmMTc=
12
+ data.tar.gz: !binary |-
13
+ MjY5ZjUxYTMyNDA4Yjg1OGMwOGZjODA5MDE1NGUxYjg0NGJjY2M1Mzk0ZTYw
14
+ ZmQxZDhlZTQwMjUzM2JhMzdhYjAzZDIyYzFmMWI2MGUwYmM1N2RlYjhhYjc4
15
+ YzhkZWEzYjIxZTg5NWI4OTYwNDJkYWRjY2IwZjczNjZjOGE1ZjU=
data/.gitignore CHANGED
@@ -12,3 +12,5 @@ pkg
12
12
  *.log
13
13
  *.json
14
14
  .rspec
15
+
16
+ *.gem
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-1.9.3-p484
1
+ ruby-1.9.3-p551
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gorgon (0.8.1)
4
+ gorgon (0.8.2)
5
5
  amqp (~> 1.1.0)
6
6
  awesome_print
7
7
  colorize (~> 0.5.8)
data/gorgon.json.sample CHANGED
@@ -30,6 +30,6 @@
30
30
  "test/functional/**/*_test.rb",
31
31
  "test/integration/**/*_test.rb"
32
32
  ],
33
-
33
+ "runtime_file": "tmp/recorded_specs_list.json",
34
34
  "originator_log_file": "log/gorgon-orginator.log"
35
35
  }
@@ -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 ||= configuration[:files].reduce([]) do |memo, obj|
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
+
@@ -1,3 +1,3 @@
1
1
  module Gorgon
2
- VERSION = "0.8.1"
2
+ VERSION = "0.8.2"
3
3
  end
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(filename)
97
- exchange.publish make_finish_message(filename, test_results)
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
- {:action => :start, :hostname => Socket.gethostname, :worker_id => @worker_id, :filename => filename}
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
- {:action => :finish, :hostname => Socket.gethostname, :worker_id => @worker_id, :filename => filename}.merge(results)
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/Fitzsimmons/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.
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/Fitzsimmons/Gorgon/master/gorgon_listener.json.sample
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.1
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-11-14 00:00:00.000000000 Z
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.0.14
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
@@ -1,9 +0,0 @@
1
- require 'acceptance_spec_helper'
2
-
3
- describe 'Gorgon' do
4
- it 'run tests' do
5
- pending 'Use a different observer of job_state to check expectations'
6
-
7
- run_originator
8
- end
9
- end