deep_test_pre 2.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.
Files changed (98) hide show
  1. data/CHANGELOG +47 -0
  2. data/README.rdoc +199 -0
  3. data/Rakefile +137 -0
  4. data/lib/deep_test.rb +78 -0
  5. data/lib/deep_test/agent.rb +108 -0
  6. data/lib/deep_test/central_command.rb +165 -0
  7. data/lib/deep_test/cpu_info.rb +22 -0
  8. data/lib/deep_test/database/mysql_setup_listener.rb +112 -0
  9. data/lib/deep_test/database/setup_listener.rb +116 -0
  10. data/lib/deep_test/deadlock_detector.rb +7 -0
  11. data/lib/deep_test/demon.rb +25 -0
  12. data/lib/deep_test/distributed/beachhead.rb +104 -0
  13. data/lib/deep_test/distributed/dispatch_controller.rb +60 -0
  14. data/lib/deep_test/distributed/establish_beachhead.rb +19 -0
  15. data/lib/deep_test/distributed/filename_resolver.rb +40 -0
  16. data/lib/deep_test/distributed/landing_fleet.rb +30 -0
  17. data/lib/deep_test/distributed/landing_ship.rb +60 -0
  18. data/lib/deep_test/distributed/remote_deployment.rb +56 -0
  19. data/lib/deep_test/distributed/rsync.rb +50 -0
  20. data/lib/deep_test/distributed/shell_environment.rb +50 -0
  21. data/lib/deep_test/distributed/ssh_client_connection_info.rb +14 -0
  22. data/lib/deep_test/extensions/object_extension.rb +40 -0
  23. data/lib/deep_test/failure_message.rb +19 -0
  24. data/lib/deep_test/lib_root.rb +4 -0
  25. data/lib/deep_test/listener_list.rb +17 -0
  26. data/lib/deep_test/local_deployment.rb +46 -0
  27. data/lib/deep_test/logger.rb +32 -0
  28. data/lib/deep_test/main.rb +41 -0
  29. data/lib/deep_test/marshallable_exception_wrapper.rb +44 -0
  30. data/lib/deep_test/metrics/data.rb +34 -0
  31. data/lib/deep_test/metrics/measurement.rb +39 -0
  32. data/lib/deep_test/null_listener.rb +62 -0
  33. data/lib/deep_test/options.rb +113 -0
  34. data/lib/deep_test/proxy_io.rb +77 -0
  35. data/lib/deep_test/rake_tasks.rb +13 -0
  36. data/lib/deep_test/result_reader.rb +40 -0
  37. data/lib/deep_test/rspec_detector.rb +21 -0
  38. data/lib/deep_test/spec.rb +17 -0
  39. data/lib/deep_test/spec/extensions/example_group_methods.rb +64 -0
  40. data/lib/deep_test/spec/extensions/example_methods.rb +52 -0
  41. data/lib/deep_test/spec/extensions/options.rb +43 -0
  42. data/lib/deep_test/spec/extensions/spec_task.rb +21 -0
  43. data/lib/deep_test/spec/runner.rb +72 -0
  44. data/lib/deep_test/spec/work_result.rb +35 -0
  45. data/lib/deep_test/spec/work_unit.rb +59 -0
  46. data/lib/deep_test/test.rb +10 -0
  47. data/lib/deep_test/test/extensions/error.rb +14 -0
  48. data/lib/deep_test/test/run_test_suite.rb +5 -0
  49. data/lib/deep_test/test/runner.rb +24 -0
  50. data/lib/deep_test/test/supervised_test_suite.rb +48 -0
  51. data/lib/deep_test/test/work_result.rb +35 -0
  52. data/lib/deep_test/test/work_unit.rb +40 -0
  53. data/lib/deep_test/test_task.rb +47 -0
  54. data/lib/deep_test/ui/console.rb +74 -0
  55. data/lib/deep_test/ui/null.rb +17 -0
  56. data/lib/deep_test/warlock.rb +146 -0
  57. data/lib/telegraph.rb +29 -0
  58. data/lib/telegraph/ack_sequence.rb +14 -0
  59. data/lib/telegraph/logging.rb +20 -0
  60. data/lib/telegraph/message.rb +39 -0
  61. data/lib/telegraph/operator.rb +47 -0
  62. data/lib/telegraph/switchboard.rb +57 -0
  63. data/lib/telegraph/wire.rb +73 -0
  64. data/test/deep_test/agent_test.rb +175 -0
  65. data/test/deep_test/central_command_test.rb +147 -0
  66. data/test/deep_test/cpu_info_test.rb +33 -0
  67. data/test/deep_test/database/mysql_setup_listener_test.rb +18 -0
  68. data/test/deep_test/demon_test.rb +23 -0
  69. data/test/deep_test/distributed/beachhead_test.rb +67 -0
  70. data/test/deep_test/distributed/dispatch_controller_test.rb +162 -0
  71. data/test/deep_test/distributed/filename_resolver_test.rb +56 -0
  72. data/test/deep_test/distributed/landing_fleet_test.rb +55 -0
  73. data/test/deep_test/distributed/landing_ship_test.rb +48 -0
  74. data/test/deep_test/distributed/remote_deployment_test.rb +134 -0
  75. data/test/deep_test/distributed/rsync_test.rb +47 -0
  76. data/test/deep_test/distributed/shell_environment_test.rb +108 -0
  77. data/test/deep_test/distributed/ssh_client_connection_info_test.rb +34 -0
  78. data/test/deep_test/extensions/object_extension_test.rb +37 -0
  79. data/test/deep_test/listener_list_test.rb +22 -0
  80. data/test/deep_test/local_deployment_test.rb +19 -0
  81. data/test/deep_test/logger_test.rb +38 -0
  82. data/test/deep_test/main_test.rb +12 -0
  83. data/test/deep_test/marshallable_exception_wrapper_test.rb +46 -0
  84. data/test/deep_test/metrics/data_test.rb +22 -0
  85. data/test/deep_test/metrics/measurement_test.rb +18 -0
  86. data/test/deep_test/proxy_io_test.rb +104 -0
  87. data/test/deep_test/result_reader_test.rb +128 -0
  88. data/test/deep_test/test/extensions/error_test.rb +42 -0
  89. data/test/deep_test/test/runner_test.rb +11 -0
  90. data/test/deep_test/test/supervised_test_suite_test.rb +107 -0
  91. data/test/deep_test/test/work_result_test.rb +85 -0
  92. data/test/deep_test/test/work_unit_test.rb +63 -0
  93. data/test/deep_test/test_task_test.rb +15 -0
  94. data/test/deep_test/ui/console_test.rb +13 -0
  95. data/test/deep_test/warlock_test.rb +40 -0
  96. data/test/test_helper.rb +30 -0
  97. data/test/test_task_test.rb +75 -0
  98. metadata +156 -0
