cukeforker 0.1.0 → 0.1.1

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