jstorimer-deep-test 1.4.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. data/.gitignore +1 -0
  2. data/README.rdoc +41 -70
  3. data/Rakefile +47 -119
  4. data/TODO +2 -2
  5. data/VERSION +1 -1
  6. data/infrastructure/dynamic_teardown.rb +22 -0
  7. data/{test → infrastructure}/fake_deadlock_error.rb +0 -0
  8. data/infrastructure/load.rb +11 -0
  9. data/infrastructure/test_central_command.rb +15 -0
  10. data/infrastructure/test_exception.rb +7 -0
  11. data/{test → infrastructure}/test_factory.rb +0 -0
  12. data/infrastructure/test_logger.rb +11 -0
  13. data/infrastructure/test_operator.rb +15 -0
  14. data/infrastructure/test_result.rb +15 -0
  15. data/infrastructure/thread_agent.rb +21 -0
  16. data/infrastructure/timewarp/Rakefile +14 -0
  17. data/infrastructure/timewarp/lib/timewarp.rb +21 -0
  18. data/infrastructure/timewarp/test/timewarp_test.rb +45 -0
  19. data/lib/deep_test.rb +28 -40
  20. data/lib/deep_test/agent.rb +108 -0
  21. data/lib/deep_test/central_command.rb +165 -0
  22. data/lib/deep_test/cpu_info.rb +22 -0
  23. data/lib/deep_test/database/mysql_setup_listener.rb +11 -12
  24. data/lib/deep_test/database/setup_listener.rb +23 -23
  25. data/lib/deep_test/demon.rb +25 -0
  26. data/lib/deep_test/distributed/beachhead.rb +104 -0
  27. data/lib/deep_test/distributed/dispatch_controller.rb +17 -10
  28. data/lib/deep_test/distributed/establish_beachhead.rb +19 -0
  29. data/lib/deep_test/distributed/landing_fleet.rb +30 -0
  30. data/lib/deep_test/distributed/landing_ship.rb +60 -0
  31. data/lib/deep_test/distributed/remote_deployment.rb +56 -0
  32. data/lib/deep_test/distributed/rsync.rb +25 -12
  33. data/lib/deep_test/distributed/shell_environment.rb +50 -0
  34. data/lib/deep_test/distributed/ssh_client_connection_info.rb +14 -0
  35. data/lib/deep_test/failure_message.rb +19 -0
  36. data/lib/deep_test/lib_root.rb +4 -0
  37. data/lib/deep_test/listener_list.rb +1 -1
  38. data/lib/deep_test/local_deployment.rb +46 -0
  39. data/lib/deep_test/logger.rb +17 -2
  40. data/lib/deep_test/main.rb +41 -0
  41. data/lib/deep_test/marshallable_exception_wrapper.rb +4 -4
  42. data/lib/deep_test/metrics/data.rb +34 -0
  43. data/lib/deep_test/metrics/measurement.rb +39 -0
  44. data/lib/deep_test/{null_worker_listener.rb → null_listener.rb} +14 -14
  45. data/lib/deep_test/options.rb +41 -56
  46. data/lib/deep_test/proxy_io.rb +77 -0
  47. data/lib/deep_test/rake_tasks.rb +3 -1
  48. data/lib/deep_test/result_reader.rb +10 -6
  49. data/lib/deep_test/rspec_detector.rb +1 -1
  50. data/lib/deep_test/spec.rb +5 -1
  51. data/lib/deep_test/spec/extensions/example_methods.rb +7 -1
  52. data/lib/deep_test/spec/extensions/spec_task.rb +3 -2
  53. data/lib/deep_test/spec/runner.rb +32 -17
  54. data/lib/deep_test/spec/work_result.rb +2 -0
  55. data/lib/deep_test/test/run_test_suite.rb +5 -0
  56. data/lib/deep_test/test/runner.rb +2 -2
  57. data/lib/deep_test/test/supervised_test_suite.rb +9 -10
  58. data/lib/deep_test/test/work_result.rb +1 -0
  59. data/lib/deep_test/test_task.rb +1 -1
  60. data/lib/deep_test/ui/console.rb +9 -11
  61. data/lib/deep_test/warlock.rb +37 -25
  62. data/lib/telegraph.rb +29 -0
  63. data/lib/telegraph/ack_sequence.rb +14 -0
  64. data/lib/telegraph/logging.rb +20 -0
  65. data/lib/telegraph/message.rb +39 -0
  66. data/lib/telegraph/operator.rb +47 -0
  67. data/lib/telegraph/switchboard.rb +57 -0
  68. data/lib/telegraph/wire.rb +73 -0
  69. data/negative_acceptance_tests/dying_spec.rb +13 -0
  70. data/negative_acceptance_tests/dying_test.rb +13 -0
  71. data/negative_acceptance_tests/failing_spec.rb +9 -0
  72. data/{test/failing.rb → negative_acceptance_tests/failing_test.rb} +3 -1
  73. data/negative_acceptance_tests/kill_agent_one_on_start_work.rb +16 -0
  74. data/negative_acceptance_tests/passing_spec.rb +10 -0
  75. data/negative_acceptance_tests/passing_test.rb +12 -0
  76. data/negative_acceptance_tests/tasks.rake +87 -0
  77. data/negative_acceptance_tests/tests.rb +60 -0
  78. data/sample_rails_project/deep_test.rb +4 -0
  79. data/sample_rails_project/lib/{foreign_host_worker_simulation_listener.rb → foreign_host_agent_simulation_listener.rb} +6 -4
  80. data/sample_rails_project/lib/tasks/deep_test.rake +13 -4
  81. data/spec/deep_test/options_spec.rb +80 -59
  82. data/spec/deep_test/spec/extensions/example_methods_spec.rb +5 -4
  83. data/spec/deep_test/spec/extensions/spec_task_spec.rb +4 -6
  84. data/spec/deep_test/spec/runner_spec.rb +59 -32
  85. data/spec/spec_helper.rb +14 -6
  86. data/test/deep_test/agent_test.rb +175 -0
  87. data/test/deep_test/central_command_test.rb +147 -0
  88. data/test/deep_test/cpu_info_test.rb +33 -0
  89. data/test/deep_test/database/mysql_setup_listener_test.rb +13 -9
  90. data/test/deep_test/demon_test.rb +23 -0
  91. data/test/deep_test/distributed/beachhead_test.rb +67 -0
  92. data/test/deep_test/distributed/dispatch_controller_test.rb +130 -177
  93. data/test/deep_test/distributed/filename_resolver_test.rb +38 -34
  94. data/test/deep_test/distributed/landing_fleet_test.rb +55 -0
  95. data/test/deep_test/distributed/landing_ship_test.rb +48 -0
  96. data/test/deep_test/distributed/remote_deployment_test.rb +134 -0
  97. data/test/deep_test/distributed/rsync_test.rb +42 -62
  98. data/test/deep_test/distributed/shell_environment_fixtures/set_bar_to_foo +1 -0
  99. data/test/deep_test/distributed/shell_environment_fixtures/set_foo_to_bar +1 -0
  100. data/test/deep_test/distributed/shell_environment_fixtures/set_foo_to_baz +1 -0
  101. data/test/deep_test/distributed/shell_environment_test.rb +108 -0
  102. data/test/deep_test/distributed/ssh_client_connection_info_test.rb +34 -0
  103. data/test/deep_test/listener_list_test.rb +17 -15
  104. data/test/deep_test/local_deployment_test.rb +19 -0
  105. data/test/deep_test/logger_test.rb +34 -7
  106. data/test/deep_test/main_test.rb +12 -0
  107. data/test/deep_test/marshallable_exception_wrapper_test.rb +31 -29
  108. data/test/deep_test/metrics/data_test.rb +22 -0
  109. data/test/deep_test/metrics/measurement_test.rb +18 -0
  110. data/test/deep_test/proxy_io_test.rb +104 -0
  111. data/test/deep_test/result_reader_test.rb +95 -95
  112. data/test/deep_test/test/extensions/error_test.rb +38 -36
  113. data/test/deep_test/test/runner_test.rb +7 -3
  114. data/test/deep_test/test/supervised_test_suite_test.rb +89 -61
  115. data/test/deep_test/test/work_result_test.rb +80 -76
  116. data/test/deep_test/test/work_unit_test.rb +53 -51
  117. data/test/deep_test/test_task_test.rb +10 -38
  118. data/test/deep_test/ui/console_test.rb +8 -4
  119. data/test/deep_test/warlock_test.rb +33 -31
  120. data/test/test_helper.rb +20 -5
  121. data/test/test_task_test.rb +60 -57
  122. metadata +94 -84
  123. data/bin/deep_test +0 -15
  124. data/jstorimer-deep-test-0.1.0.gem +0 -0
  125. data/jstorimer-deep-test.gemspec +0 -1425
  126. data/lib/deep_test/distributed/drb_client_connection_info.rb +0 -15
  127. data/lib/deep_test/distributed/master_test_server.rb +0 -52
  128. data/lib/deep_test/distributed/multi_test_server_proxy.rb +0 -44
  129. data/lib/deep_test/distributed/null_work_unit.rb +0 -12
  130. data/lib/deep_test/distributed/remote_worker_client.rb +0 -54
  131. data/lib/deep_test/distributed/remote_worker_server.rb +0 -82
  132. data/lib/deep_test/distributed/show_status.rhtml +0 -41
  133. data/lib/deep_test/distributed/test_server.rb +0 -78
  134. data/lib/deep_test/distributed/test_server_status.rb +0 -9
  135. data/lib/deep_test/distributed/test_server_workers.rb +0 -24
  136. data/lib/deep_test/distributed/throughput_runner.rb +0 -42
  137. data/lib/deep_test/distributed/throughput_statistics.rb +0 -26
  138. data/lib/deep_test/distributed/throughput_worker_client.rb +0 -19
  139. data/lib/deep_test/extensions/drb_extension.rb +0 -34
  140. data/lib/deep_test/local_workers.rb +0 -55
  141. data/lib/deep_test/metrics/gatherer.rb +0 -67
  142. data/lib/deep_test/metrics/queue_lock_wait_time_measurement.rb +0 -133
  143. data/lib/deep_test/option.rb +0 -60
  144. data/lib/deep_test/process_orchestrator.rb +0 -49
  145. data/lib/deep_test/server.rb +0 -75
  146. data/lib/deep_test/spec/extensions/reporter.rb +0 -29
  147. data/lib/deep_test/worker.rb +0 -57
  148. data/script/internal/run_test_suite.rb +0 -7
  149. data/script/public/master_test_server.rb +0 -24
  150. data/script/public/test_server.rb +0 -18
  151. data/script/public/test_throughput.rb +0 -29
  152. data/spec/deep_test/option_spec.rb +0 -33
  153. data/spec/thread_worker.rb +0 -25
  154. data/test/deep_test/distributed/drb_client_connection_info_test.rb +0 -42
  155. data/test/deep_test/distributed/master_test_server_test.rb +0 -32
  156. data/test/deep_test/distributed/multi_test_server_proxy_test.rb +0 -96
  157. data/test/deep_test/distributed/remote_worker_client_test.rb +0 -180
  158. data/test/deep_test/distributed/remote_worker_server_test.rb +0 -99
  159. data/test/deep_test/distributed/test_server_test.rb +0 -94
  160. data/test/deep_test/distributed/test_server_workers_test.rb +0 -26
  161. data/test/deep_test/distributed/throughput_runner_test.rb +0 -68
  162. data/test/deep_test/distributed/throughput_worker_client_test.rb +0 -28
  163. data/test/deep_test/local_workers_test.rb +0 -22
  164. data/test/deep_test/metrics/gatherer_test.rb +0 -66
  165. data/test/deep_test/process_orchestrator_test.rb +0 -11
  166. data/test/deep_test/server_test.rb +0 -58
  167. data/test/deep_test/worker_test.rb +0 -94
  168. data/test/failing.rake +0 -11
  169. data/test/simple_test_blackboard.rb +0 -45
  170. data/test/simple_test_blackboard_test.rb +0 -33
@@ -17,9 +17,12 @@ module DeepTest
17
17
 
18
18
  threads = @receivers.map do |r|
19
19
  Thread.new do
20
- Thread.current[:receiver] = r
21
- Timeout.timeout(@options.timeout_in_seconds) do
20
+ begin
21
+ Thread.current[:receiver] = r
22
22
  r.send method_name, *args
23
+ rescue Exception => e
24
+ Thread.current[:original_exception] = e
25
+ raise
23
26
  end
24
27
  end
25
28
  end
@@ -30,15 +33,14 @@ module DeepTest
30
33
  results << t.value
31
34
  rescue Timeout::Error
32
35
  @receivers.delete t[:receiver]
33
- DeepTest.logger.error "Timeout dispatching #{method_name} to #{t[:receiver].__drburi}"
34
- rescue DRb::DRbConnError
36
+ DeepTest.logger.error { "Timeout dispatching #{method_name} to #{description t[:receiver]}" }
37
+ rescue Exception => this_exception
35
38
  @receivers.delete t[:receiver]
36
- unless options[:ignore_connection_error]
37
- DeepTest.logger.error "Connection Refused dispatching #{method_name} to #{t[:receiver].__drburi}"
38
- end
39
- rescue Exception => e
40
- @receivers.delete t[:receiver]
41
- DeepTest.logger.error "Exception while dispatching #{method_name} to #{t[:receiver].__drburi} #{e.message}"
39
+ DeepTest.logger.error { "Exception while dispatching #{method_name} to #{description t[:receiver]}:" }
40
+
41
+ e = t[:original_exception] || this_exception
42
+ DeepTest.logger.error { "#{e.class}: #{e.message}" }
43
+ e.backtrace.each {|l| DeepTest.logger.error { l } }
42
44
  end
43
45
  end
44
46
 
@@ -46,6 +48,11 @@ module DeepTest
46
48
  ensure
47
49
  @options.ui_instance.dispatch_finished(method_name)
48
50
  end
51
+
52
+ def description(receiver)
53
+ receiver.inspect
54
+ end
55
+
49
56
  end
50
57
 
51
58
  class NoDispatchReceiversError < StandardError; end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + "/../../deep_test"
2
+ options = DeepTest::Options.from_command_line(ENV['OPTIONS'])
3
+ ENV['DEEP_TEST_LOG_LEVEL'] = options.environment_log_level
4
+ options.ssh_client_connection_info = DeepTest::Distributed::SshClientConnectionInfo.new
5
+
6
+ DeepTest.logger.debug { "mirror establish_beachhead for #{options.origin_hostname}" }
7
+
8
+ STDIN.close
9
+
10
+ beachhead_port = DeepTest::Distributed::Beachhead.new(
11
+ File.join(options.mirror_path, File.basename(options.sync_options[:source])),
12
+ options
13
+ ).daemonize
14
+
15
+ puts "Beachhead port: #{beachhead_port}"
16
+ $stdout.flush
17
+
18
+ exit!(0)
19
+
@@ -0,0 +1,30 @@
1
+ module DeepTest
2
+ module Distributed
3
+ class LandingFleet
4
+ def initialize(options, slaves)
5
+ DeepTest.logger.debug { "LandingFleet#initialize #{slaves.length} slaves" }
6
+ @slave_controller = DispatchController.new(options, slaves)
7
+ end
8
+
9
+ def establish_beachhead(options)
10
+ DeepTest.logger.debug { "dispatch establish_beachhead for #{options.origin_hostname}" }
11
+ @slave_controller.dispatch :establish_beachhead, options
12
+ end
13
+
14
+ def push_code(options)
15
+ DeepTest.logger.debug { "dispatch push_code for #{options.origin_hostname}" }
16
+ @slave_controller.dispatch :push_code, options
17
+ end
18
+
19
+ def load_files(files)
20
+ DeepTest.logger.debug { "dispatch load_files" }
21
+ @slave_controller.dispatch :load_files, files
22
+ end
23
+
24
+ def deploy_agents
25
+ DeepTest.logger.debug { "dispatch deploy_agents" }
26
+ @slave_controller.dispatch :deploy_agents
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,60 @@
1
+ module DeepTest
2
+ module Distributed
3
+ class LandingShip
4
+ def initialize(config)
5
+ @config = config
6
+ end
7
+
8
+ def push_code(options)
9
+ RSync.push(@config[:address], options.sync_options, options.mirror_path)
10
+ end
11
+
12
+ def establish_beachhead(options)
13
+ command = "#{ssh_command(options)} '#{spawn_command(options)}' 2>&1"
14
+ DeepTest.logger.debug { "Establishing Beachhead: #{command}" }
15
+
16
+ output = `#{command}`
17
+ output.each do |line|
18
+ if DeepTest.logger.level == Logger::DEBUG
19
+ puts output
20
+ end
21
+ if line =~ /Beachhead port: (.+)/
22
+ @wire = Telegraph::Wire.connect(@config[:address], $1.to_i)
23
+ end
24
+ end
25
+ raise "LandingShip unable to establish Beachhead. Output from #{@config[:address]} was:\n#{output}" unless @wire
26
+ end
27
+
28
+ def load_files(files)
29
+ @wire.send_message Beachhead::LoadFiles.new(files)
30
+ end
31
+
32
+ def deploy_agents
33
+ @wire.send_message Beachhead::DeployAgents
34
+ begin
35
+ message = @wire.next_message :timeout => 1
36
+ raise "Unexpected message from Beachhead: #{message.inspect}" unless message.body == Beachhead::Done
37
+ rescue Telegraph::NoMessageAvailable
38
+ retry
39
+ end
40
+ end
41
+
42
+ def ssh_command(options)
43
+ username_option = if options.sync_options[:username]
44
+ " -l #{options.sync_options[:username]}"
45
+ else
46
+ ""
47
+ end
48
+
49
+ "ssh -4 #{@config[:address]}#{username_option}"
50
+ end
51
+
52
+ def spawn_command(options)
53
+ "#{ShellEnvironment.like_login} && " +
54
+ "cd #{options.mirror_path} && " +
55
+ "OPTIONS=#{options.to_command_line} " +
56
+ "ruby lib/deep_test/distributed/establish_beachhead.rb"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,56 @@
1
+ module DeepTest
2
+ module Distributed
3
+ class RemoteDeployment
4
+ def initialize(options, landing_fleet, failover_deployment)
5
+ @failover_deployment = failover_deployment
6
+ @options = options
7
+ @landing_fleet = landing_fleet
8
+ end
9
+
10
+ def load_files(filelist)
11
+ # load one file before calling listeners to make sure environment has
12
+ # been initialized as expected
13
+ #
14
+ load filelist.first
15
+ @options.new_listener_list.before_sync
16
+
17
+ t = Thread.new do
18
+ @landing_fleet.push_code(@options)
19
+ @landing_fleet.establish_beachhead(@options)
20
+ @landing_fleet.load_files filelist
21
+ end
22
+
23
+ filelist[1..-1].each {|f| load f}
24
+
25
+ begin
26
+ t.join
27
+ rescue => e
28
+ # The failover here doesn't invoke load_files on the failover_deployment
29
+ # because it will be a LocalDeployment, which forks from the current
30
+ # process. The fact that we depend in this here is damp...
31
+ #
32
+ fail_over("load_files", e)
33
+ end
34
+ end
35
+
36
+ def deploy_agents
37
+ DeepTest.logger.debug { "RemoteDeployment deploying agents with #{@landing_fleet}" }
38
+ @landing_fleet.deploy_agents
39
+ rescue => e
40
+ raise if failed_over?
41
+ fail_over("deploy_agents", e)
42
+ retry
43
+ end
44
+
45
+ def fail_over(method, exception)
46
+ DeepTest.logger.debug { "RemoteDeployment failing over on #{method}." }
47
+ @options.ui_instance.distributed_failover_to_local(method, exception)
48
+ @landing_fleet = @failover_deployment
49
+ end
50
+
51
+ def failed_over?
52
+ @landing_fleet == @failover_deployment
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,35 +1,48 @@
1
1
  module DeepTest
2
2
  module Distributed
3
3
  class RSync
4
- def self.sync(connection_info, options, destination)
5
- command = Args.new(connection_info, options).command(destination)
6
- DeepTest.logger.debug("rsycing: #{command}")
4
+ def self.push(address, sync_options, destination)
5
+ sync(:push, address, sync_options, destination)
6
+ end
7
+
8
+ def self.sync(operation, address, sync_options, destination)
9
+ command = Args.new(address, sync_options).send("#{operation}_command",
10
+ destination)
11
+
12
+ DeepTest.logger.debug { "rsycing: #{command}" }
7
13
  successful = system command
8
14
  raise "RSync Failed!!" unless successful
9
15
  end
10
16
 
11
17
  class Args
12
- def initialize(connection_info, options)
13
- @connection_info = connection_info
14
- @options = options
15
- @sync_options = options.sync_options
18
+ def initialize(address, sync_options)
19
+ @address = address
20
+ @sync_options = sync_options
21
+ end
22
+
23
+ def pull_command(destination)
24
+ command remote_location(@sync_options[:source]), destination
25
+ end
26
+
27
+ def push_command(destination)
28
+ command @sync_options[:source], remote_location(destination)
16
29
  end
17
30
 
18
- def command(destination)
31
+ def command(source, destination)
19
32
  # The '/' after source tells rsync to copy the contents
20
33
  # of source to destination, rather than the source directory
21
34
  # itself
22
- "rsync -az --delete #{@sync_options[:rsync_options]} #{source_location}/ #{destination}".strip.squeeze(" ")
35
+ "rsync -az --delete #{@sync_options[:rsync_options]} #{DeepTest::LIB_ROOT} #{source} #{destination}".strip.squeeze(" ")
23
36
  end
24
37
 
25
- def source_location
38
+ def remote_location(path)
26
39
  source = ""
27
40
  unless @sync_options[:local]
28
41
  source << @sync_options[:username] << '@' if @sync_options[:username]
29
- source << @connection_info.address
42
+ source << @address
30
43
  source << (@sync_options[:daemon] ? '::' : ':')
31
44
  end
32
- source << @sync_options[:source]
45
+ source << path
33
46
  end
34
47
  end
35
48
  end
@@ -0,0 +1,50 @@
1
+ module DeepTest
2
+ module Distributed
3
+ class ShellEnvironment
4
+ def self.like_login
5
+ login_env = new
6
+ login_env.include_first '/etc/profile'
7
+ login_env.include_first '~/.profile', '~/.bash_profile', '~/.bashrc'
8
+ login_env
9
+ end
10
+
11
+ def initialize
12
+ @source_file_lists = []
13
+ end
14
+
15
+ def include_first(*filenames)
16
+ source_file_lists << SourceFileList.new(filenames)
17
+ end
18
+
19
+ def to_s
20
+ source_file_lists.join(" && ")
21
+ end
22
+
23
+ def ==(other)
24
+ source_file_lists == other.source_file_lists
25
+ end
26
+
27
+ attr_reader :source_file_lists
28
+ protected :source_file_lists
29
+
30
+ class SourceFileList
31
+ def initialize(filenames)
32
+ @filenames = filenames
33
+ end
34
+
35
+ def to_s
36
+ "if" +
37
+ filenames.map {|f| " [[ -f #{f} ]]; then . #{f}; "}.join("elif") +
38
+ "fi"
39
+ end
40
+
41
+ def ==(other)
42
+ filenames == other.filenames
43
+ end
44
+
45
+ attr_reader :filenames
46
+ protected :filenames
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,14 @@
1
+ module DeepTest
2
+ module Distributed
3
+ class SshClientConnectionInfo
4
+ attr_reader :address
5
+
6
+ def initialize
7
+ raise "SSH_CLIENT environment variable not set" unless ENV['SSH_CLIENT']
8
+ ENV['SSH_CLIENT'] =~ /^(.+) \d+ \d+$/
9
+ raise "Unable to extract address from SSH_CLIENT (#{ENV['SSH_CLIENT']})" unless $1
10
+ @address = $1
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module DeepTest
2
+ module FailureMessage
3
+ def self.show(title, message, width = 70)
4
+ lines = [" #{title} ".center(width, '*')]
5
+ message.each do |line|
6
+ lines << "* #{line.strip}".ljust(width - 1) + "*"
7
+ end
8
+ lines << "*" * width
9
+ string = lines.join("\n")
10
+ begin
11
+ puts string
12
+ rescue
13
+ IO.new(2) do |err|
14
+ err.puts string
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,4 @@
1
+ module DeepTest
2
+ LIB_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '/..')) unless defined?(DeepTest::LIB_ROOT)
3
+ end
4
+
@@ -6,7 +6,7 @@ module DeepTest
6
6
  @listeners = listeners
7
7
  end
8
8
 
9
- NullWorkerListener.instance_methods(false).each do |event|
9
+ NullListener.instance_methods(false).each do |event|
10
10
  eval <<-end_src
11
11
  def #{event}(*args)
12
12
  @listeners.each {|l| l.#{event}(*args)}
@@ -0,0 +1,46 @@
1
+ module DeepTest
2
+ class LocalDeployment
3
+ attr_reader :warlock
4
+
5
+ def initialize(options, agent_class = DeepTest::Agent)
6
+ @options = options
7
+ @agent_class = agent_class
8
+ end
9
+
10
+ def warlock
11
+ @warlock ||= Warlock.new @options
12
+ end
13
+
14
+ def load_files(files)
15
+ files.each {|f| load f}
16
+ end
17
+
18
+ def deploy_agents
19
+ DeepTest.logger.debug { "Deploying #{number_of_agents} #{@agent_class}s" }
20
+ wait_for_connect_threads = []
21
+ each_agent do |agent_num|
22
+ stream_from_child_process, stream_to_parent_process = IO.pipe
23
+ warlock.start "agent #{agent_num}", @agent_class.new(agent_num, @options, @options.new_listener_list),
24
+ stream_from_child_process, stream_to_parent_process
25
+ wait_for_connect_threads << Thread.new do
26
+ stream_to_parent_process.close
27
+ message = stream_from_child_process.read
28
+ stream_from_child_process.close
29
+ raise "Agent was not able to connect: #{message}" unless message == "Connected\n"
30
+ end
31
+ end
32
+
33
+ wait_for_connect_threads.each { |t| t.join }
34
+ end
35
+
36
+ def number_of_agents
37
+ @options.number_of_agents
38
+ end
39
+
40
+ private
41
+
42
+ def each_agent
43
+ number_of_agents.to_i.times { |agent_num| yield agent_num }
44
+ end
45
+ end
46
+ end
@@ -2,16 +2,31 @@ module DeepTest
2
2
  class Logger < ::Logger
3
3
  def initialize(*args)
4
4
  super
5
- self.formatter = proc { |severity, time, progname, msg| "[DeepTest] #{msg}\n" }
5
+ hostname = Socket.gethostname
6
+ self.formatter = proc { |severity, time, progname, msg| "[DeepTest@#{hostname}] #{time.strftime "%F %T"} #{msg}\n" }
6
7
  self.level = configured_log_level
7
8
  end
8
9
 
10
+ def io_stream
11
+ @logdev.dev
12
+ end
13
+
9
14
  def configured_log_level
10
15
  if ENV['DEEP_TEST_LOG_LEVEL']
11
- Logger.const_get(ENV['DEEP_TEST_LOG_LEVEL'])
16
+ Logger.const_get(ENV['DEEP_TEST_LOG_LEVEL'].upcase)
12
17
  else
13
18
  Logger::INFO
14
19
  end
15
20
  end
21
+
22
+ Severity.constants.each do |severity|
23
+ eval <<-end_src
24
+ def #{severity.downcase}
25
+ super
26
+ rescue Exception => e
27
+ super "\#{e.class}: \#{e} occurred logging on \#{caller[0]}", &nil
28
+ end
29
+ end_src
30
+ end
16
31
  end
17
32
  end