@@ -0,0 +1,175 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ module DeepTest
4
+ unit_tests do
5
+ test "puts result on central_command with acknowledgement of work" do
6
+ options = Options.new({})
7
+ central_command = TestCentralCommand.start options
8
+ central_command.write_work Test::WorkUnit.new(TestFactory.passing_test)
9
+ central_command.done_with_work
10
+
11
+ Agent.new(0, options, stub_everything).execute(StringIO.new, StringIO.new)
12
+
13
+ assert_equal [], central_command.switchboard.live_wires.first.unacked_messages
14
+ assert_kind_of ::Test::Unit::TestResult, central_command.take_result
15
+ end
16
+
17
+ test "puts passing and failing tests on central_command for each test" do
18
+ options = Options.new({})
19
+ central_command = TestCentralCommand.start options
20
+ central_command.write_work Test::WorkUnit.new(TestFactory.passing_test)
21
+ central_command.write_work Test::WorkUnit.new(TestFactory.failing_test)
22
+ central_command.done_with_work
23
+
24
+ Agent.new(0, options, stub_everything).execute(StringIO.new, StringIO.new)
25
+
26
+ result_1 = central_command.take_result
27
+ result_2 = central_command.take_result
28
+
29
+ assert_equal true, (result_1.passed? || result_2.passed?)
30
+ assert_equal false, (result_1.passed? && result_2.passed?)
31
+ end
32
+
33
+ test "notifies listener that it is starting" do
34
+ options = Options.new({})
35
+ central_command = TestCentralCommand.start options
36
+ central_command.done_with_work
37
+ listener = stub_everything
38
+ agent = Agent.new(0, options, listener)
39
+ listener.expects(:starting).with(agent)
40
+ agent.execute(StringIO.new, StringIO.new)
41
+ end
42
+
43
+ test "notifies listener that it is about to do work" do
44
+ options = Options.new({})
45
+ central_command = TestCentralCommand.start options
46
+ work_unit = Test::WorkUnit.new(TestFactory.passing_test)
47
+ central_command.write_work work_unit
48
+ central_command.done_with_work
49
+ listener = stub_everything
50
+ agent = Agent.new(0, options, listener)
51
+ listener.expects(:starting_work).with(agent, work_unit)
52
+ agent.execute(StringIO.new, StringIO.new)
53
+ end
54
+
55
+ test "notifies listener that it has done work" do
56
+ options = Options.new({})
57
+ central_command = TestCentralCommand.start(options)
58
+ work_unit = ResultWorkUnit.new(:result)
59
+ central_command.write_work work_unit
60
+ central_command.done_with_work
61
+ listener = stub_everything
62
+ agent = Agent.new(0, options, listener)
63
+ listener.expects(:finished_work).with(agent, work_unit, TestResult.new(:result))
64
+ agent.execute(StringIO.new, StringIO.new)
65
+ end
66
+
67
+ test "connect indicates it has connected" do
68
+ options = Options.new({})
69
+ central_command = TestCentralCommand.start(options)
70
+ agent = Agent.new(0, options, stub_everything)
71
+ yielded = false
72
+ agent.connect(io = StringIO.new) do
73
+ yielded = true
74
+ assert_equal "Connected\n", io.string
75
+ assert_equal true, io.closed?
76
+ end
77
+ assert yielded, "connect didn't yield"
78
+ end
79
+
80
+ test "connect closes stream even if there is an error" do
81
+ options = Options.new({})
82
+ agent = Agent.new(0, options, stub_everything)
83
+ io = StringIO.new
84
+ assert_raises(Errno::EADDRNOTAVAIL) { agent.connect io }
85
+ assert_equal true, io.closed?
86
+ end
87
+
88
+ class ResultWorkUnit
89
+ attr_reader :result
90
+
91
+ def initialize(result)
92
+ @result = result
93
+ end
94
+
95
+ def run
96
+ TestResult.new(result)
97
+ end
98
+
99
+ def ==(other)
100
+ other.class == self.class && other.result == result
101
+ end
102
+ end
103
+
104
+ class ErrorWorkUnit
105
+ attr_reader :exception
106
+
107
+ def initialize(exception)
108
+ @exception = exception
109
+ end
110
+
111
+ def run
112
+ raise @exception
113
+ end
114
+
115
+ def ==(other)
116
+ other.class == self.class && other.exception == exception
117
+ end
118
+ end
119
+
120
+ test "exception raised by work unit gives in Agent::Error" do
121
+ options = Options.new({})
122
+ central_command = TestCentralCommand.start options
123
+ work_unit = ErrorWorkUnit.new(exception = TestException.new)
124
+ central_command.write_work work_unit
125
+ central_command.done_with_work
126
+
127
+ Agent.new(0, options, stub_everything).execute(StringIO.new, StringIO.new)
128
+
129
+ assert_equal Agent::Error.new(work_unit, exception), central_command.take_result
130
+ end
131
+
132
+ test "Agent::Error can marshal itself even if the contents are not marshallable" do
133
+ o = Object.new
134
+ def o._dump; raise "error"; end
135
+
136
+ error = Agent::Error.new o, Exception.new("my error")
137
+ error_through_marshalling = Marshal.load Marshal.dump(error)
138
+ assert_equal Exception, error_through_marshalling.error.class
139
+ assert_equal "my error", error_through_marshalling.error.message
140
+ assert_equal "<< Undumpable >>", error_through_marshalling.work_unit
141
+ end
142
+
143
+ test "requests work until it finds some" do
144
+ options = Options.new({})
145
+ central_command = TestCentralCommand.start(options)
146
+
147
+ t = Thread.new { Agent.new(0, options, stub_everything).execute(StringIO.new, StringIO.new) }
148
+ Thread.pass
149
+ central_command.write_work stub(:run => TestResult.new(:result))
150
+ central_command.done_with_work
151
+ t.join
152
+ assert_equal TestResult.new(:result), central_command.take_result
153
+ end
154
+
155
+ test "finish running if a connection error is received" do
156
+ options = Options.new({})
157
+ central_command = TestCentralCommand.start(options)
158
+ begin
159
+ t = Thread.new { Agent.new(0, options, stub_everything).execute(StringIO.new, StringIO.new) }
160
+ sleep 0.1
161
+ ensure
162
+ central_command.stop
163
+ end
164
+ t.join
165
+ end
166
+
167
+ test "number is available to indentify agent" do
168
+ assert_equal 1, Agent.new(1, Options.new({}), nil).number
169
+ end
170
+
171
+ test "does not fork from rake" do
172
+ assert !defined?($rakefile)
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,147 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ module DeepTest
4
+ unit_tests do
5
+ test "take_work returns result of push_work when it is available" do
6
+ central_command = CentralCommand.new Options.new({})
7
+ central_command.write_work :work
8
+ assert_equal :work, central_command.take_work
9
+ end
10
+
11
+ test "take_work raises error when no work is currently available" do
12
+ assert_raises(CentralCommand::NoWorkUnitsAvailableError) do
13
+ CentralCommand.new(Options.new({})).take_work
14
+ end
15
+ end
16
+
17
+ test "take_work raises error when there is no work left to" do
18
+ central_command = CentralCommand.new Options.new({})
19
+ central_command.done_with_work
20
+
21
+ assert_raises(CentralCommand::NoWorkUnitsRemainingError) do
22
+ central_command.take_work
23
+ end
24
+ end
25
+
26
+ test "take_result raises NoAgentsRunningError if agents are connected" do
27
+ central_command = CentralCommand.start Options.new({})
28
+ DynamicTeardown.on_teardown { central_command.stop }
29
+ assert_raises(CentralCommand::NoAgentsRunningError) {central_command.take_result}
30
+ end
31
+
32
+ test "start returns instance of central_command" do
33
+ central_command = CentralCommand.start Options.new({})
34
+ DynamicTeardown.on_teardown { central_command.stop }
35
+ assert_kind_of CentralCommand, central_command
36
+ end
37
+
38
+ test "after starting CentralCommand responds to NeedWork messages by supplying new units of work" do
39
+ central_command = CentralCommand.start(options = Options.new({}))
40
+ DynamicTeardown.on_teardown { central_command.stop }
41
+ central_command.write_work(:a)
42
+ central_command.write_work(:b)
43
+ central_command.write_work(:c)
44
+
45
+ wire = Telegraph::Wire.connect("localhost", options.server_port)
46
+ [:a, :b, :c].each do |work_unit|
47
+ Thread.pass
48
+ wire.send_message CentralCommand::NeedWork
49
+ assert_equal work_unit, wire.next_message(:timeout => 2.0).body
50
+ end
51
+ end
52
+
53
+ test "after starting CentralCommand responds to Result messages adding results to the queue" do
54
+ central_command = CentralCommand.start(options = Options.new({}))
55
+ DynamicTeardown.on_teardown { central_command.stop }
56
+ wire = Telegraph::Wire.connect("localhost", options.server_port)
57
+ result_1, result_2, result_3 = TestResult.new(1), TestResult.new(2), TestResult.new(3)
58
+
59
+ [result_1, result_2, result_3].each do |result|
60
+ wire.send_message result
61
+ end
62
+
63
+ assert_equal result_1, central_command.take_result
64
+ assert_equal result_2, central_command.take_result
65
+ assert_equal result_3, central_command.take_result
66
+ end
67
+
68
+ test "after starting CentralCommand responds to Result by supplying a new unit of work" do
69
+ central_command = CentralCommand.start(options = Options.new({}))
70
+ DynamicTeardown.on_teardown { central_command.stop }
71
+ central_command.write_work(:a)
72
+ central_command.write_work(:b)
73
+ central_command.write_work(:c)
74
+
75
+ wire = Telegraph::Wire.connect("localhost", options.server_port)
76
+ result_1, result_2, result_3 = TestResult.new(1), TestResult.new(2), TestResult.new(3)
77
+ [[result_1, :a], [result_2, :b], [result_3, :c]].each do |result, work_unit|
78
+ Thread.pass
79
+ wire.send_message result_1
80
+ assert_equal work_unit, wire.next_message(:timeout => 2.0).body
81
+ end
82
+ end
83
+
84
+ test "will add results to queue with a worker waiting for work that is not available" do
85
+ central_command = CentralCommand.start(options = Options.new({}))
86
+ DynamicTeardown.on_teardown { central_command.stop }
87
+
88
+ Telegraph::Wire.connect("localhost", options.server_port) do |wire|
89
+ wire.send_message CentralCommand::NeedWork
90
+ wire.send_message TestResult.new(1)
91
+ end
92
+
93
+ assert_equal TestResult.new(1), central_command.take_result
94
+ end
95
+
96
+ test "will distribute work units that have not received results from dead workers when other work runs out" do
97
+ central_command = CentralCommand.start(options = Options.new({}))
98
+ DynamicTeardown.on_teardown { central_command.stop }
99
+
100
+ central_command.write_work(:a)
101
+
102
+ Telegraph::Wire.connect("localhost", options.server_port) do |wire|
103
+ wire.send_message CentralCommand::NeedWork
104
+ assert_equal :a, wire.next_message(:timeout => 1).body
105
+ end
106
+
107
+ Telegraph::Wire.connect("localhost", options.server_port) do |wire|
108
+ wire.send_message CentralCommand::NeedWork
109
+ assert_equal :a, wire.next_message(:timeout => 1).body
110
+ end
111
+ end
112
+
113
+ test "will add measurements to data when received over the wire" do
114
+ central_command = CentralCommand.start(options = Options.new({}))
115
+ DynamicTeardown.on_teardown { central_command.stop }
116
+
117
+ Telegraph::Wire.connect("localhost", options.server_port) do |wire|
118
+ wire.send_message Metrics::Measurement.new("category", 1, "units")
119
+ end
120
+
121
+ sleep 0.05
122
+
123
+ assert_match /category: 1.0 avg/, central_command.data.summary
124
+ end
125
+
126
+ class SetCalledGlobalToTrue
127
+ include CentralCommand::Operation
128
+ def execute; $called = true; end
129
+ end
130
+
131
+ test "will execute Operations read from the wire" do
132
+ $called = false
133
+ DynamicTeardown.on_teardown { $called = nil }
134
+ central_command = CentralCommand.start(options = Options.new({}))
135
+ DynamicTeardown.on_teardown { central_command.stop }
136
+ wire = Telegraph::Wire.connect("localhost", options.server_port)
137
+ wire.send_message SetCalledGlobalToTrue.new
138
+
139
+ Timeout.timeout(2) do
140
+ loop do
141
+ break if $called
142
+ sleep 0.25
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ module DeepTest
4
+ unit_tests do
5
+ test "count parses sysctl output on darwin" do
6
+ cpu_info = CpuInfo.new("foodarwinbar")
7
+ cpu_info.expects(:`).with("sysctl -n hw.ncpu").returns("2\n")
8
+ assert_equal 2, cpu_info.count
9
+ end
10
+
11
+ test "count parses /proc/cpuinfo on linux" do
12
+ cpu_info = CpuInfo.new("foolinuxbar")
13
+ File.expects(:readlines).with("/proc/cpuinfo").returns [
14
+ "processor : 0",
15
+ "vendor_id : GenuineIntel",
16
+ "cpu family : 6",
17
+ "",
18
+ "processor : 1",
19
+ "vendor_id : GenuineIntel",
20
+ "cpu family : 6",
21
+ ]
22
+ assert_equal 2, cpu_info.count
23
+ end
24
+
25
+ test "count returns nil on other platforms" do
26
+ assert_equal nil, CpuInfo.new("foobar").count
27
+ end
28
+
29
+ test "platform defaults to the current ruby_platform" do
30
+ assert_equal RUBY_PLATFORM, CpuInfo.new.platform
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + "/../../test_helper"
2
+
3
+ module DeepTest
4
+ module Database
5
+ unit_tests do
6
+ test "dump_schema includes procedures" do
7
+ listener = MysqlSetupListener.new
8
+ listener.expects(:system).with do |command|
9
+ command =~ / -R /
10
+ end
11
+ listener.expects(:master_database_config).returns({})
12
+ listener.expects(:dump_file_name).returns("")
13
+ $?.expects(:success?).returns(true)
14
+ listener.dump_schema
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ module DeepTest
4
+ unit_tests do
5
+ class ProcDemon
6
+ include Demon
7
+ def initialize(block); @block = block; end
8
+ def execute; @block.call; end
9
+ end
10
+
11
+ test "forked redirects output back to central command" do
12
+ options = Options.new({})
13
+ operator = TestOperator.listen(options)
14
+ ProcDemon.new(proc do
15
+ puts "hello stdout"
16
+ end).forked("name", options, [])
17
+
18
+ assert_equal ProxyIO::Stdout::Output.new("hello stdout"), operator.next_message[0].body
19
+ assert_equal ProxyIO::Stdout::Output.new("\n"), operator.next_message[0].body
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,67 @@
1
+ require File.dirname(__FILE__) + "/../../test_helper"
2
+
3
+ module DeepTest
4
+ module Distributed
5
+ unit_tests do
6
+ test "load_files loads each file in list, resolving each filename with resolver" do
7
+ FilenameResolver.expects(:new).with("/mirror/dir").returns(resolver = mock)
8
+
9
+ beachhead = Beachhead.new "/mirror/dir", Options.new({})
10
+
11
+ resolver.expects(:resolve).with("/source/path/my/file.rb").returns("/mirror/dir/my/file.rb")
12
+ beachhead.expects(:load).with("/mirror/dir/my/file.rb")
13
+ Dir.expects(:chdir).with("/mirror/dir")
14
+
15
+ beachhead.load_files(["/source/path/my/file.rb"])
16
+ end
17
+
18
+ test "service is removed after grace period if agents have not been started" do
19
+ options = Options.new({:number_of_agents => 0})
20
+ TestCentralCommand.start options
21
+ begin
22
+ beachhead = Beachhead.new "", options
23
+ beachhead.daemonize(0.25)
24
+ # Have to sleep long enough to warlock to reap dead process
25
+ sleep 2.0
26
+ assert_equal 0, beachhead.warlock.demon_count
27
+ ensure
28
+ beachhead.warlock.stop_demons
29
+ end
30
+ end
31
+
32
+ test "service is not removed after grace period if agents have been started" do
33
+ options = Options.new({:number_of_agents => 0})
34
+ TestCentralCommand.start options
35
+ begin
36
+ beachhead = Beachhead.new "", options
37
+ # Since we're not actually starting agents, we don't want to exit when none are running for this test
38
+ beachhead.warlock.stubs(:exit_when_none_running)
39
+ port = beachhead.daemonize(0.25)
40
+ Telegraph::Wire.connect("localhost", port).send_message Beachhead::DeployAgents
41
+ # Have to sleep long enough to warlock to reap dead process
42
+ sleep 1.0
43
+ assert_equal 1, beachhead.warlock.demon_count
44
+ ensure
45
+ beachhead.warlock.stop_demons
46
+ end
47
+ end
48
+
49
+ test "responds with Done after receiving LoadFiles and DeployAgents" do
50
+ options = Options.new({:number_of_agents => 0})
51
+ TestCentralCommand.start options
52
+ begin
53
+ beachhead = Beachhead.new File.dirname(__FILE__), options
54
+ # Since we're not actually starting agents, we don't want to exit when none are running for this test
55
+ beachhead.warlock.stubs(:exit_when_none_running)
56
+ port = beachhead.daemonize(0.25)
57
+ wire = Telegraph::Wire.connect("localhost", port)
58
+ wire.send_message Beachhead::LoadFiles.new([])
59
+ wire.send_message Beachhead::DeployAgents
60
+ assert_equal Beachhead::Done, wire.next_message(:timeout => 1).body
61
+ ensure
62
+ beachhead.warlock.stop_demons
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end