cukeforker 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|