cukeforker 0.1.0 → 0.1.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/lib/cukeforker.rb CHANGED
@@ -7,6 +7,7 @@ require "cucumber/cli/main"
7
7
  require "vnctools"
8
8
  require "fileutils"
9
9
  require "observer"
10
+ require "forwardable"
10
11
  require "ostruct"
11
12
 
12
13
  module CukeForker
@@ -1,30 +1,56 @@
1
1
  module CukeForker
2
- class RecordingVncListener < VncListener
3
- def initialize(pool, opts = {})
4
- super(pool)
5
-
6
- @ext = opts[:codec] || "mpeg4"
7
- @options = opts
2
+ class RecordingVncListener < AbstractListener
3
+ extend Forwardable
4
+
5
+ def_delegators :@listener, :on_run_starting, :on_worker_finished, :on_worker_forked,
6
+ :on_run_interrupted, :on_run_finished, :on_display_fetched,
7
+ :on_display_released, :on_display_starting, :on_display_stopping,
8
+ :on_eta
9
+
10
+
11
+ def initialize(listener, opts = {})
12
+ @listener = listener
13
+ @ext = opts[:codec] || "mp4"
14
+ @options = opts
15
+
16
+ @recorders = []
8
17
  end
9
-
18
+
10
19
  def on_worker_starting(worker)
11
- super
12
- worker.data.recorder = recorder_for(worker)
20
+ @listener.on_worker_starting(worker)
21
+
22
+ @recorders << worker.data.recorder = recorder_for(worker)
23
+ worker.data.recorder.start
13
24
  end
14
25
 
15
26
  def on_worker_finished(worker)
16
- worker.data.recorder.stop
27
+ recorder = worker.data.recorder
28
+ recorder.stop
29
+
30
+ unless worker.failed?
31
+ FileUtils.rm_rf recorder.output
32
+ end
33
+
34
+ @recorders.delete(recorder)
17
35
  worker.data.recorder = nil
18
-
19
- super
36
+
37
+ @listener.on_worker_finished(worker)
38
+ end
39
+
40
+ def on_run_interrupted
41
+ @listener.on_run_interrupted
42
+
43
+ @recorders.each do |recorder|
44
+ recorder.stop rescue nil
45
+ end
20
46
  end
21
47
 
22
48
  private
23
-
49
+
24
50
  def recorder_for(worker)
25
51
  display = worker.data.vnc.display
26
52
  output = File.join(worker.out, "#{worker.basename}.#{@ext}")
27
-
53
+
28
54
  VncTools::Recorder.new display, output, @options
29
55
  end
30
56
 
@@ -9,6 +9,8 @@ module CukeForker
9
9
  # :max => Fixnum number of workers (default: 2)
10
10
  # :vnc => true/false children are launched with DISPLAY set from a VNC server pool,
11
11
  # where the size of the pool is equal to :max
12
+ # :record => true/false whether to record a video of failed tests (requires ffmpeg)
13
+ # this will be ignored if if :vnc is not true
12
14
  # :notify => object (or array of objects) implementing the AbstractListener API
13
15
  # :out => path directory to dump output to (default: current working dir)
14
16
  # :log => true/false wether or not to log to stdout (default: true)
@@ -47,7 +49,11 @@ module CukeForker
47
49
 
48
50
  if opts[:vnc]
49
51
  vnc_pool = VncTools::ServerPool.new(max)
50
- listeners << VncListener.new(vnc_pool)
52
+ listener = VncListener.new(vnc_pool)
53
+
54
+ if opts[:record]
55
+ listeners << RecordingVncListener.new(listener)
56
+ end
51
57
  end
52
58
 
53
59
  queue = WorkerQueue.new max
@@ -1,3 +1,3 @@
1
1
  module CukeForker
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -2,9 +2,78 @@ require File.expand_path("../../spec_helper", __FILE__)
2
2
 
3
3
  module CukeForker
4
4
  describe RecordingVncListener do
