jcukeforker 0.2.10 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.mdown +1 -1
- data/jcukeforker.gemspec +2 -2
- data/lib/jcukeforker/logging_listener.rb +1 -1
- data/lib/jcukeforker/runner.rb +19 -16
- data/lib/jcukeforker/status_server.rb +12 -18
- data/lib/jcukeforker/task_manager.rb +9 -18
- data/lib/jcukeforker/version.rb +1 -1
- data/lib/jcukeforker/worker.rb +17 -15
- data/lib/jcukeforker.rb +0 -4
- data/spec/jcukeforker/logging_listener_spec.rb +6 -6
- data/spec/jcukeforker/runner_spec.rb +7 -4
- data/spec/jcukeforker/status_server_spec.rb +6 -14
- data/spec/jcukeforker/task_manager_spec.rb +8 -19
- data/spec/jcukeforker/worker_spec.rb +9 -7
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eacfc36a1e04a32f288f0a1bc87c226983276fb6
|
4
|
+
data.tar.gz: 424e070d33ef9f5e2ff838c78d518db25a346532
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ce41ed903f5ab5e56b4c4ac9bc71042d31f1f6cdf32f87ab1474f925d8ac387dde784188264d9eb95c7abf5067fd3fc26b7233e52d5a80a583562bcc20eb75c
|
7
|
+
data.tar.gz: af3f360b1638b2760cf5efe60ca9120da8b0b40adf57b0f54aff97d1dad64c37a27753f098d7c330065ef8a3a4851dccf9fdce402c7418fc31ec1e0394459613
|
data/README.mdown
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Forking cukes and VNC displays.
|
4
4
|
|
5
|
-
Jcukeforker is a fork of cukeforker desgined for jruby.
|
5
|
+
Jcukeforker is a fork of cukeforker desgined for jruby and windows. Jcukeforker > 0.3 should work on windows.
|
6
6
|
|
7
7
|
[![Gem Version](https://badge.fury.io/rb/jcukeforker.svg)](http://badge.fury.io/rb/jcukeforker)
|
8
8
|
[![Build Status](https://secure.travis-ci.org/jesg/jcukeforker.png)](http://travis-ci.org/jesg/jcukeforker)
|
data/jcukeforker.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Jason Gowan", "Jari Bakken"]
|
10
10
|
s.email = ["gowanjason@gmail.com"]
|
11
11
|
s.homepage = ""
|
12
|
-
s.summary = %q{
|
13
|
-
s.description = %q{Library to maintain a forking queue of Cucumber processes, with optional VNC displays. Designed for JRuby.}
|
12
|
+
s.summary = %q{CukeForker, for JRuby and Windows}
|
13
|
+
s.description = %q{Library to maintain a forking queue of Cucumber processes, with optional VNC displays. Designed for JRuby and Windows.}
|
14
14
|
|
15
15
|
s.rubyforge_project = "jcukeforker"
|
16
16
|
|
data/lib/jcukeforker/runner.rb
CHANGED
@@ -19,8 +19,6 @@ module JCukeForker
|
|
19
19
|
# :format => Symbol format passed to `cucumber --format` (default: html)
|
20
20
|
# :extra_args => Array extra arguments passed to cucumber
|
21
21
|
# :delay => Numeric seconds to sleep between each worker is started (default: 0)
|
22
|
-
# :port => String port that the event server runs on
|
23
|
-
# (default: 6333)
|
24
22
|
|
25
23
|
class Runner
|
26
24
|
include Observable
|
@@ -34,7 +32,6 @@ module JCukeForker
|
|
34
32
|
:log => true,
|
35
33
|
:format => :html,
|
36
34
|
:delay => 0,
|
37
|
-
:port => '6333'
|
38
35
|
}
|
39
36
|
|
40
37
|
def self.run(features, opts = {})
|
@@ -47,23 +44,30 @@ module JCukeForker
|
|
47
44
|
max = opts[:max]
|
48
45
|
raise ':max must be >= 1' if max < 1
|
49
46
|
format = opts[:format]
|
50
|
-
out = File.join
|
47
|
+
out = File.expand_path(File.join(opts[:out]))
|
51
48
|
listeners = Array(opts[:notify])
|
52
49
|
extra_args = Array(opts[:extra_args])
|
53
50
|
delay = opts[:delay]
|
54
|
-
port
|
51
|
+
puts "The port option is deprecated in jcukeforker > 0.2.10" if opts[:port]
|
55
52
|
|
56
53
|
if opts[:log]
|
57
54
|
listeners << LoggingListener.new
|
58
55
|
end
|
59
56
|
|
57
|
+
FileUtils.mkdir_p out
|
58
|
+
io_in = File.join out, 'in'
|
59
|
+
io_out = File.join out, 'out'
|
60
|
+
# truncate
|
61
|
+
File.open(io_in, 'w') {}
|
62
|
+
File.open(io_out, 'w') {}
|
63
|
+
|
60
64
|
task_opts = {format: format,out: out,extra_args: extra_args}
|
61
|
-
|
65
|
+
io_out_file = File.open(io_out, 'a')
|
66
|
+
io_out_file.sync = true
|
67
|
+
task_manager = TaskManager.new features, io_out_file, task_opts
|
62
68
|
|
63
69
|
listeners << task_manager
|
64
|
-
status_server = StatusServer.new
|
65
|
-
worker_dir = "/tmp/jcukeforker-#{SecureRandom.hex 4}"
|
66
|
-
FileUtils.mkdir_p worker_dir
|
70
|
+
status_server = StatusServer.new io_in
|
67
71
|
|
68
72
|
vnc_pool = nil
|
69
73
|
if vnc = opts[:vnc]
|
@@ -76,9 +80,9 @@ module JCukeForker
|
|
76
80
|
end
|
77
81
|
end
|
78
82
|
|
79
|
-
processes = create_processes(max,
|
83
|
+
processes = create_processes(max, io_in, io_out, vnc_pool, opts[:record])
|
80
84
|
|
81
|
-
runner = Runner.new status_server, processes,
|
85
|
+
runner = Runner.new status_server, processes, vnc_pool, delay, task_manager
|
82
86
|
|
83
87
|
listeners.each { |l|
|
84
88
|
status_server.add_observer l
|
@@ -88,10 +92,9 @@ module JCukeForker
|
|
88
92
|
runner
|
89
93
|
end
|
90
94
|
|
91
|
-
def initialize(status_server, processes,
|
95
|
+
def initialize(status_server, processes, vnc_pool, delay, task_manager)
|
92
96
|
@status_server = status_server
|
93
97
|
@processes = processes
|
94
|
-
@worker_dir = worker_dir
|
95
98
|
@vnc_pool = vnc_pool
|
96
99
|
@delay = delay
|
97
100
|
@task_manager = task_manager
|
@@ -113,11 +116,11 @@ module JCukeForker
|
|
113
116
|
|
114
117
|
private
|
115
118
|
|
116
|
-
def self.create_processes(max,
|
119
|
+
def self.create_processes(max, io_in, io_out, vnc_pool = nil, record = false)
|
117
120
|
worker_file = "#{File.expand_path File.dirname(__FILE__)}/worker_script.rb"
|
118
121
|
|
119
122
|
(1..max).inject([]) do |l, i|
|
120
|
-
process_args = %W[ruby #{worker_file} #{
|
123
|
+
process_args = %W[ruby #{worker_file} #{io_in} #{io_out} #{i}]
|
121
124
|
if vnc_pool && record
|
122
125
|
if record.kind_of? Hash
|
123
126
|
process_args << record.to_json
|
@@ -128,6 +131,7 @@ module JCukeForker
|
|
128
131
|
process = ChildProcess.build(*process_args)
|
129
132
|
process.io.inherit!
|
130
133
|
process.environment['DISPLAY'] = vnc_pool.get.display if vnc_pool
|
134
|
+
process.environment['JCUKEFORKER_WORKER'] = i
|
131
135
|
l << process
|
132
136
|
end
|
133
137
|
end
|
@@ -150,7 +154,6 @@ module JCukeForker
|
|
150
154
|
@status_server.shutdown
|
151
155
|
ensure # catch potential second Interrupt
|
152
156
|
@vnc_pool.stop if @vnc_pool
|
153
|
-
FileUtils.rm_r @worker_dir
|
154
157
|
fire :on_run_finished, @task_manager.has_failures?
|
155
158
|
end
|
156
159
|
|
@@ -1,41 +1,35 @@
|
|
1
|
-
require 'socket'
|
2
1
|
|
3
2
|
module JCukeForker
|
4
3
|
class StatusServer
|
5
4
|
include Observable
|
6
5
|
|
7
|
-
attr_reader :
|
6
|
+
attr_reader :io_in
|
8
7
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@thread_pool = []
|
8
|
+
def initialize(io_in)
|
9
|
+
@io_in = File.open(io_in, 'r')
|
10
|
+
@io_in.sync = true
|
13
11
|
end
|
14
12
|
|
15
13
|
def run
|
16
14
|
@master_thread = Thread.new do
|
17
15
|
loop do
|
18
|
-
|
19
|
-
|
16
|
+
raw_message = @io_in.gets(sep=$-0)
|
17
|
+
next if raw_message.nil?
|
18
|
+
handle_message(raw_message)
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
23
|
def shutdown
|
25
|
-
if @
|
26
|
-
@
|
24
|
+
if @io_in
|
25
|
+
@io_in.close
|
27
26
|
@master_thread.terminate
|
28
|
-
@thread_pool.each(&:terminate)
|
29
27
|
end
|
30
28
|
end
|
31
29
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
json_obj = JSON.parse raw_message
|
36
|
-
fire json_obj.first, *json_obj[1..-1]
|
37
|
-
end
|
38
|
-
socket.close
|
30
|
+
def handle_message(raw_message)
|
31
|
+
json_obj = JSON.parse raw_message
|
32
|
+
fire json_obj.first, *json_obj[1..-1]
|
39
33
|
end
|
40
34
|
|
41
35
|
private
|
@@ -2,16 +2,14 @@
|
|
2
2
|
module JCukeForker
|
3
3
|
class TaskManager < AbstractListener
|
4
4
|
|
5
|
-
def initialize(features, opts={})
|
5
|
+
def initialize(features, io_out, opts={})
|
6
6
|
@features = features
|
7
7
|
@opts = opts
|
8
|
-
@
|
8
|
+
@io_out = io_out
|
9
9
|
@failures = false
|
10
|
-
@mutex = Mutex.new
|
11
10
|
end
|
12
11
|
|
13
12
|
def on_worker_register(worker_path)
|
14
|
-
@worker_sockets[worker_path] = UNIXSocket.open worker_path
|
15
13
|
pop_task worker_path
|
16
14
|
end
|
17
15
|
|
@@ -20,13 +18,8 @@ module JCukeForker
|
|
20
18
|
pop_task worker_path
|
21
19
|
end
|
22
20
|
|
23
|
-
def on_worker_dead(worker_path)
|
24
|
-
socket = @worker_sockets.delete worker_path
|
25
|
-
socket.close
|
26
|
-
end
|
27
|
-
|
28
21
|
def close
|
29
|
-
|
22
|
+
io_out.close
|
30
23
|
end
|
31
24
|
|
32
25
|
def has_failures?
|
@@ -36,14 +29,12 @@ module JCukeForker
|
|
36
29
|
private
|
37
30
|
|
38
31
|
def pop_task(worker_path)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
@worker_sockets[worker_path].puts(task)
|
32
|
+
task = {action: '__KILL__', worker: worker_path}.to_json
|
33
|
+
if feature = @features.shift
|
34
|
+
task = @opts.merge(worker: worker_path, feature: feature, action: :feature).to_json
|
35
|
+
end
|
36
|
+
|
37
|
+
@io_out.write("#{task}#{$-0}")
|
47
38
|
end
|
48
39
|
end
|
49
40
|
end
|
data/lib/jcukeforker/version.rb
CHANGED
data/lib/jcukeforker/worker.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'socket'
|
2
1
|
require 'securerandom'
|
3
2
|
require 'json'
|
4
3
|
require 'fileutils'
|
@@ -16,40 +15,43 @@ module JCukeForker
|
|
16
15
|
|
17
16
|
attr_reader :feature, :format, :out, :basename
|
18
17
|
|
19
|
-
def initialize(status_path, task_path, recorder = nil)
|
18
|
+
def initialize(status_path, task_path, worker_num, recorder = nil)
|
20
19
|
@status_path = status_path
|
21
20
|
@task_path = task_path
|
21
|
+
@worker_num = worker_num
|
22
22
|
if ENV['DISPLAY'] && recorder
|
23
23
|
config = JSON.parse(recorder)
|
24
24
|
add_observer JCukeForker::RecordingVncListener.new(self, config)
|
25
25
|
end
|
26
|
-
@
|
26
|
+
@status_file = File.open(status_path, 'a')
|
27
|
+
@status_file.sync = true
|
27
28
|
@status = nil
|
28
29
|
end
|
29
30
|
|
30
31
|
def register
|
31
|
-
@
|
32
|
+
@event_file = File.open(@task_path, 'r')
|
32
33
|
update_status :on_worker_register
|
33
34
|
end
|
34
35
|
|
35
36
|
def close
|
36
|
-
@
|
37
|
-
@
|
37
|
+
@event_file.close
|
38
|
+
@status_file.close
|
38
39
|
end
|
39
40
|
|
40
41
|
def run
|
41
|
-
worker_socket = @worker_server.accept
|
42
42
|
loop do
|
43
|
-
raw_message =
|
43
|
+
raw_message = @event_file.gets(sep=$-0)
|
44
44
|
if raw_message.nil? then
|
45
|
-
sleep 0.
|
45
|
+
sleep 0.1
|
46
46
|
next
|
47
47
|
end
|
48
|
-
|
48
|
+
json_obj = JSON.parse raw_message
|
49
|
+
next unless json_obj['worker'] == @worker_num
|
50
|
+
if json_obj['action'] == '__KILL__'
|
49
51
|
update_status :on_worker_dead
|
50
52
|
break
|
51
53
|
end
|
52
|
-
set_state
|
54
|
+
set_state json_obj
|
53
55
|
update_status :on_task_starting, feature
|
54
56
|
status = execute_cucumber
|
55
57
|
update_status :on_task_finished, feature, status
|
@@ -57,12 +59,13 @@ module JCukeForker
|
|
57
59
|
end
|
58
60
|
|
59
61
|
def update_status(meth, *args)
|
60
|
-
message = [meth, @
|
62
|
+
message = [meth, @worker_num]
|
63
|
+
|
61
64
|
message += args
|
62
65
|
|
63
66
|
changed
|
64
67
|
notify_observers *message
|
65
|
-
@
|
68
|
+
@status_file.write("#{message.to_json}#{$-0}")
|
66
69
|
end
|
67
70
|
|
68
71
|
def failed?
|
@@ -91,9 +94,8 @@ module JCukeForker
|
|
91
94
|
|
92
95
|
private
|
93
96
|
|
94
|
-
def set_state(
|
97
|
+
def set_state(json_obj)
|
95
98
|
@status = nil
|
96
|
-
json_obj = JSON.parse raw_message
|
97
99
|
@format = json_obj['format']
|
98
100
|
@feature = json_obj['feature']
|
99
101
|
@extra_args = json_obj['extra_args']
|
data/lib/jcukeforker.rb
CHANGED
@@ -8,8 +8,8 @@ module JCukeForker
|
|
8
8
|
it "logs all events" do
|
9
9
|
Time.stub(:now => Time.now)
|
10
10
|
|
11
|
-
mock_worker = {:path => '
|
12
|
-
mock_worker2 = {:path => '
|
11
|
+
mock_worker = {:path => '1', :feature => 'foo/bar', :status => true }
|
12
|
+
mock_worker2 = {:path => '15', :feature => 'foo/baz', :status => false}
|
13
13
|
|
14
14
|
listener.on_run_starting
|
15
15
|
listener.on_worker_register mock_worker[:path]
|
@@ -27,14 +27,14 @@ module JCukeForker
|
|
27
27
|
|
28
28
|
stdout.string.should == <<-OUTPUT
|
29
29
|
I, [#{timestamp}] INFO -- : [ run ] starting
|
30
|
-
I, [#{timestamp}] INFO -- : [ worker 1 ] register:
|
30
|
+
I, [#{timestamp}] INFO -- : [ worker 1 ] register: 1
|
31
31
|
I, [#{timestamp}] INFO -- : [ worker 1 ] starting: foo/bar
|
32
|
-
I, [#{timestamp}] INFO -- : [ worker 15 ] register:
|
32
|
+
I, [#{timestamp}] INFO -- : [ worker 15 ] register: 15
|
33
33
|
I, [#{timestamp}] INFO -- : [ worker 15 ] starting: foo/baz
|
34
34
|
I, [#{timestamp}] INFO -- : [ worker 1 ] passed : foo/bar
|
35
35
|
I, [#{timestamp}] INFO -- : [ worker 15 ] failed : foo/baz
|
36
|
-
I, [#{timestamp}] INFO -- : [ worker 1 ] dead :
|
37
|
-
I, [#{timestamp}] INFO -- : [ worker 15 ] dead :
|
36
|
+
I, [#{timestamp}] INFO -- : [ worker 1 ] dead : 1
|
37
|
+
I, [#{timestamp}] INFO -- : [ worker 15 ] dead : 15
|
38
38
|
I, [#{timestamp}] INFO -- : [ run ] interrupted - please wait
|
39
39
|
I, [#{timestamp}] INFO -- : [ run ] finished, passed
|
40
40
|
OUTPUT
|
@@ -17,10 +17,14 @@ module JCukeForker
|
|
17
17
|
|
18
18
|
mock_task_manager = double(TaskManager, :update => nil, :has_failures? => false)
|
19
19
|
mock_status_server = double(StatusServer, :port => nil)
|
20
|
+
mock_io_out = double(IO, :sync= => nil)
|
20
21
|
mock_tasks = Array.new(2) { |n| double("Worker-#{n}") }
|
21
22
|
|
22
|
-
TaskManager.should_receive(:new).with(features, {format: format, out: out, extra_args: []}).and_return mock_task_manager
|
23
|
-
StatusServer.should_receive(:new).with('
|
23
|
+
TaskManager.should_receive(:new).with(features, mock_io_out, {format: format, out: out, extra_args: []}).and_return mock_task_manager
|
24
|
+
StatusServer.should_receive(:new).with('/tmp/in').and_return mock_status_server
|
25
|
+
File.should_receive(:open).with('/tmp/in', 'w').and_return mock_io_out
|
26
|
+
File.should_receive(:open).with('/tmp/out', 'w').and_return mock_io_out
|
27
|
+
File.should_receive(:open).with('/tmp/out', 'a').and_return mock_io_out
|
24
28
|
|
25
29
|
mock_status_server.should_receive(:add_observer).with listeners.first
|
26
30
|
mock_status_server.should_receive(:add_observer).with mock_task_manager
|
@@ -52,7 +56,7 @@ module JCukeForker
|
|
52
56
|
let(:work_dir) { '/tmp/jcukeforker-testdir' }
|
53
57
|
let(:vnc_pool) { double(VncTools::ServerPool, :stop => nil) }
|
54
58
|
let(:mock_task_manager) { double(TaskManager, :update => nil, :has_failures? => false) }
|
55
|
-
let(:runner) { Runner.new(status_server, [process],
|
59
|
+
let(:runner) { Runner.new(status_server, [process], vnc_pool, 0, mock_task_manager) }
|
56
60
|
|
57
61
|
|
58
62
|
it "processes the queue" do
|
@@ -62,7 +66,6 @@ module JCukeForker
|
|
62
66
|
process.should_receive(:start)
|
63
67
|
process.should_receive(:wait)
|
64
68
|
# listener.should_receive(:update).with(:on_run_finished, false)
|
65
|
-
FileUtils.should_receive(:rm_r).with(work_dir)
|
66
69
|
|
67
70
|
runner.run
|
68
71
|
end
|
@@ -2,15 +2,8 @@ require File.expand_path("../../spec_helper", __FILE__)
|
|
2
2
|
|
3
3
|
module JCukeForker
|
4
4
|
describe StatusServer do
|
5
|
-
it "initializes at designated port" do
|
6
|
-
mock_tcp_server = double(TCPServer).as_null_object
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
StatusServer.new '4444'
|
11
|
-
end
|
12
|
-
|
13
|
-
it "can handle a connection" do
|
6
|
+
it "can handle a message" do
|
14
7
|
|
15
8
|
status = :on_worker_register
|
16
9
|
worker_path = 'worker-path'
|
@@ -19,16 +12,15 @@ module JCukeForker
|
|
19
12
|
# register a listener, just do an end to end test
|
20
13
|
mock_listener = double(AbstractListener, :update => nil)
|
21
14
|
mock_listener.should_receive(:update).with(status.to_s, worker_path)
|
15
|
+
mock_io = double(IO, :sync= => nil)
|
16
|
+
File.should_receive(:open).with('/tmp/in', 'r').and_return(mock_io)
|
22
17
|
|
23
18
|
# expect the worker to register
|
24
|
-
|
19
|
+
io_in = '/tmp/in'
|
20
|
+
status_server = StatusServer.new io_in
|
25
21
|
status_server.add_observer mock_listener
|
26
22
|
|
27
|
-
|
28
|
-
socket.puts raw_message
|
29
|
-
socket.close
|
30
|
-
|
31
|
-
status_server.handle_connection( status_server.instance_variable_get(:@server).accept )
|
23
|
+
status_server.handle_message(raw_message)
|
32
24
|
|
33
25
|
end
|
34
26
|
end
|
@@ -5,45 +5,34 @@ module JCukeForker
|
|
5
5
|
let(:worker_path) { '/tmp/jcukeforker-test-socket' }
|
6
6
|
let(:feature) { 'feature:1' }
|
7
7
|
let(:mock_socket) { double('socket', :puts => nil) }
|
8
|
+
let(:mock_file) { double(IO, :puts => nil) }
|
8
9
|
|
9
10
|
it "can register a worker" do
|
10
11
|
|
11
|
-
|
12
|
-
mock_socket.should_receive(:puts).with({feature: feature}.to_json)
|
12
|
+
mock_file.should_receive(:write).with("{\"worker\":\"/tmp/jcukeforker-test-socket\",\"feature\":\"feature:1\",\"action\":\"feature\"}#{$-0}")
|
13
13
|
|
14
|
-
task_manager = TaskManager.new [feature]
|
14
|
+
task_manager = TaskManager.new [feature], mock_file
|
15
15
|
task_manager.on_worker_register worker_path
|
16
16
|
end
|
17
17
|
|
18
18
|
it "can finish task" do
|
19
19
|
|
20
|
-
|
20
|
+
mock_file.should_receive(:write).with("{\"worker\":\"/tmp/jcukeforker-test-socket\",\"feature\":\"feature:1\",\"action\":\"feature\"}#{$-0}")
|
21
21
|
|
22
|
-
task_manager = TaskManager.new [feature]
|
23
|
-
task_manager.instance_variable_get(:@worker_sockets)[worker_path] = mock_socket
|
22
|
+
task_manager = TaskManager.new [feature], mock_file
|
24
23
|
task_manager.on_task_finished worker_path, nil, nil
|
25
24
|
end
|
26
25
|
|
27
|
-
it "can close dead worker" do
|
28
|
-
|
29
|
-
mock_socket.should_receive(:close)
|
30
|
-
|
31
|
-
task_manager = TaskManager.new [feature]
|
32
|
-
task_manager.instance_variable_get(:@worker_sockets)[worker_path] = mock_socket
|
33
|
-
task_manager.on_worker_dead worker_path
|
34
|
-
end
|
35
|
-
|
36
26
|
it "can send '__KILL__' when there are no tasks left" do
|
37
27
|
|
38
|
-
|
28
|
+
mock_file.should_receive(:write).with("{\"action\":\"__KILL__\",\"worker\":\"/tmp/jcukeforker-test-socket\"}#{$-0}")
|
39
29
|
|
40
|
-
task_manager = TaskManager.new []
|
41
|
-
task_manager.instance_variable_get(:@worker_sockets)[worker_path] = mock_socket
|
30
|
+
task_manager = TaskManager.new [], mock_file
|
42
31
|
task_manager.on_task_finished worker_path, nil, nil
|
43
32
|
end
|
44
33
|
|
45
34
|
it "can detect failure" do
|
46
|
-
task_manager = TaskManager.new []
|
35
|
+
task_manager = TaskManager.new [], mock_file
|
47
36
|
def task_manager.pop_task(*args); end
|
48
37
|
task_manager.on_task_finished worker_path, feature, false
|
49
38
|
task_manager.has_failures?.should == true
|
@@ -3,13 +3,14 @@ require File.expand_path("../../spec_helper", __FILE__)
|
|
3
3
|
module JCukeForker
|
4
4
|
describe Worker do
|
5
5
|
let(:worker_path) { '/tmp/jcukeforker-test-socket' }
|
6
|
-
let(:status_path) { '
|
7
|
-
let(:
|
6
|
+
let(:status_path) { '/tmp/in' }
|
7
|
+
let(:mock_status_file) { double(IO, :close => nil) }
|
8
8
|
let(:mock_worker_server) { double(UNIXServer, :close => nil) }
|
9
9
|
let(:mock_worker_socket) { double(UNIXSocket, :close => nil) }
|
10
10
|
let(:worker) do
|
11
|
-
|
12
|
-
|
11
|
+
File.should_receive(:open).with('/tmp/in', 'a').and_return(mock_status_file)
|
12
|
+
mock_status_file.should_receive(:sync=).with(true)
|
13
|
+
Worker.new status_path, worker_path, '1'
|
13
14
|
end
|
14
15
|
|
15
16
|
it "can create worker" do
|
@@ -17,9 +18,10 @@ module JCukeForker
|
|
17
18
|
end
|
18
19
|
|
19
20
|
it "can register worker" do
|
20
|
-
UNIXServer.should_receive(:new).with(worker_path).and_return(mock_worker_server)
|
21
21
|
|
22
|
-
|
22
|
+
mock_status_file.should_receive(:write).with("[\"on_worker_register\",\"1\"]#{$-0}")
|
23
|
+
mock_event_file = double(IO)
|
24
|
+
File.should_receive(:open).with(worker_path, 'r').and_return(mock_event_file)
|
23
25
|
|
24
26
|
worker.register
|
25
27
|
end
|
@@ -29,7 +31,7 @@ module JCukeForker
|
|
29
31
|
path = "some/path"
|
30
32
|
|
31
33
|
it "has an output file for each format specified" do
|
32
|
-
json_str = {'format' => formats, 'feature' => 'some/feature:51', 'extra_args' => [], 'out' => path}
|
34
|
+
json_str = {'format' => formats, 'feature' => 'some/feature:51', 'extra_args' => [], 'out' => path}
|
33
35
|
worker.send :set_state, json_str
|
34
36
|
expected_args = formats.flat_map do |f|
|
35
37
|
%W[--format #{f} --out #{path}/some_feature_51.#{f}]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jcukeforker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Gowan
|
@@ -102,7 +102,7 @@ dependencies:
|
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '10'
|
104
104
|
description: Library to maintain a forking queue of Cucumber processes, with optional
|
105
|
-
VNC displays. Designed for JRuby.
|
105
|
+
VNC displays. Designed for JRuby and Windows.
|
106
106
|
email:
|
107
107
|
- gowanjason@gmail.com
|
108
108
|
executables:
|
@@ -161,10 +161,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
161
|
version: '0'
|
162
162
|
requirements: []
|
163
163
|
rubyforge_project: jcukeforker
|
164
|
-
rubygems_version: 2.
|
164
|
+
rubygems_version: 2.2.0
|
165
165
|
signing_key:
|
166
166
|
specification_version: 4
|
167
|
-
summary:
|
167
|
+
summary: CukeForker, for JRuby and Windows
|
168
168
|
test_files:
|
169
169
|
- spec/jcukeforker/formatters/scenario_line_logger_spec.rb
|
170
170
|
- spec/jcukeforker/logging_listener_spec.rb
|