cukeforker 0.0.1
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 +6 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.mdown +26 -0
- data/Rakefile +5 -0
- data/bin/cukeforker +9 -0
- data/cukeforker.gemspec +25 -0
- data/lib/cukeforker.rb +20 -0
- data/lib/cukeforker/abstract_listener.rb +39 -0
- data/lib/cukeforker/logging_listener.rb +65 -0
- data/lib/cukeforker/runner.rb +104 -0
- data/lib/cukeforker/version.rb +3 -0
- data/lib/cukeforker/vnc_listener.rb +21 -0
- data/lib/cukeforker/vnc_server.rb +62 -0
- data/lib/cukeforker/vnc_server_pool.rb +68 -0
- data/lib/cukeforker/worker.rb +87 -0
- data/lib/cukeforker/worker_queue.rb +113 -0
- data/spec/cukeforker/logging_listener_spec.rb +45 -0
- data/spec/cukeforker/runner_spec.rb +84 -0
- data/spec/cukeforker/vnc_listener_spec.rb +32 -0
- data/spec/cukeforker/vnc_server_pool_spec.rb +62 -0
- data/spec/cukeforker/vnc_server_spec.rb +48 -0
- data/spec/cukeforker/worker_queue_spec.rb +117 -0
- data/spec/cukeforker/worker_spec.rb +102 -0
- data/spec/spec_helper.rb +28 -0
- metadata +135 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
module CukeForker
|
4
|
+
describe WorkerQueue do
|
5
|
+
let(:workers) { Array.new(5) { |n| mock("Worker-#{n}") } }
|
6
|
+
let(:queue) { WorkerQueue.new(3) }
|
7
|
+
|
8
|
+
it "adds an item to the queue" do
|
9
|
+
queue.should_not be_backed_up
|
10
|
+
queue.add workers.first
|
11
|
+
queue.should be_backed_up
|
12
|
+
end
|
13
|
+
|
14
|
+
it "starts up to the max number of workers" do
|
15
|
+
queue.should_not be_full
|
16
|
+
queue.should be_empty
|
17
|
+
|
18
|
+
workers.each { |w| queue.add w }
|
19
|
+
|
20
|
+
workers[0].should_receive(:start)
|
21
|
+
workers[1].should_receive(:start)
|
22
|
+
workers[2].should_receive(:start)
|
23
|
+
|
24
|
+
queue.fill
|
25
|
+
|
26
|
+
queue.size.should == 3
|
27
|
+
queue.should be_full
|
28
|
+
queue.should be_backed_up
|
29
|
+
end
|
30
|
+
|
31
|
+
it "removes finished workers from the queue" do
|
32
|
+
workers.each do |w|
|
33
|
+
w.should_receive(:start)
|
34
|
+
queue.add w
|
35
|
+
end
|
36
|
+
|
37
|
+
queue.fill
|
38
|
+
|
39
|
+
workers[0].stub!(:finished? => true)
|
40
|
+
workers[1].stub!(:finished? => true)
|
41
|
+
workers[2].stub!(:finished? => false)
|
42
|
+
|
43
|
+
queue.poll
|
44
|
+
|
45
|
+
queue.should_not be_full
|
46
|
+
queue.size.should == 1
|
47
|
+
|
48
|
+
queue.fill
|
49
|
+
|
50
|
+
queue.should be_full
|
51
|
+
end
|
52
|
+
|
53
|
+
it "notifies observers when workers are started or finished" do
|
54
|
+
listener = AbstractListener.new
|
55
|
+
queue.add_observer listener
|
56
|
+
|
57
|
+
workers.each { |w| queue.add w }
|
58
|
+
|
59
|
+
workers[0].stub(:start => nil, :finished? => true)
|
60
|
+
workers[1].stub(:start => nil, :finished? => true)
|
61
|
+
workers[2].stub(:start => nil, :finished? => false)
|
62
|
+
|
63
|
+
listener.should_receive(:on_worker_starting).exactly(3).times
|
64
|
+
queue.fill
|
65
|
+
|
66
|
+
listener.should_receive(:on_worker_finished).exactly(2).times
|
67
|
+
queue.poll
|
68
|
+
end
|
69
|
+
|
70
|
+
it "knows if any of the workers failed" do
|
71
|
+
workers.each { |w| queue.add w }
|
72
|
+
|
73
|
+
workers[0].stub(:start => nil, :finished? => true, :failed? => true)
|
74
|
+
workers[1].stub(:start => nil, :finished? => true, :failed? => false)
|
75
|
+
workers[2].stub(:start => nil, :finished? => true, :failed? => false)
|
76
|
+
|
77
|
+
queue.fill
|
78
|
+
queue.poll
|
79
|
+
|
80
|
+
queue.should have_failures
|
81
|
+
end
|
82
|
+
|
83
|
+
it "processes the queue until no longer backed up" do
|
84
|
+
workers.each { |w| queue.add w }
|
85
|
+
|
86
|
+
workers[0].stub(:start => nil, :finished? => true, :failed? => true)
|
87
|
+
workers[1].stub(:start => nil, :finished? => true, :failed? => false)
|
88
|
+
workers[2].stub(:start => nil, :finished? => true, :failed? => false)
|
89
|
+
workers[3].stub(:start => nil, :finished? => true, :failed? => false)
|
90
|
+
workers[4].stub(:start => nil, :finished? => true, :failed? => false)
|
91
|
+
|
92
|
+
queue.process
|
93
|
+
|
94
|
+
queue.should_not be_backed_up
|
95
|
+
queue.should_not be_full
|
96
|
+
end
|
97
|
+
|
98
|
+
it "polls until all workers are finished" do
|
99
|
+
queue.stub :start_time => Time.now
|
100
|
+
workers[0..2].each { |w| queue.add w }
|
101
|
+
|
102
|
+
workers[0].stub(:start => nil)
|
103
|
+
workers[1].stub(:start => nil)
|
104
|
+
workers[2].stub(:start => nil)
|
105
|
+
|
106
|
+
workers[0].should_receive(:finished?).twice.and_return false, true
|
107
|
+
workers[1].should_receive(:finished?).twice.and_return false, true
|
108
|
+
workers[2].should_receive(:finished?).twice.and_return false, true
|
109
|
+
|
110
|
+
queue.fill
|
111
|
+
queue.should_not be_backed_up
|
112
|
+
queue.should be_full
|
113
|
+
|
114
|
+
queue.wait_until_finished
|
115
|
+
end
|
116
|
+
end # WorkerQueue
|
117
|
+
end # CukeForker
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
module CukeForker
|
4
|
+
describe Worker do
|
5
|
+
let(:worker) { Worker.new("some/feature", :json, "some/path", %w[--extra args]) }
|
6
|
+
|
7
|
+
before {
|
8
|
+
FileUtils.stub :mkdir_p
|
9
|
+
}
|
10
|
+
|
11
|
+
it "creates an argument string based on the given parameters" do
|
12
|
+
worker.args.should == %w{--format json --out some/path/some_feature.json --extra args some/feature }
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has an output file" do
|
16
|
+
worker.output.should == "some/path/some_feature.json"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has a stdout file" do
|
20
|
+
worker.stdout.should == "some/path/some_feature.stdout"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has a stderr file" do
|
24
|
+
worker.stderr.should == "some/path/some_feature.stderr"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has a text representation" do
|
28
|
+
worker.text.should include("some/feature")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "runs a passing cuke and exits with 0" do
|
32
|
+
Process.should_receive(:fork).and_yield.and_return(1234)
|
33
|
+
$stdout.should_receive(:reopen).with("some/path/some_feature.stdout")
|
34
|
+
$stderr.should_receive(:reopen).with("some/path/some_feature.stderr")
|
35
|
+
|
36
|
+
Cucumber::Cli::Main.should_receive(:execute).and_return(false)
|
37
|
+
worker.should_receive(:exit).with(0)
|
38
|
+
|
39
|
+
worker.start
|
40
|
+
end
|
41
|
+
|
42
|
+
it "runs a failing cuke and exits with 1" do
|
43
|
+
Process.should_receive(:fork).and_yield.and_return(1234)
|
44
|
+
$stdout.should_receive(:reopen).with("some/path/some_feature.stdout")
|
45
|
+
$stderr.should_receive(:reopen).with("some/path/some_feature.stderr")
|
46
|
+
|
47
|
+
Cucumber::Cli::Main.should_receive(:execute).and_return(true)
|
48
|
+
worker.should_receive(:exit).with(1)
|
49
|
+
|
50
|
+
worker.start
|
51
|
+
end
|
52
|
+
|
53
|
+
it "sets DISPLAY if a VNC server is set" do
|
54
|
+
worker.vnc = mock(VncServer, :display => ":5")
|
55
|
+
|
56
|
+
Process.should_receive(:fork).and_yield.and_return(1234)
|
57
|
+
$stdout.should_receive(:reopen).with("some/path/some_feature.stdout")
|
58
|
+
$stderr.should_receive(:reopen).with("some/path/some_feature.stderr")
|
59
|
+
Cucumber::Cli::Main.should_receive(:execute).and_return(false)
|
60
|
+
worker.should_receive(:exit).with(0)
|
61
|
+
|
62
|
+
ENV.should_receive(:[]=).with("DISPLAY", ":5")
|
63
|
+
|
64
|
+
worker.start
|
65
|
+
end
|
66
|
+
|
67
|
+
it "considers itself failed if status wasn't collected" do
|
68
|
+
worker.stub :status => nil
|
69
|
+
worker.should be_failed
|
70
|
+
end
|
71
|
+
|
72
|
+
it "considers itself failed if the exit code was 1" do
|
73
|
+
worker.stub :status => mock(:exitstatus => 1)
|
74
|
+
worker.should be_failed
|
75
|
+
end
|
76
|
+
|
77
|
+
it "considers itself failed if the exit code was 0" do
|
78
|
+
worker.stub :status => mock(:exitstatus => 0)
|
79
|
+
worker.should_not be_failed
|
80
|
+
end
|
81
|
+
|
82
|
+
it "knows if the child is still running" do
|
83
|
+
Process.stub :waitpid2 => nil
|
84
|
+
worker.should_not be_finished
|
85
|
+
end
|
86
|
+
|
87
|
+
it "knows if the child is finished" do
|
88
|
+
Process.stub :waitpid2 => [1234, :some_status]
|
89
|
+
worker.should be_finished
|
90
|
+
worker.status.should == :some_status
|
91
|
+
end
|
92
|
+
|
93
|
+
it "knows if the child has already been reaped" do
|
94
|
+
Process.stub(:waitpid2).and_raise(Errno::ECHILD)
|
95
|
+
worker.should be_finished
|
96
|
+
|
97
|
+
Process.stub(:waitpid2).and_raise(Errno::ESRCH)
|
98
|
+
worker.should be_finished
|
99
|
+
end
|
100
|
+
|
101
|
+
end # Worker
|
102
|
+
end # CukeForker
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
if ENV['COVERAGE']
|
2
|
+
raise "simplecov only works on 1.9" unless RUBY_PLATFORM >= "1.9"
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.start {
|
5
|
+
add_filter "spec/"
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift File.expand_path("../lib")
|
10
|
+
require 'cukeforker'
|
11
|
+
|
12
|
+
module CukeForker
|
13
|
+
module SpecHelper
|
14
|
+
class FakeVnc
|
15
|
+
def start
|
16
|
+
# noop
|
17
|
+
end
|
18
|
+
|
19
|
+
def display
|
20
|
+
":1"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.configure { |c|
|
27
|
+
c.include CukeForker::SpecHelper
|
28
|
+
}
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cukeforker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Jari Bakken
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-21 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: cucumber
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rspec
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :development
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: simplecov
|
48
|
+
prerelease: false
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id003
|
59
|
+
description: Library to maintain a forking queue of Cucumber processes, with optional VNC displays.
|
60
|
+
email:
|
61
|
+
- jari.bakken@gmail.com
|
62
|
+
executables:
|
63
|
+
- cukeforker
|
64
|
+
extensions: []
|
65
|
+
|
66
|
+
extra_rdoc_files: []
|
67
|
+
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- .rspec
|
71
|
+
- Gemfile
|
72
|
+
- LICENSE
|
73
|
+
- README.mdown
|
74
|
+
- Rakefile
|
75
|
+
- bin/cukeforker
|
76
|
+
- cukeforker.gemspec
|
77
|
+
- lib/cukeforker.rb
|
78
|
+
- lib/cukeforker/abstract_listener.rb
|
79
|
+
- lib/cukeforker/logging_listener.rb
|
80
|
+
- lib/cukeforker/runner.rb
|
81
|
+
- lib/cukeforker/version.rb
|
82
|
+
- lib/cukeforker/vnc_listener.rb
|
83
|
+
- lib/cukeforker/vnc_server.rb
|
84
|
+
- lib/cukeforker/vnc_server_pool.rb
|
85
|
+
- lib/cukeforker/worker.rb
|
86
|
+
- lib/cukeforker/worker_queue.rb
|
87
|
+
- spec/cukeforker/logging_listener_spec.rb
|
88
|
+
- spec/cukeforker/runner_spec.rb
|
89
|
+
- spec/cukeforker/vnc_listener_spec.rb
|
90
|
+
- spec/cukeforker/vnc_server_pool_spec.rb
|
91
|
+
- spec/cukeforker/vnc_server_spec.rb
|
92
|
+
- spec/cukeforker/worker_queue_spec.rb
|
93
|
+
- spec/cukeforker/worker_spec.rb
|
94
|
+
- spec/spec_helper.rb
|
95
|
+
has_rdoc: true
|
96
|
+
homepage: ""
|
97
|
+
licenses: []
|
98
|
+
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
version: "0"
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
version: "0"
|
120
|
+
requirements: []
|
121
|
+
|
122
|
+
rubyforge_project: cukeforker
|
123
|
+
rubygems_version: 1.3.7
|
124
|
+
signing_key:
|
125
|
+
specification_version: 3
|
126
|
+
summary: Library to maintain a forking queue of Cucumber processes
|
127
|
+
test_files:
|
128
|
+
- spec/cukeforker/logging_listener_spec.rb
|
129
|
+
- spec/cukeforker/runner_spec.rb
|
130
|
+
- spec/cukeforker/vnc_listener_spec.rb
|
131
|
+
- spec/cukeforker/vnc_server_pool_spec.rb
|
132
|
+
- spec/cukeforker/vnc_server_spec.rb
|
133
|
+
- spec/cukeforker/worker_queue_spec.rb
|
134
|
+
- spec/cukeforker/worker_spec.rb
|
135
|
+
- spec/spec_helper.rb
|