cukeforker 0.0.9 → 0.1.0
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/cukeforker.gemspec +1 -0
- data/lib/cukeforker.rb +2 -2
- data/lib/cukeforker/recording_vnc_listener.rb +32 -0
- data/lib/cukeforker/runner.rb +1 -1
- data/lib/cukeforker/version.rb +1 -1
- data/spec/cukeforker/logging_listener_spec.rb +1 -1
- data/spec/cukeforker/recording_vnc_listener_spec.rb +10 -0
- data/spec/cukeforker/runner_spec.rb +2 -2
- data/spec/cukeforker/vnc_listener_spec.rb +2 -2
- data/spec/spec_helper.rb +0 -18
- metadata +21 -27
- data/lib/cukeforker/vnc_server.rb +0 -62
- data/lib/cukeforker/vnc_server_pool.rb +0 -68
- data/spec/cukeforker/vnc_server_pool_spec.rb +0 -62
- data/spec/cukeforker/vnc_server_spec.rb +0 -48
data/cukeforker.gemspec
CHANGED
data/lib/cukeforker.rb
CHANGED
@@ -4,6 +4,7 @@ end
|
|
4
4
|
|
5
5
|
|
6
6
|
require "cucumber/cli/main"
|
7
|
+
require "vnctools"
|
7
8
|
require "fileutils"
|
8
9
|
require "observer"
|
9
10
|
require "ostruct"
|
@@ -11,10 +12,9 @@ require "ostruct"
|
|
11
12
|
module CukeForker
|
12
13
|
end
|
13
14
|
|
14
|
-
require 'cukeforker/vnc_server_pool'
|
15
|
-
require 'cukeforker/vnc_server'
|
16
15
|
require 'cukeforker/abstract_listener'
|
17
16
|
require 'cukeforker/vnc_listener'
|
17
|
+
require 'cukeforker/recording_vnc_listener'
|
18
18
|
require 'cukeforker/logging_listener'
|
19
19
|
require 'cukeforker/worker'
|
20
20
|
require 'cukeforker/worker_queue'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module CukeForker
|
2
|
+
class RecordingVncListener < VncListener
|
3
|
+
def initialize(pool, opts = {})
|
4
|
+
super(pool)
|
5
|
+
|
6
|
+
@ext = opts[:codec] || "mpeg4"
|
7
|
+
@options = opts
|
8
|
+
end
|
9
|
+
|
10
|
+
def on_worker_starting(worker)
|
11
|
+
super
|
12
|
+
worker.data.recorder = recorder_for(worker)
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_worker_finished(worker)
|
16
|
+
worker.data.recorder.stop
|
17
|
+
worker.data.recorder = nil
|
18
|
+
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def recorder_for(worker)
|
25
|
+
display = worker.data.vnc.display
|
26
|
+
output = File.join(worker.out, "#{worker.basename}.#{@ext}")
|
27
|
+
|
28
|
+
VncTools::Recorder.new display, output, @options
|
29
|
+
end
|
30
|
+
|
31
|
+
end # RecordingVncListener
|
32
|
+
end # CukeForker
|
data/lib/cukeforker/runner.rb
CHANGED
data/lib/cukeforker/version.rb
CHANGED
@@ -11,7 +11,7 @@ module CukeForker
|
|
11
11
|
mock_worker = mock(Worker, :id => "1", :feature => "foo/bar", :failed? => false)
|
12
12
|
mock_worker2 = mock(Worker, :id => "15", :feature => "foo/baz", :failed? => true)
|
13
13
|
|
14
|
-
mock_display = mock(
|
14
|
+
mock_display = mock(VncTools::Server)
|
15
15
|
mock_display.stub(:display).and_return(nil, ":5", ":15")
|
16
16
|
|
17
17
|
listener.on_run_starting
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
module CukeForker
|
4
|
+
describe RecordingVncListener do
|
5
|
+
let(:recorder) { mock(VncTools::Recorder) }
|
6
|
+
let(:listener) { RecordingVncListener.new nil, :codec => "foo" }
|
7
|
+
|
8
|
+
# TODO: yuck inheritance
|
9
|
+
end # RecordingVncListener
|
10
|
+
end # CukeForker
|
@@ -37,8 +37,8 @@ module CukeForker
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "sets up the VNC pool if :vnc => true" do
|
40
|
-
mock_pool = mock(
|
41
|
-
|
40
|
+
mock_pool = mock(VncTools::ServerPool, :add_observer => nil)
|
41
|
+
VncTools::ServerPool.should_receive(:new).with(2).and_return mock_pool
|
42
42
|
VncListener.should_receive(:new).with(mock_pool).and_return mock(:update => nil)
|
43
43
|
|
44
44
|
Runner.create([], :max => 2, :vnc => true)
|
@@ -2,8 +2,8 @@ require File.expand_path("../../spec_helper", __FILE__)
|
|
2
2
|
|
3
3
|
module CukeForker
|
4
4
|
describe VncListener do
|
5
|
-
let(:server) { mock(
|
6
|
-
let(:pool) { mock(
|
5
|
+
let(:server) { mock(VncTools::Server, :display => ":15") }
|
6
|
+
let(:pool) { mock(VncTools::ServerPool) }
|
7
7
|
let(:worker) { mock(Worker, :data => OpenStruct.new) }
|
8
8
|
let(:listener) { VncListener.new pool }
|
9
9
|
|
data/spec/spec_helper.rb
CHANGED
@@ -8,21 +8,3 @@ end
|
|
8
8
|
|
9
9
|
$LOAD_PATH.unshift File.expand_path("../lib")
|
10
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
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cukeforker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 0
|
8
|
-
- 9
|
9
|
-
version: 0.0.9
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
10
6
|
platform: ruby
|
11
7
|
authors:
|
12
8
|
- Jari Bakken
|
@@ -14,7 +10,7 @@ autorequire:
|
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
12
|
|
17
|
-
date: 2011-
|
13
|
+
date: 2011-02-04 00:00:00 +01:00
|
18
14
|
default_executable:
|
19
15
|
dependencies:
|
20
16
|
- !ruby/object:Gem::Dependency
|
@@ -25,37 +21,42 @@ dependencies:
|
|
25
21
|
requirements:
|
26
22
|
- - ">="
|
27
23
|
- !ruby/object:Gem::Version
|
28
|
-
segments:
|
29
|
-
- 0
|
30
24
|
version: "0"
|
31
25
|
type: :runtime
|
32
26
|
version_requirements: *id001
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
28
|
+
name: vnctools
|
35
29
|
prerelease: false
|
36
30
|
requirement: &id002 !ruby/object:Gem::Requirement
|
37
31
|
none: false
|
38
32
|
requirements:
|
39
33
|
- - ">="
|
40
34
|
- !ruby/object:Gem::Version
|
41
|
-
segments:
|
42
|
-
- 0
|
43
35
|
version: "0"
|
44
|
-
type: :
|
36
|
+
type: :runtime
|
45
37
|
version_requirements: *id002
|
46
38
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
39
|
+
name: rspec
|
48
40
|
prerelease: false
|
49
41
|
requirement: &id003 !ruby/object:Gem::Requirement
|
50
42
|
none: false
|
51
43
|
requirements:
|
52
44
|
- - ">="
|
53
45
|
- !ruby/object:Gem::Version
|
54
|
-
segments:
|
55
|
-
- 0
|
56
46
|
version: "0"
|
57
47
|
type: :development
|
58
48
|
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: simplecov
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
59
60
|
description: Library to maintain a forking queue of Cucumber processes, with optional VNC displays.
|
60
61
|
email:
|
61
62
|
- jari.bakken@gmail.com
|
@@ -77,18 +78,16 @@ files:
|
|
77
78
|
- lib/cukeforker.rb
|
78
79
|
- lib/cukeforker/abstract_listener.rb
|
79
80
|
- lib/cukeforker/logging_listener.rb
|
81
|
+
- lib/cukeforker/recording_vnc_listener.rb
|
80
82
|
- lib/cukeforker/runner.rb
|
81
83
|
- lib/cukeforker/version.rb
|
82
84
|
- lib/cukeforker/vnc_listener.rb
|
83
|
-
- lib/cukeforker/vnc_server.rb
|
84
|
-
- lib/cukeforker/vnc_server_pool.rb
|
85
85
|
- lib/cukeforker/worker.rb
|
86
86
|
- lib/cukeforker/worker_queue.rb
|
87
87
|
- spec/cukeforker/logging_listener_spec.rb
|
88
|
+
- spec/cukeforker/recording_vnc_listener_spec.rb
|
88
89
|
- spec/cukeforker/runner_spec.rb
|
89
90
|
- spec/cukeforker/vnc_listener_spec.rb
|
90
|
-
- spec/cukeforker/vnc_server_pool_spec.rb
|
91
|
-
- spec/cukeforker/vnc_server_spec.rb
|
92
91
|
- spec/cukeforker/worker_queue_spec.rb
|
93
92
|
- spec/cukeforker/worker_spec.rb
|
94
93
|
- spec/spec_helper.rb
|
@@ -106,30 +105,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
105
|
requirements:
|
107
106
|
- - ">="
|
108
107
|
- !ruby/object:Gem::Version
|
109
|
-
segments:
|
110
|
-
- 0
|
111
108
|
version: "0"
|
112
109
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
110
|
none: false
|
114
111
|
requirements:
|
115
112
|
- - ">="
|
116
113
|
- !ruby/object:Gem::Version
|
117
|
-
segments:
|
118
|
-
- 0
|
119
114
|
version: "0"
|
120
115
|
requirements: []
|
121
116
|
|
122
117
|
rubyforge_project: cukeforker
|
123
|
-
rubygems_version: 1.
|
118
|
+
rubygems_version: 1.5.0
|
124
119
|
signing_key:
|
125
120
|
specification_version: 3
|
126
121
|
summary: Library to maintain a forking queue of Cucumber processes
|
127
122
|
test_files:
|
128
123
|
- spec/cukeforker/logging_listener_spec.rb
|
124
|
+
- spec/cukeforker/recording_vnc_listener_spec.rb
|
129
125
|
- spec/cukeforker/runner_spec.rb
|
130
126
|
- spec/cukeforker/vnc_listener_spec.rb
|
131
|
-
- spec/cukeforker/vnc_server_pool_spec.rb
|
132
|
-
- spec/cukeforker/vnc_server_spec.rb
|
133
127
|
- spec/cukeforker/worker_queue_spec.rb
|
134
128
|
- spec/cukeforker/worker_spec.rb
|
135
129
|
- spec/spec_helper.rb
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require "socket"
|
2
|
-
|
3
|
-
module CukeForker
|
4
|
-
class VncServer
|
5
|
-
|
6
|
-
class Error < StandardError
|
7
|
-
end
|
8
|
-
|
9
|
-
class << self
|
10
|
-
def displays
|
11
|
-
Dir[File.expand_path("~/.vnc/*.pid")].map { |e| e[/(\d+)\.pid/, 1] }.compact
|
12
|
-
end
|
13
|
-
|
14
|
-
def all
|
15
|
-
displays.map { |display| new ":#{display}" }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
attr_reader :display
|
20
|
-
|
21
|
-
def initialize(display = nil)
|
22
|
-
@display = display
|
23
|
-
end
|
24
|
-
|
25
|
-
def start
|
26
|
-
if display
|
27
|
-
server display
|
28
|
-
else
|
29
|
-
output = server
|
30
|
-
@display = output[/desktop is #{host}(\S+)/, 1]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def stop
|
35
|
-
server "-kill", display.to_s
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def server(*args)
|
41
|
-
cmd = ['tightvncserver', args, '2>&1'].flatten.compact
|
42
|
-
out = `#{cmd.join ' '}`
|
43
|
-
|
44
|
-
unless last_status.success?
|
45
|
-
raise Error, "could not run tightvncserver: #{out.inspect}"
|
46
|
-
end
|
47
|
-
|
48
|
-
out
|
49
|
-
end
|
50
|
-
|
51
|
-
def last_status
|
52
|
-
$?
|
53
|
-
end
|
54
|
-
|
55
|
-
def host
|
56
|
-
@host ||= Socket.gethostname
|
57
|
-
end
|
58
|
-
end # VncServer
|
59
|
-
end # CukeForker
|
60
|
-
|
61
|
-
|
62
|
-
|
@@ -1,68 +0,0 @@
|
|
1
|
-
module CukeForker
|
2
|
-
class VncServerPool
|
3
|
-
include Observable
|
4
|
-
|
5
|
-
def initialize(capacity, klass = VncServer)
|
6
|
-
@capacity = capacity
|
7
|
-
@servers = Array.new(capacity) { klass.new }
|
8
|
-
@running = []
|
9
|
-
end
|
10
|
-
|
11
|
-
def stop
|
12
|
-
running.each do |s|
|
13
|
-
fire :on_display_stopping, s
|
14
|
-
s.stop
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def size
|
19
|
-
@servers.size
|
20
|
-
end
|
21
|
-
|
22
|
-
def get
|
23
|
-
raise OutOfDisplaysError if @servers.empty?
|
24
|
-
|
25
|
-
server = next_server
|
26
|
-
fire :on_display_fetched, server
|
27
|
-
|
28
|
-
server
|
29
|
-
end
|
30
|
-
|
31
|
-
def release(server)
|
32
|
-
raise TooManyDisplaysError if size == @capacity
|
33
|
-
fire :on_display_released, server
|
34
|
-
|
35
|
-
@servers.unshift server
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def fire(*args)
|
41
|
-
changed
|
42
|
-
notify_observers(*args)
|
43
|
-
end
|
44
|
-
|
45
|
-
def running
|
46
|
-
@running
|
47
|
-
end
|
48
|
-
|
49
|
-
def next_server
|
50
|
-
server = @servers.shift
|
51
|
-
|
52
|
-
if server.display.nil?
|
53
|
-
fire :on_display_starting, server
|
54
|
-
server.start
|
55
|
-
@running << server
|
56
|
-
end
|
57
|
-
|
58
|
-
server
|
59
|
-
end
|
60
|
-
|
61
|
-
class TooManyDisplaysError < StandardError
|
62
|
-
end
|
63
|
-
|
64
|
-
class OutOfDisplaysError < StandardError
|
65
|
-
end
|
66
|
-
|
67
|
-
end # DisplayPool
|
68
|
-
end # CukeForker
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
-
|
3
|
-
module CukeForker
|
4
|
-
describe VncServerPool do
|
5
|
-
let(:pool) { VncServerPool.new(3, SpecHelper::FakeVnc) }
|
6
|
-
|
7
|
-
it "creates 3 instances of the given display class" do
|
8
|
-
SpecHelper::FakeVnc.should_receive(:new).exactly(3).times
|
9
|
-
|
10
|
-
pool = VncServerPool.new(3, SpecHelper::FakeVnc)
|
11
|
-
pool.size.should == 3
|
12
|
-
end
|
13
|
-
|
14
|
-
it "can fetch a server from the pool" do
|
15
|
-
pool.get.should be_kind_of(SpecHelper::FakeVnc)
|
16
|
-
pool.size.should == 2
|
17
|
-
end
|
18
|
-
|
19
|
-
it "can release a server" do
|
20
|
-
obj = pool.get
|
21
|
-
pool.size.should == 2
|
22
|
-
|
23
|
-
pool.release obj
|
24
|
-
end
|
25
|
-
|
26
|
-
it "can stop the pool" do
|
27
|
-
mock_server = mock(VncServer)
|
28
|
-
|
29
|
-
pool.stub(:running => [mock_server])
|
30
|
-
mock_server.should_receive(:stop)
|
31
|
-
|
32
|
-
pool.stop
|
33
|
-
end
|
34
|
-
|
35
|
-
it "raises a TooManyDisplaysError if the pool is over capacity" do
|
36
|
-
lambda { pool.release "foo" }.should raise_error(VncServerPool::TooManyDisplaysError)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "raises a OutOfDisplaysError if the pool is empty" do
|
40
|
-
3.times { pool.get }
|
41
|
-
lambda { pool.get }.should raise_error(VncServerPool::OutOfDisplaysError)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "notifies observers" do
|
45
|
-
server = mock(VncServer, :start => nil, :stop => nil)
|
46
|
-
observer = mock(AbstractListener)
|
47
|
-
|
48
|
-
SpecHelper::FakeVnc.stub :new => server
|
49
|
-
|
50
|
-
observer.should_receive(:update).with :on_display_fetched , server
|
51
|
-
observer.should_receive(:update).with :on_display_released, server
|
52
|
-
observer.should_receive(:update).with :on_display_starting, server
|
53
|
-
observer.should_receive(:update).with :on_display_stopping , server
|
54
|
-
|
55
|
-
pool.add_observer observer
|
56
|
-
|
57
|
-
pool.release pool.get
|
58
|
-
pool.stop
|
59
|
-
end
|
60
|
-
|
61
|
-
end # VncServerPool
|
62
|
-
end # CukeForker
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
-
|
3
|
-
module CukeForker
|
4
|
-
describe VncServer do
|
5
|
-
|
6
|
-
context "managing new displays" do
|
7
|
-
let(:server) { VncServer.new }
|
8
|
-
|
9
|
-
it "starts a new server" do
|
10
|
-
server.should_receive(:`).with("tightvncserver 2>&1").and_return("desktop is #{Socket.gethostname}:1")
|
11
|
-
server.start
|
12
|
-
server.display.should == ":1"
|
13
|
-
end
|
14
|
-
|
15
|
-
it "stops the server" do
|
16
|
-
server.should_receive(:`).with("tightvncserver -kill :5 2>&1")
|
17
|
-
server.stub :display => ":5"
|
18
|
-
server.stop
|
19
|
-
end
|
20
|
-
|
21
|
-
it "raises VncServer::Error if the server could not be started" do
|
22
|
-
server.should_receive(:`).and_return("oops")
|
23
|
-
server.stub :last_status => mock(:success? => false)
|
24
|
-
|
25
|
-
lambda { server.start }.should raise_error(VncServer::Error, /oops/)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
context "controlling an existing display" do
|
30
|
-
let(:server) { VncServer.new ":5" }
|
31
|
-
|
32
|
-
it "starts the server on the given display" do
|
33
|
-
server.should_receive(:`).with("tightvncserver :5 2>&1").and_return("desktop is #{Socket.gethostname}:5")
|
34
|
-
server.start
|
35
|
-
server.display.should == ":5"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
it "returns an instance for all existing displays" do
|
40
|
-
Dir.stub(:[]).and_return [".vnc/qa1:1.pid", ".vnc/qa1:2.pid", ".vnc/qa1:3.pid"]
|
41
|
-
|
42
|
-
all = VncServer.all
|
43
|
-
all.size.should == 3
|
44
|
-
all.map { |e| e.display }.should == [":1", ":2", ":3"]
|
45
|
-
end
|
46
|
-
|
47
|
-
end # VncServer
|
48
|
-
end # CukeForker
|