jcukeforker 0.2.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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.mdown +45 -0
- data/Rakefile +7 -0
- data/bin/cukeforker +9 -0
- data/jcukeforker.gemspec +29 -0
- data/lib/jcukeforker/abstract_listener.rb +57 -0
- data/lib/jcukeforker/configurable_vnc_server.rb +16 -0
- data/lib/jcukeforker/formatters/junit_scenario_formatter.rb +40 -0
- data/lib/jcukeforker/formatters/scenario_line_logger.rb +28 -0
- data/lib/jcukeforker/logging_listener.rb +59 -0
- data/lib/jcukeforker/recording_vnc_listener.rb +60 -0
- data/lib/jcukeforker/runner.rb +155 -0
- data/lib/jcukeforker/scenarios.rb +43 -0
- data/lib/jcukeforker/status_server.rb +37 -0
- data/lib/jcukeforker/task_manager.rb +45 -0
- data/lib/jcukeforker/version.rb +3 -0
- data/lib/jcukeforker/worker.rb +122 -0
- data/lib/jcukeforker/worker_script.rb +6 -0
- data/lib/jcukeforker.rb +29 -0
- data/spec/jcukeforker/formatters/scenario_line_logger_spec.rb +44 -0
- data/spec/jcukeforker/logging_listener_spec.rb +43 -0
- data/spec/jcukeforker/recording_vnc_listener_spec.rb +81 -0
- data/spec/jcukeforker/runner_spec.rb +94 -0
- data/spec/jcukeforker/scenarios_spec.rb +67 -0
- data/spec/jcukeforker/status_server_spec.rb +36 -0
- data/spec/jcukeforker/task_manager_spec.rb +48 -0
- data/spec/jcukeforker/worker_spec.rb +27 -0
- data/spec/spec_helper.rb +6 -0
- metadata +183 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
module JCukeForker
|
4
|
+
describe Runner do
|
5
|
+
|
6
|
+
context "creating" do
|
7
|
+
it "sets up a new instance" do
|
8
|
+
# sigh.
|
9
|
+
|
10
|
+
max = 4
|
11
|
+
format = :json
|
12
|
+
out = "/tmp"
|
13
|
+
listeners = [double(AbstractListener, :update => nil)]
|
14
|
+
log = false
|
15
|
+
features = %w[a b]
|
16
|
+
delay = 1
|
17
|
+
|
18
|
+
mock_task_manager = double(TaskManager, :update => nil)
|
19
|
+
mock_status_server = double(StatusServer)
|
20
|
+
mock_tasks = Array.new(2) { |n| double("Worker-#{n}") }
|
21
|
+
|
22
|
+
TaskManager.should_receive(:new).and_return mock_task_manager
|
23
|
+
StatusServer.should_receive(:new).with('6333').and_return mock_status_server
|
24
|
+
|
25
|
+
mock_status_server.should_receive(:add_observer).with listeners.first
|
26
|
+
mock_status_server.should_receive(:add_observer).with mock_task_manager
|
27
|
+
|
28
|
+
mock_task_manager.should_receive(:add).with(feature: features[0], format: format, out: out, extra_args: [])
|
29
|
+
mock_task_manager.should_receive(:add).with(feature: features[1], format: format, out: out, extra_args: [])
|
30
|
+
|
31
|
+
Runner.create(features,
|
32
|
+
:max => max,
|
33
|
+
:notify => listeners,
|
34
|
+
:format => format,
|
35
|
+
:log => false,
|
36
|
+
:out => out,
|
37
|
+
:delay => 1
|
38
|
+
).should be_kind_of(Runner)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "creates and runs a new runner" do
|
42
|
+
r = double(Runner)
|
43
|
+
Runner.should_receive(:create).with(%w[a b], {}).and_return(r)
|
44
|
+
r.should_receive(:run)
|
45
|
+
|
46
|
+
Runner.run(%w[a b])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "running" do
|
51
|
+
let(:listener) { double(AbstractListener, :update => nil) }
|
52
|
+
let(:queue) { double(Queue, :has_failures? => false) }
|
53
|
+
let(:status_server0) { double(StatusServer, :run => nil) }
|
54
|
+
let(:status_server) { double(StatusServer, :async => status_server0, :shutdown => nil) }
|
55
|
+
let(:process) { double(ChildProcess, :start => nil, :wait => nil) }
|
56
|
+
let(:work_dir) { '/tmp/jcukeforker-testdir' }
|
57
|
+
let(:vnc_pool) { double(VncTools::ServerPool, :stop => nil) }
|
58
|
+
let(:runner) { Runner.new(status_server, [process], work_dir, vnc_pool, 0) }
|
59
|
+
|
60
|
+
it "processes the queue" do
|
61
|
+
runner.add_observer listener
|
62
|
+
|
63
|
+
listener.should_receive(:update).with(:on_run_starting)
|
64
|
+
process.should_receive(:start)
|
65
|
+
process.should_receive(:wait)
|
66
|
+
# listener.should_receive(:update).with(:on_run_finished, false)
|
67
|
+
FileUtils.should_receive(:rm_r).with(work_dir)
|
68
|
+
|
69
|
+
runner.run
|
70
|
+
end
|
71
|
+
|
72
|
+
it "fires on_run_interrupted and shuts down if the run is interrupted" do
|
73
|
+
runner.add_observer listener
|
74
|
+
|
75
|
+
process.stub(:wait).and_raise(Interrupt)
|
76
|
+
runner.stub(:stop)
|
77
|
+
listener.should_receive(:update).with(:on_run_interrupted)
|
78
|
+
|
79
|
+
runner.run
|
80
|
+
end
|
81
|
+
|
82
|
+
it "fires on_run_interrupted and shuts down if an error occurs" do
|
83
|
+
runner.add_observer listener
|
84
|
+
|
85
|
+
process.stub(:wait).and_raise(StandardError)
|
86
|
+
runner.stub(:stop)
|
87
|
+
listener.should_receive(:update).with(:on_run_interrupted)
|
88
|
+
|
89
|
+
lambda { runner.run }.should raise_error(StandardError)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end # Runner
|
94
|
+
end # CukeForker
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
module JCukeForker
|
4
|
+
describe Scenarios do
|
5
|
+
it "returns all scenarios and their line numbers" do
|
6
|
+
feature_1 = Cucumber::FeatureFile.new("features/test1.feature")
|
7
|
+
feature_2 = Cucumber::FeatureFile.new("features/test2.feature")
|
8
|
+
|
9
|
+
feature_1.instance_variable_set(:@source,
|
10
|
+
"Feature: test 1
|
11
|
+
Scenario: test scenario 1
|
12
|
+
Given nothing happens
|
13
|
+
|
14
|
+
Scenario: test scenario 2
|
15
|
+
Given nothing else happens")
|
16
|
+
|
17
|
+
|
18
|
+
feature_2.instance_variable_set(:@source,
|
19
|
+
"Feature: test 2
|
20
|
+
|
21
|
+
Scenario: test scenario 3
|
22
|
+
Given nothing happens
|
23
|
+
|
24
|
+
Scenario Outline: test scenario 4
|
25
|
+
Given nothing happens
|
26
|
+
Examples:
|
27
|
+
| nothing |
|
28
|
+
| 1 |
|
29
|
+
")
|
30
|
+
|
31
|
+
Cucumber::FeatureFile.stub(:new).with("features/test1.feature").and_return(feature_1)
|
32
|
+
Cucumber::FeatureFile.stub(:new).with("features/test2.feature").and_return(feature_2)
|
33
|
+
|
34
|
+
Scenarios.stub(:feature_files).and_return(['features/test1.feature', 'features/test2.feature'])
|
35
|
+
|
36
|
+
all_scenarios = Scenarios.all
|
37
|
+
|
38
|
+
all_scenarios.length.should == 4
|
39
|
+
all_scenarios[0].should == "features/test1.feature:2"
|
40
|
+
all_scenarios[1].should == "features/test1.feature:5"
|
41
|
+
all_scenarios[2].should == "features/test2.feature:3"
|
42
|
+
all_scenarios[3].should == "features/test2.feature:6"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns all scenarios and their line numbers" do
|
46
|
+
feature_1 = Cucumber::FeatureFile.new("features/test1.feature")
|
47
|
+
|
48
|
+
feature_1.instance_variable_set(:@source,
|
49
|
+
"Feature: test 1
|
50
|
+
@find_me
|
51
|
+
Scenario: test scenario 1
|
52
|
+
Given nothing happens
|
53
|
+
|
54
|
+
Scenario: test scenario 2
|
55
|
+
Given nothing else happens")
|
56
|
+
|
57
|
+
Cucumber::FeatureFile.stub(:new).with("features/test1.feature").and_return(feature_1)
|
58
|
+
|
59
|
+
Scenarios.stub(:feature_files).and_return(['features/test1.feature'])
|
60
|
+
|
61
|
+
all_scenarios = Scenarios.by_args(%W[-t @find_me])
|
62
|
+
|
63
|
+
all_scenarios.length.should == 1
|
64
|
+
all_scenarios[0].should == "features/test1.feature:3"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
module JCukeForker
|
4
|
+
describe StatusServer do
|
5
|
+
it "initializes at designated port" do
|
6
|
+
mock_tcp_server = double(TCPServer).as_null_object
|
7
|
+
|
8
|
+
TCPServer.should_receive(:new).with('localhost', '4444').and_return mock_tcp_server
|
9
|
+
|
10
|
+
StatusServer.new '4444'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can handle a connection" do
|
14
|
+
|
15
|
+
status = :on_worker_register
|
16
|
+
worker_path = 'worker-path'
|
17
|
+
raw_message = [status, worker_path].to_json
|
18
|
+
|
19
|
+
# register a listener, just do an end to end test
|
20
|
+
mock_listener = double(AbstractListener, :update => nil)
|
21
|
+
mock_listener.should_receive(:update).with(status.to_s, worker_path)
|
22
|
+
|
23
|
+
# expect the worker to register
|
24
|
+
status_server = StatusServer.new
|
25
|
+
status_server.add_observer mock_listener
|
26
|
+
|
27
|
+
socket = TCPSocket.new 'localhost', '6333'
|
28
|
+
socket.puts raw_message
|
29
|
+
socket.close
|
30
|
+
|
31
|
+
status_server.handle_connection( status_server.instance_variable_get(:@server).accept )
|
32
|
+
|
33
|
+
status_server.shutdown
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
module JCukeForker
|
4
|
+
describe TaskManager do
|
5
|
+
let(:worker_path) { '/tmp/jcukeforker-test-socket' }
|
6
|
+
let(:task) { {name: 'my task'} }
|
7
|
+
let(:mock_socket) { double('socket', :puts => nil) }
|
8
|
+
|
9
|
+
it "can register a worker" do
|
10
|
+
|
11
|
+
UNIXSocket.stub(:open).and_return(mock_socket)
|
12
|
+
expect(mock_socket).to receive(:puts).with(task.to_json)
|
13
|
+
|
14
|
+
task_manager = TaskManager.new
|
15
|
+
task_manager.add task
|
16
|
+
task_manager.on_worker_register worker_path
|
17
|
+
end
|
18
|
+
|
19
|
+
it "can finish task" do
|
20
|
+
|
21
|
+
expect(mock_socket).to receive(:puts).with(task.to_json)
|
22
|
+
|
23
|
+
task_manager = TaskManager.new
|
24
|
+
task_manager.add task
|
25
|
+
task_manager.instance_variable_get(:@worker_sockets)[worker_path] = mock_socket
|
26
|
+
task_manager.on_task_finished worker_path, nil, nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can close dead worker" do
|
30
|
+
|
31
|
+
expect(mock_socket).to receive(:close)
|
32
|
+
|
33
|
+
task_manager = TaskManager.new
|
34
|
+
task_manager.add task
|
35
|
+
task_manager.instance_variable_get(:@worker_sockets)[worker_path] = mock_socket
|
36
|
+
task_manager.on_worker_dead worker_path
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can send '__KILL__' when there are no tasks left" do
|
40
|
+
|
41
|
+
expect(mock_socket).to receive(:puts).with('__KILL__')
|
42
|
+
|
43
|
+
task_manager = TaskManager.new
|
44
|
+
task_manager.instance_variable_get(:@worker_sockets)[worker_path] = mock_socket
|
45
|
+
task_manager.on_task_finished worker_path, nil, nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
module JCukeForker
|
4
|
+
describe Worker do
|
5
|
+
let(:worker_path) { '/tmp/jcukeforker-test-socket' }
|
6
|
+
let(:status_path) { '6333' }
|
7
|
+
let(:mock_status_socket) { double(TCPSocket, :close => nil) }
|
8
|
+
let(:mock_worker_server) { double(UNIXServer, :close => nil) }
|
9
|
+
let(:mock_worker_socket) { double(UNIXSocket, :close => nil) }
|
10
|
+
let(:worker) do
|
11
|
+
TCPSocket.should_receive(:new).with('localhost', status_path).and_return(mock_status_socket)
|
12
|
+
Worker.new status_path, worker_path
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can create worker" do
|
16
|
+
worker
|
17
|
+
end
|
18
|
+
|
19
|
+
it "can register worker" do
|
20
|
+
UNIXServer.should_receive(:new).with(worker_path).and_return(mock_worker_server)
|
21
|
+
|
22
|
+
mock_status_socket.should_receive(:puts).with("[\"on_worker_register\",\"/tmp/jcukeforker-test-socket\"]")
|
23
|
+
|
24
|
+
worker.register
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jcukeforker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jason Gowan
|
8
|
+
- Jari Bakken
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-08-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: cucumber
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 1.1.5
|
21
|
+
requirement: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - '>='
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 1.1.5
|
26
|
+
prerelease: false
|
27
|
+
type: :runtime
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: vnctools
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 0.1.1
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.1.1
|
40
|
+
prerelease: false
|
41
|
+
type: :runtime
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: celluloid-io
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.15.0
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.15.0
|
54
|
+
prerelease: false
|
55
|
+
type: :runtime
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: childprocess
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.5.3
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.5.3
|
68
|
+
prerelease: false
|
69
|
+
type: :runtime
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.5'
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ~>
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '2.5'
|
82
|
+
prerelease: false
|
83
|
+
type: :development
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: coveralls
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
prerelease: false
|
97
|
+
type: :development
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rake
|
100
|
+
version_requirements: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ~>
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 0.9.2
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.9.2
|
110
|
+
prerelease: false
|
111
|
+
type: :development
|
112
|
+
description: Library to maintain a forking queue of Cucumber processes, with optional VNC displays.
|
113
|
+
email:
|
114
|
+
- gowanjason@gmail.com
|
115
|
+
executables:
|
116
|
+
- cukeforker
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- .gitignore
|
121
|
+
- .rspec
|
122
|
+
- Gemfile
|
123
|
+
- LICENSE
|
124
|
+
- README.mdown
|
125
|
+
- Rakefile
|
126
|
+
- bin/cukeforker
|
127
|
+
- jcukeforker.gemspec
|
128
|
+
- lib/jcukeforker.rb
|
129
|
+
- lib/jcukeforker/abstract_listener.rb
|
130
|
+
- lib/jcukeforker/configurable_vnc_server.rb
|
131
|
+
- lib/jcukeforker/formatters/junit_scenario_formatter.rb
|
132
|
+
- lib/jcukeforker/formatters/scenario_line_logger.rb
|
133
|
+
- lib/jcukeforker/logging_listener.rb
|
134
|
+
- lib/jcukeforker/recording_vnc_listener.rb
|
135
|
+
- lib/jcukeforker/runner.rb
|
136
|
+
- lib/jcukeforker/scenarios.rb
|
137
|
+
- lib/jcukeforker/status_server.rb
|
138
|
+
- lib/jcukeforker/task_manager.rb
|
139
|
+
- lib/jcukeforker/version.rb
|
140
|
+
- lib/jcukeforker/worker.rb
|
141
|
+
- lib/jcukeforker/worker_script.rb
|
142
|
+
- spec/jcukeforker/formatters/scenario_line_logger_spec.rb
|
143
|
+
- spec/jcukeforker/logging_listener_spec.rb
|
144
|
+
- spec/jcukeforker/recording_vnc_listener_spec.rb
|
145
|
+
- spec/jcukeforker/runner_spec.rb
|
146
|
+
- spec/jcukeforker/scenarios_spec.rb
|
147
|
+
- spec/jcukeforker/status_server_spec.rb
|
148
|
+
- spec/jcukeforker/task_manager_spec.rb
|
149
|
+
- spec/jcukeforker/worker_spec.rb
|
150
|
+
- spec/spec_helper.rb
|
151
|
+
homepage: ''
|
152
|
+
licenses: []
|
153
|
+
metadata: {}
|
154
|
+
post_install_message:
|
155
|
+
rdoc_options: []
|
156
|
+
require_paths:
|
157
|
+
- lib
|
158
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
requirements:
|
160
|
+
- - '>='
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '0'
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - '>='
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
requirements: []
|
169
|
+
rubyforge_project: jcukeforker
|
170
|
+
rubygems_version: 2.1.9
|
171
|
+
signing_key:
|
172
|
+
specification_version: 4
|
173
|
+
summary: Library to maintain a forking queue of Cucumber processes
|
174
|
+
test_files:
|
175
|
+
- spec/jcukeforker/formatters/scenario_line_logger_spec.rb
|
176
|
+
- spec/jcukeforker/logging_listener_spec.rb
|
177
|
+
- spec/jcukeforker/recording_vnc_listener_spec.rb
|
178
|
+
- spec/jcukeforker/runner_spec.rb
|
179
|
+
- spec/jcukeforker/scenarios_spec.rb
|
180
|
+
- spec/jcukeforker/status_server_spec.rb
|
181
|
+
- spec/jcukeforker/task_manager_spec.rb
|
182
|
+
- spec/jcukeforker/worker_spec.rb
|
183
|
+
- spec/spec_helper.rb
|