5
- let(:recorder) { mock(VncTools::Recorder) }
6
- let(:listener) { RecordingVncListener.new nil, :codec => "foo" }
5
+ let(:server) { mock(VncTools::Server, :display => ":2")}
6
+ let(:vnc_listener) { mock(VncListener).as_null_object }
7
+ let(:worker) { mock(Worker, :data => OpenStruct.new(:vnc => server), :out => ".", :basename => "foo", :failed? => true) }
8
+ let(:recorder) { mock(VncTools::Recorder, :start => nil, :stop => nil, :output => "foo.mp4") }
9
+ let(:listener) { RecordingVncListener.new vnc_listener }
10
+
11
+ it "forwards messages to the wrapped listener do" do
12
+ VncTools::Recorder.should_receive(:new).and_return(recorder)
13
+
14
+ # TODO: better way to do this
15
+
16
+ vnc_listener.should_receive :on_run_starting
17
+ vnc_listener.should_receive :on_worker_starting
18
+ vnc_listener.should_receive :on_worker_finished
19
+ vnc_listener.should_receive :on_worker_forked
20
+ vnc_listener.should_receive :on_run_interrupted
21
+ vnc_listener.should_receive :on_run_finished
22
+ vnc_listener.should_receive :on_display_fetched
23
+ vnc_listener.should_receive :on_display_released
24
+ vnc_listener.should_receive :on_display_starting
25
+ vnc_listener.should_receive :on_display_stopping
26
+ vnc_listener.should_receive :on_eta
27
+
28
+ listener.on_run_starting
29
+ listener.on_worker_starting worker
30
+ listener.on_worker_finished worker
31
+ listener.on_worker_forked worker
32
+ listener.on_run_interrupted
33
+ listener.on_run_finished
34
+ listener.on_display_fetched
35
+ listener.on_display_released
36
+ listener.on_display_starting
37
+ listener.on_display_stopping
38
+ listener.on_eta
39
+ end
40
+
41
+ it "starts recording when the worker is started" do
42
+ VncTools::Recorder.should_receive(:new).with(":2", "./foo.mp4", {}).and_return(recorder)
43
+ recorder.should_receive(:start)
44
+
45
+ listener.on_worker_starting worker
46
+ end
47
+
48
+ it "stops recording when the worker is finished" do
49
+ worker.data.recorder = recorder
50
+ recorder.should_receive(:stop)
51
+
52
+ listener.on_worker_finished worker
53
+
54
+ worker.data.recorder.should be_nil
55
+ end
56
+
57
+ it "deletes the output file if the worker succeeded" do
58
+ worker.data.recorder = recorder
59
+ recorder.stub(:stop)
60
+
61
+ worker.should_receive(:failed?).and_return(false)
62
+ recorder.should_receive(:output).and_return("./foo.mp4")
63
+ FileUtils.should_receive(:rm_rf).with("./foo.mp4")
64
+
65
+ listener.on_worker_finished worker
66
+ end
67
+
68
+ it "stops all recorders when the run is interrupted" do
69
+ VncTools::Recorder.should_receive(:new).with(":2", "./foo.mp4", {}).and_return(recorder)
70
+ recorder.should_receive(:start)
71
+
72
+ listener.on_worker_starting worker
73
+ recorder.should_receive(:stop)
74
+
75
+ listener.on_run_interrupted
76
+ end
7
77
 
8
- # TODO: yuck inheritance
9
78
  end # RecordingVncListener
10
79
  end # CukeForker
@@ -44,6 +44,17 @@ module CukeForker
44
44
  Runner.create([], :max => 2, :vnc => true)
45
45
  end
46
46
 
47
+ it "sets up VNC recording if :record => true" do
48
+ mock_pool = mock(VncTools::ServerPool, :add_observer => nil)
49
+ VncTools::ServerPool.should_receive(:new).with(2).and_return mock_pool
50
+
51
+ mock_vnc_listener = mock(:update => nil)
52
+ VncListener.should_receive(:new).with(mock_pool).and_return(mock_vnc_listener)
53
+ RecordingVncListener.should_receive(:new).with(mock_vnc_listener).and_return(mock(:update => nil))
54
+
55
+ Runner.create([], :max => 2, :vnc => true, :record => true)
56
+ end
57
+
47
58
  it "creates and runs a new runner" do
48
59
  r = mock(Runner)
49
60
  Runner.should_receive(:create).with(%w[a b], {}).and_return(r)
@@ -78,6 +89,16 @@ module CukeForker
78
89
 
79
90
  runner.run
80
91
  end
92
+
93
+ it "fires on_run_interrupted and shuts down if an error occurs" do
94
+ runner.add_observer listener
95
+
96
+ queue.stub(:process).and_raise(StandardError)
97
+ runner.stub(:stop)
98
+ listener.should_receive(:update).with(:on_run_interrupted)
99
+
100
+ lambda { runner.run }.should raise_error(StandardError)
101
+ end
81
102
  end
82
103
 
83
104
  end # Runner
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: cukeforker
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.1.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jari Bakken
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-02-04 00:00:00 +01:00
13
+ date: 2011-02-11 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency