deep_test 1.1.4 → 1.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.
- data/CHANGELOG +15 -5
- data/README +149 -5
- data/Rakefile +131 -11
- data/bin/deep_test +15 -0
- data/lib/deep_test.rb +62 -4
- data/lib/deep_test/database/mysql_setup_listener.rb +109 -0
- data/lib/deep_test/database/setup_listener.rb +116 -0
- data/lib/deep_test/distributed/dispatch_controller.rb +53 -0
- data/lib/deep_test/distributed/drb_client_connection_info.rb +15 -0
- data/lib/deep_test/distributed/filename_resolver.rb +40 -0
- data/lib/deep_test/distributed/master_test_server.rb +52 -0
- data/lib/deep_test/distributed/multi_test_server_proxy.rb +44 -0
- data/lib/deep_test/distributed/null_work_unit.rb +12 -0
- data/lib/deep_test/distributed/remote_worker_client.rb +54 -0
- data/lib/deep_test/distributed/remote_worker_server.rb +82 -0
- data/lib/deep_test/distributed/rsync.rb +37 -0
- data/lib/deep_test/distributed/show_status.rhtml +41 -0
- data/lib/deep_test/distributed/test_server.rb +78 -0
- data/lib/deep_test/distributed/test_server_status.rb +9 -0
- data/lib/deep_test/distributed/test_server_workers.rb +24 -0
- data/lib/deep_test/distributed/throughput_runner.rb +42 -0
- data/lib/deep_test/distributed/throughput_statistics.rb +26 -0
- data/lib/deep_test/distributed/throughput_worker_client.rb +19 -0
- data/lib/deep_test/extensions/drb_extension.rb +34 -0
- data/lib/deep_test/extensions/object_extension.rb +8 -0
- data/lib/deep_test/listener_list.rb +17 -0
- data/lib/deep_test/local_workers.rb +55 -0
- data/lib/deep_test/logger.rb +10 -2
- data/lib/deep_test/marshallable_exception_wrapper.rb +44 -0
- data/lib/deep_test/metrics/gatherer.rb +67 -0
- data/lib/deep_test/metrics/queue_lock_wait_time_measurement.rb +133 -0
- data/lib/deep_test/null_worker_listener.rb +50 -0
- data/lib/deep_test/option.rb +60 -0
- data/lib/deep_test/options.rb +61 -24
- data/lib/deep_test/process_orchestrator.rb +31 -78
- data/lib/deep_test/rake_tasks.rb +3 -0
- data/lib/deep_test/result_reader.rb +36 -0
- data/lib/deep_test/rspec_detector.rb +15 -8
- data/lib/deep_test/server.rb +68 -4
- data/lib/deep_test/spec.rb +1 -0
- data/lib/deep_test/spec/extensions/example_group_methods.rb +37 -11
- data/lib/deep_test/spec/extensions/example_methods.rb +46 -0
- data/lib/deep_test/spec/extensions/options.rb +35 -3
- data/lib/deep_test/spec/runner.rb +19 -10
- data/lib/deep_test/spec/work_result.rb +12 -9
- data/lib/deep_test/spec/work_unit.rb +12 -7
- data/lib/deep_test/test.rb +1 -1
- data/lib/deep_test/test/extensions/error.rb +7 -7
- data/lib/deep_test/test/runner.rb +1 -6
- data/lib/deep_test/test/supervised_test_suite.rb +19 -16
- data/lib/deep_test/test/work_result.rb +34 -0
- data/lib/deep_test/test/work_unit.rb +6 -2
- data/lib/deep_test/test_task.rb +15 -35
- data/lib/deep_test/ui/console.rb +76 -0
- data/lib/deep_test/ui/null.rb +17 -0
- data/lib/deep_test/warlock.rb +92 -17
- data/lib/deep_test/worker.rb +38 -2
- data/script/internal/run_test_suite.rb +7 -0
- data/script/public/master_test_server.rb +24 -0
- data/script/public/test_server.rb +18 -0
- data/script/public/test_throughput.rb +29 -0
- data/test/deep_test/database/mysql_setup_listener_test.rb +14 -0
- data/test/deep_test/distributed/dispatch_controller_test.rb +209 -0
- data/test/deep_test/distributed/drb_client_connection_info_test.rb +42 -0
- data/test/deep_test/distributed/filename_resolver_test.rb +52 -0
- data/test/deep_test/distributed/master_test_server_test.rb +32 -0
- data/test/deep_test/distributed/multi_test_server_proxy_test.rb +96 -0
- data/test/deep_test/distributed/remote_worker_client_test.rb +180 -0
- data/test/deep_test/distributed/remote_worker_server_test.rb +99 -0
- data/test/deep_test/distributed/rsync_test.rb +67 -0
- data/test/deep_test/distributed/test_server_test.rb +94 -0
- data/test/deep_test/distributed/test_server_workers_test.rb +26 -0
- data/test/deep_test/distributed/throughput_runner_test.rb +68 -0
- data/test/deep_test/distributed/throughput_worker_client_test.rb +28 -0
- data/test/deep_test/listener_list_test.rb +20 -0
- data/test/deep_test/local_workers_test.rb +22 -0
- data/test/{logger_test.rb → deep_test/logger_test.rb} +2 -2
- data/test/deep_test/marshallable_exception_wrapper_test.rb +44 -0
- data/test/deep_test/metrics/gatherer_test.rb +66 -0
- data/test/deep_test/process_orchestrator_test.rb +11 -0
- data/test/deep_test/result_reader_test.rb +128 -0
- data/test/deep_test/server_test.rb +58 -0
- data/test/deep_test/test/extensions/error_test.rb +40 -0
- data/test/deep_test/test/supervised_test_suite_test.rb +19 -29
- data/test/deep_test/test/work_result_test.rb +81 -0
- data/test/deep_test/test/work_unit_test.rb +15 -4
- data/test/deep_test/test_task_test.rb +10 -0
- data/test/deep_test/ui/console_test.rb +9 -0
- data/test/deep_test/warlock_test.rb +17 -0
- data/test/deep_test/worker_test.rb +32 -0
- data/test/simple_test_blackboard.rb +2 -1
- data/test/test_helper.rb +1 -0
- metadata +117 -59
- data/lib/deep_test/rinda_blackboard.rb +0 -26
- data/lib/deep_test/test/extensions/test_result.rb +0 -17
- data/lib/deep_test/tuple_space_factory.rb +0 -12
- data/script/run_test_suite.rb +0 -5
- data/test/deep_test/rinda_blackboard_test.rb +0 -15
- data/test/deep_test/test/extensions/test_result_test.rb +0 -71
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
module Database
|
|
3
|
+
#
|
|
4
|
+
# SetupListener implementation for MySQL.
|
|
5
|
+
#
|
|
6
|
+
class MysqlSetupListener < SetupListener
|
|
7
|
+
class <<self
|
|
8
|
+
#
|
|
9
|
+
# ActiveRecord configuration to use when connecting to
|
|
10
|
+
# MySQL to create databases, drop database, and grant
|
|
11
|
+
# privileges. By default, connects to information_schema
|
|
12
|
+
# on localhost as root with no password.
|
|
13
|
+
#
|
|
14
|
+
attr_accessor :admin_configuration
|
|
15
|
+
end
|
|
16
|
+
self.admin_configuration = {
|
|
17
|
+
:adapter => "mysql",
|
|
18
|
+
:host => "localhost",
|
|
19
|
+
:username => "root",
|
|
20
|
+
:database => "information_schema"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Creates database and grants privileges (via +grant_privileges+)
|
|
25
|
+
# on it via ActiveRecord connection based on admin_configuration.
|
|
26
|
+
#
|
|
27
|
+
def create_database
|
|
28
|
+
admin_connection do |connection|
|
|
29
|
+
connection.create_database worker_database
|
|
30
|
+
grant_privileges connection
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# Grants 'all' privilege on worker database to username and password
|
|
36
|
+
# specified by worker database config. If your application has
|
|
37
|
+
# special database privilege needs beyond 'all', you should override
|
|
38
|
+
# this method and grant them.
|
|
39
|
+
#
|
|
40
|
+
def grant_privileges(connection)
|
|
41
|
+
sql = %{grant all on #{worker_database}.*
|
|
42
|
+
to %s@'localhost' identified by %s;} % [
|
|
43
|
+
connection.quote(worker_database_config[:username]),
|
|
44
|
+
connection.quote(worker_database_config[:password])
|
|
45
|
+
]
|
|
46
|
+
connection.execute sql
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# Drops database via ActiveRecord connection based on admin_configuration
|
|
51
|
+
#
|
|
52
|
+
def drop_database
|
|
53
|
+
admin_connection do |connection|
|
|
54
|
+
connection.drop_database worker_database
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
#
|
|
59
|
+
# Dumps schema from master database using mysqldump command
|
|
60
|
+
#
|
|
61
|
+
def dump_schema
|
|
62
|
+
config = command_line_config(master_database_config)
|
|
63
|
+
system "mysqldump -R #{config} > #{dump_file_name}"
|
|
64
|
+
raise "Error Dumping schema" unless $?.success?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# Loads dumpfile into worker database using mysql command
|
|
69
|
+
#
|
|
70
|
+
def load_schema
|
|
71
|
+
config = command_line_config(worker_database_config)
|
|
72
|
+
system "mysql #{config} < #{dump_file_name}"
|
|
73
|
+
raise "Error Loading schema" unless $?.success?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#
|
|
77
|
+
# Location to store dumpfile. The default assumes you are testing
|
|
78
|
+
# a Rails project. You should override this if you are not using Rails
|
|
79
|
+
# or would like the dump file to be something other than the default
|
|
80
|
+
#
|
|
81
|
+
def dump_file_name
|
|
82
|
+
"#{RAILS_ROOT}/db/deep_test_schema.sql"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def system(command) # :nodoc:
|
|
86
|
+
DeepTest.logger.info command
|
|
87
|
+
super command
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def command_line_config(config) # :nodoc:
|
|
91
|
+
command = ['-u', config[:username]]
|
|
92
|
+
command += ["-p#{config[:password]}"] if config[:password]
|
|
93
|
+
command += ['-h', config[:host]] if config[:host]
|
|
94
|
+
command += ['-P', config[:port]] if config[:port]
|
|
95
|
+
command += ['-S', config[:socket]] if config[:socket]
|
|
96
|
+
command += [config[:database]]
|
|
97
|
+
command.join(' ')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def admin_connection # :nodoc:
|
|
101
|
+
conn = ActiveRecord::Base.mysql_connection(self.class.admin_configuration)
|
|
102
|
+
yield conn
|
|
103
|
+
ensure
|
|
104
|
+
conn.disconnect! if conn
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
module Database
|
|
3
|
+
#
|
|
4
|
+
# Skeleton Listener to help with setting up a separate database
|
|
5
|
+
# for each worker. Calls +dump_schema+, +load_schema+, +create_database+,
|
|
6
|
+
# and +drop_database+ hooks provided by subclasses that implement database
|
|
7
|
+
# setup strategies for particular database flavors.
|
|
8
|
+
#
|
|
9
|
+
class SetupListener < NullWorkerListener
|
|
10
|
+
DUMPED_SCHEMAS = [] unless defined?(DUMPED_SCHEMAS)
|
|
11
|
+
|
|
12
|
+
def before_sync # :nodoc:
|
|
13
|
+
dump_schema_once
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def before_starting_workers # :nodoc:
|
|
17
|
+
dump_schema_once
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def dump_schema_once # :nodoc:
|
|
21
|
+
schema_name = master_database_config[:database]
|
|
22
|
+
dump_schema unless DUMPED_SCHEMAS.include?(schema_name)
|
|
23
|
+
DUMPED_SCHEMAS << schema_name
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def starting(worker) # :nodoc:
|
|
27
|
+
@worker = worker
|
|
28
|
+
|
|
29
|
+
at_exit do
|
|
30
|
+
DeepTest.logger.debug("dropping database #{worker_database}")
|
|
31
|
+
drop_database
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
drop_database
|
|
35
|
+
create_database
|
|
36
|
+
connect_to_database
|
|
37
|
+
load_schema
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#
|
|
41
|
+
# Called on each worker after creating database and before loading
|
|
42
|
+
# schema to initialize connections
|
|
43
|
+
#
|
|
44
|
+
def connect_to_database
|
|
45
|
+
ActiveRecord::Base.establish_connection(worker_database_config)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#
|
|
49
|
+
# Called in each worker to create the database named by
|
|
50
|
+
# +worker_database+.
|
|
51
|
+
#
|
|
52
|
+
def create_database
|
|
53
|
+
raise "Subclass must implement"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#
|
|
57
|
+
# Called in each worker to drop the database created by
|
|
58
|
+
# +create_database+. This method is called twice, once before
|
|
59
|
+
# +create_database+ to ensure that no database exists and once
|
|
60
|
+
# at exit to clean as the worker process exits. This method
|
|
61
|
+
# must not fail if the database does not exist when it is called.
|
|
62
|
+
#
|
|
63
|
+
def drop_database
|
|
64
|
+
raise "Subclass must implement"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# Called before any workers are spawned to dump the schema that
|
|
69
|
+
# will be used for testing. When running distributed, this method
|
|
70
|
+
# is called on the local machine providing the tests to run.
|
|
71
|
+
#
|
|
72
|
+
# For distributed testing to work, the schema must be dumped in
|
|
73
|
+
# location accessible by all worker machines. The easiest way to
|
|
74
|
+
# accomplish this is to dump it to a location within the working copy.
|
|
75
|
+
#
|
|
76
|
+
def dump_schema
|
|
77
|
+
raise "Subclass must implement"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# Called once in each worker as it is starting to load the schema
|
|
83
|
+
# dumped from dump_schema. Subclasses should load the schema definition
|
|
84
|
+
# into the +worker_database+
|
|
85
|
+
#
|
|
86
|
+
def load_schema
|
|
87
|
+
raise "Subclass must implement"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
#
|
|
91
|
+
# ActiveRecord configuration for the worker database. By default,
|
|
92
|
+
# the same as +master_database_config+, except that points to
|
|
93
|
+
# +worker_database+ instead of the database named in the master config.
|
|
94
|
+
#
|
|
95
|
+
def worker_database_config
|
|
96
|
+
master_database_config.merge(:database => worker_database)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# ActiveRecord configuration for the master database, based on
|
|
101
|
+
# RAILS_ENV. If not running Rails, you'll need to override this
|
|
102
|
+
# to provide the correct configuration.
|
|
103
|
+
#
|
|
104
|
+
def master_database_config
|
|
105
|
+
ActiveRecord::Base.configurations[RAILS_ENV].with_indifferent_access
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
#
|
|
109
|
+
# Unique name for database on machine that worker is running on.
|
|
110
|
+
#
|
|
111
|
+
def worker_database
|
|
112
|
+
"deep_test_worker_#{@worker.number}_pid_#{Process.pid}"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
module Distributed
|
|
3
|
+
class DispatchController
|
|
4
|
+
def initialize(options, receivers)
|
|
5
|
+
@options = options
|
|
6
|
+
@receivers = receivers
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def dispatch(method_name, *args)
|
|
10
|
+
dispatch_with_options(method_name, {}, *args)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def dispatch_with_options(method_name, options, *args)
|
|
14
|
+
raise NoDispatchReceiversError if @receivers.empty?
|
|
15
|
+
|
|
16
|
+
@options.ui_instance.dispatch_starting(method_name)
|
|
17
|
+
|
|
18
|
+
threads = @receivers.map do |r|
|
|
19
|
+
Thread.new do
|
|
20
|
+
Thread.current[:receiver] = r
|
|
21
|
+
Timeout.timeout(@options.timeout_in_seconds) do
|
|
22
|
+
r.send method_name, *args
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
results = []
|
|
28
|
+
threads.each do |t|
|
|
29
|
+
begin
|
|
30
|
+
results << t.value
|
|
31
|
+
rescue Timeout::Error
|
|
32
|
+
@receivers.delete t[:receiver]
|
|
33
|
+
DeepTest.logger.error "Timeout dispatching #{method_name} to #{t[:receiver].__drburi}"
|
|
34
|
+
rescue DRb::DRbConnError
|
|
35
|
+
@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}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
results
|
|
46
|
+
ensure
|
|
47
|
+
@options.ui_instance.dispatch_finished(method_name)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class NoDispatchReceiversError < StandardError; end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
module Distributed
|
|
3
|
+
class DRbClientConnectionInfo
|
|
4
|
+
attr_reader :address
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
info = Thread.current['DRb']
|
|
8
|
+
raise "No DRb client found" unless info && info['client']
|
|
9
|
+
peeraddr = info['client'].peeraddr
|
|
10
|
+
DeepTest.logger.debug("DRbClientConnection info: #{peeraddr.inspect}")
|
|
11
|
+
@address = peeraddr[3]
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
module Distributed
|
|
3
|
+
class FilenameResolver
|
|
4
|
+
def initialize(base_path)
|
|
5
|
+
@base_path = base_path
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def resolve(filename)
|
|
9
|
+
return resolve("/" + filename) unless filename[0] == ?/
|
|
10
|
+
|
|
11
|
+
return filename.sub(@cached_replaced_path, @base_path) if @cached_replaced_path
|
|
12
|
+
|
|
13
|
+
each_potential_filename(filename) do |potential_filename|
|
|
14
|
+
if File.exist?(potential_filename)
|
|
15
|
+
cache_resolution(filename, potential_filename)
|
|
16
|
+
return potential_filename
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
raise "Filename resolution failed. Cannot resolve #{filename} within #{@base_path}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def cache_resolution(original_filename, resolved_filename)
|
|
24
|
+
@cached_replaced_path = original_filename.sub(
|
|
25
|
+
resolved_filename.sub(@base_path, ""), ""
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def each_potential_filename(filename)
|
|
30
|
+
basename = File.basename(filename)
|
|
31
|
+
dirs = File.dirname(filename).split('/')
|
|
32
|
+
|
|
33
|
+
begin
|
|
34
|
+
dirs.shift
|
|
35
|
+
yield [@base_path, dirs, basename].flatten.join('/')
|
|
36
|
+
end until dirs.empty?
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
module Distributed
|
|
3
|
+
class MasterTestServer
|
|
4
|
+
include ERB::Util
|
|
5
|
+
|
|
6
|
+
STATUS_PORT = 4020 unless defined?(STATUS_PORT)
|
|
7
|
+
|
|
8
|
+
attr_reader :servers
|
|
9
|
+
|
|
10
|
+
def initialize(servers)
|
|
11
|
+
@servers = servers
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def show_status(req, res)
|
|
15
|
+
template = File.read(File.dirname(__FILE__) + "/show_status.rhtml")
|
|
16
|
+
res.body = ERB.new(template).result(binding)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_server_statuses
|
|
20
|
+
@servers.map do |s|
|
|
21
|
+
status = begin
|
|
22
|
+
s.status
|
|
23
|
+
rescue Exception => e
|
|
24
|
+
e
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
[s.__drburi, status]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.start(uri, server_uris)
|
|
32
|
+
master = start_drb(uri, server_uris)
|
|
33
|
+
start_http(master)
|
|
34
|
+
DeepTest.logger.info "MasterTestServer listening at #{DRb.uri}"
|
|
35
|
+
DRb.thread.join
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.start_drb(uri, server_uris)
|
|
39
|
+
servers = server_uris.map {|server_uri| DRbObject.new_with_uri server_uri}
|
|
40
|
+
master = DeepTest::Distributed::MasterTestServer.new(servers)
|
|
41
|
+
DRb.start_service(uri, master)
|
|
42
|
+
master
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.start_http(master)
|
|
46
|
+
s = WEBrick::HTTPServer.new :Port => STATUS_PORT
|
|
47
|
+
s.mount_proc("/", &master.method(:show_status))
|
|
48
|
+
Thread.new {s.start}
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
module Distributed
|
|
3
|
+
class MultiTestServerProxy
|
|
4
|
+
def initialize(options, slaves)
|
|
5
|
+
DeepTest.logger.debug "MultiTestServerProxy#initialize #{slaves.length} slaves"
|
|
6
|
+
@slave_controller = DispatchController.new(options, slaves)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def spawn_worker_server(options)
|
|
10
|
+
DeepTest.logger.debug "dispatch spawn_worker_server for #{options.origin_hostname}"
|
|
11
|
+
WorkerServerProxy.new options,
|
|
12
|
+
@slave_controller.dispatch(:spawn_worker_server,
|
|
13
|
+
options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def sync(options)
|
|
17
|
+
DeepTest.logger.debug "dispatch sync for #{options.origin_hostname}"
|
|
18
|
+
@slave_controller.dispatch(:sync, options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class WorkerServerProxy
|
|
22
|
+
def initialize(options, slaves)
|
|
23
|
+
DeepTest.logger.debug "WorkerServerProxy#initialize #{slaves.inspect}"
|
|
24
|
+
@slave_controller = DispatchController.new(options, slaves)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def load_files(files)
|
|
28
|
+
DeepTest.logger.debug "dispatch load_files"
|
|
29
|
+
@slave_controller.dispatch(:load_files, files)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def start_all
|
|
33
|
+
DeepTest.logger.debug "dispatch start_all"
|
|
34
|
+
@slave_controller.dispatch(:start_all)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def stop_all
|
|
38
|
+
DeepTest.logger.debug "dispatch stop_all"
|
|
39
|
+
@slave_controller.dispatch_with_options(:stop_all, :ignore_connection_error => true)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|