jperkins-deep_test 1.2.2
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 +47 -0
- data/README.rdoc +228 -0
- data/Rakefile +247 -0
- data/bin/deep_test +15 -0
- data/lib/deep_test.rb +91 -0
- data/lib/deep_test/database/mysql_setup_listener.rb +112 -0
- data/lib/deep_test/database/postgresql_setup_listener.rb +116 -0
- data/lib/deep_test/database/setup_listener.rb +125 -0
- data/lib/deep_test/deadlock_detector.rb +7 -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 +40 -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 +17 -0
- 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 +62 -0
- data/lib/deep_test/option.rb +60 -0
- data/lib/deep_test/options.rb +110 -0
- data/lib/deep_test/process_orchestrator.rb +49 -0
- data/lib/deep_test/rake_tasks.rb +11 -0
- data/lib/deep_test/result_reader.rb +36 -0
- data/lib/deep_test/rspec_detector.rb +21 -0
- data/lib/deep_test/server.rb +75 -0
- data/lib/deep_test/spec.rb +13 -0
- data/lib/deep_test/spec/extensions/example_group_methods.rb +64 -0
- data/lib/deep_test/spec/extensions/example_methods.rb +46 -0
- data/lib/deep_test/spec/extensions/options.rb +43 -0
- data/lib/deep_test/spec/extensions/reporter.rb +29 -0
- data/lib/deep_test/spec/extensions/spec_task.rb +20 -0
- data/lib/deep_test/spec/runner.rb +57 -0
- data/lib/deep_test/spec/work_result.rb +33 -0
- data/lib/deep_test/spec/work_unit.rb +59 -0
- data/lib/deep_test/test.rb +10 -0
- data/lib/deep_test/test/extensions/error.rb +14 -0
- data/lib/deep_test/test/runner.rb +24 -0
- data/lib/deep_test/test/supervised_test_suite.rb +49 -0
- data/lib/deep_test/test/work_result.rb +34 -0
- data/lib/deep_test/test/work_unit.rb +40 -0
- data/lib/deep_test/test_task.rb +47 -0
- data/lib/deep_test/ui/console.rb +76 -0
- data/lib/deep_test/ui/null.rb +17 -0
- data/lib/deep_test/warlock.rb +134 -0
- data/lib/deep_test/worker.rb +57 -0
- 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/spec/deep_test/option_spec.rb +33 -0
- data/spec/deep_test/options_spec.rb +183 -0
- data/spec/deep_test/spec/extensions/example_group_methods_spec.rb +48 -0
- data/spec/deep_test/spec/extensions/example_methods_spec.rb +61 -0
- data/spec/deep_test/spec/extensions/options_spec.rb +23 -0
- data/spec/deep_test/spec/extensions/reporter_spec.rb +28 -0
- data/spec/deep_test/spec/extensions/spec_task_spec.rb +36 -0
- data/spec/deep_test/spec/runner_spec.rb +106 -0
- data/spec/deep_test/spec/work_result_spec.rb +14 -0
- data/spec/deep_test/spec/work_unit_spec.rb +78 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/thread_worker.rb +25 -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/extensions/object_extension_test.rb +37 -0
- data/test/deep_test/listener_list_test.rb +20 -0
- data/test/deep_test/local_workers_test.rb +22 -0
- data/test/deep_test/logger_test.rb +11 -0
- 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/runner_test.rb +7 -0
- data/test/deep_test/test/supervised_test_suite_test.rb +79 -0
- data/test/deep_test/test/work_result_test.rb +81 -0
- data/test/deep_test/test/work_unit_test.rb +61 -0
- data/test/deep_test/test_task_test.rb +43 -0
- data/test/deep_test/ui/console_test.rb +9 -0
- data/test/deep_test/warlock_test.rb +38 -0
- data/test/deep_test/worker_test.rb +94 -0
- data/test/failing.rake +11 -0
- data/test/failing.rb +7 -0
- data/test/fake_deadlock_error.rb +12 -0
- data/test/simple_test_blackboard.rb +45 -0
- data/test/simple_test_blackboard_test.rb +33 -0
- data/test/test_factory.rb +74 -0
- data/test/test_helper.rb +15 -0
- data/test/test_task_test.rb +72 -0
- metadata +214 -0
data/bin/deep_test
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
script_dir = File.dirname(__FILE__) + '/../script/public'
|
|
4
|
+
script_file = script_dir + "/#{ARGV.shift}.rb"
|
|
5
|
+
|
|
6
|
+
unless File.exist?(script_file)
|
|
7
|
+
puts 'Usage: deep_test <script> [arguments]'
|
|
8
|
+
puts ' Available Scripts: '
|
|
9
|
+
Dir.glob(script_dir + '/*.rb').each do |name|
|
|
10
|
+
puts " #{File.basename(name, '.rb')}"
|
|
11
|
+
end
|
|
12
|
+
exit(1)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
load script_file
|
data/lib/deep_test.rb
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
class << self
|
|
3
|
+
def logger
|
|
4
|
+
@logger ||= DeepTest::Logger.new($stdout)
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Fork in a separate thread. If we fork from a DRb thread
|
|
9
|
+
# (a thread handling a method call invoked over drb),
|
|
10
|
+
# DRb still thinks the current object is the DRb Front Object,
|
|
11
|
+
# and reports its uri as the same as in the parent process, even
|
|
12
|
+
# if you restart DRb service.
|
|
13
|
+
#
|
|
14
|
+
def self.drb_safe_fork(&block)
|
|
15
|
+
Thread.new {Process.fork(&block)}.value
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.init(options)
|
|
19
|
+
return if @initialized
|
|
20
|
+
@initialized = true
|
|
21
|
+
Metrics::Gatherer.setup(options)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class WorkUnitNeverReceivedError < StandardError
|
|
25
|
+
def initialize
|
|
26
|
+
super "DeepTest result never received. Maybe an error was printed above?"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def backtrace
|
|
30
|
+
[]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
require "logger"
|
|
36
|
+
require "drb"
|
|
37
|
+
require "timeout"
|
|
38
|
+
require "thread"
|
|
39
|
+
require "socket"
|
|
40
|
+
require "webrick"
|
|
41
|
+
require "timeout"
|
|
42
|
+
|
|
43
|
+
require File.dirname(__FILE__) + "/deep_test/extensions/object_extension"
|
|
44
|
+
require File.dirname(__FILE__) + "/deep_test/extensions/drb_extension"
|
|
45
|
+
|
|
46
|
+
require File.dirname(__FILE__) + "/deep_test/deadlock_detector"
|
|
47
|
+
require File.dirname(__FILE__) + "/deep_test/local_workers"
|
|
48
|
+
require File.dirname(__FILE__) + "/deep_test/logger"
|
|
49
|
+
|
|
50
|
+
require File.dirname(__FILE__) + "/deep_test/marshallable_exception_wrapper"
|
|
51
|
+
require File.dirname(__FILE__) + "/deep_test/null_worker_listener"
|
|
52
|
+
require File.dirname(__FILE__) + "/deep_test/listener_list"
|
|
53
|
+
require File.dirname(__FILE__) + "/deep_test/option"
|
|
54
|
+
require File.dirname(__FILE__) + "/deep_test/options"
|
|
55
|
+
require File.dirname(__FILE__) + "/deep_test/process_orchestrator"
|
|
56
|
+
require File.dirname(__FILE__) + "/deep_test/result_reader"
|
|
57
|
+
require File.dirname(__FILE__) + "/deep_test/rspec_detector"
|
|
58
|
+
require File.dirname(__FILE__) + "/deep_test/server"
|
|
59
|
+
require File.dirname(__FILE__) + "/deep_test/test_task"
|
|
60
|
+
require File.dirname(__FILE__) + "/deep_test/worker"
|
|
61
|
+
require File.dirname(__FILE__) + "/deep_test/warlock"
|
|
62
|
+
|
|
63
|
+
require File.dirname(__FILE__) + "/deep_test/database/setup_listener"
|
|
64
|
+
require File.dirname(__FILE__) + "/deep_test/database/mysql_setup_listener"
|
|
65
|
+
require File.dirname(__FILE__) + "/deep_test/database/postgresql_setup_listener"
|
|
66
|
+
|
|
67
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/dispatch_controller"
|
|
68
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/drb_client_connection_info"
|
|
69
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/filename_resolver"
|
|
70
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/master_test_server"
|
|
71
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/test_server"
|
|
72
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/test_server_status"
|
|
73
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/test_server_workers"
|
|
74
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/multi_test_server_proxy"
|
|
75
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/null_work_unit"
|
|
76
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/remote_worker_client"
|
|
77
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/remote_worker_server"
|
|
78
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/rsync"
|
|
79
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/throughput_runner"
|
|
80
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/throughput_statistics"
|
|
81
|
+
require File.dirname(__FILE__) + "/deep_test/distributed/throughput_worker_client"
|
|
82
|
+
|
|
83
|
+
require File.dirname(__FILE__) + "/deep_test/metrics/gatherer"
|
|
84
|
+
|
|
85
|
+
DeepTest::RSpecDetector.if_rspec_available do
|
|
86
|
+
require File.dirname(__FILE__) + "/deep_test/spec"
|
|
87
|
+
end
|
|
88
|
+
require File.dirname(__FILE__) + "/deep_test/test"
|
|
89
|
+
|
|
90
|
+
require File.dirname(__FILE__) + "/deep_test/ui/console"
|
|
91
|
+
require File.dirname(__FILE__) + "/deep_test/ui/null"
|
|
@@ -0,0 +1,112 @@
|
|
|
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
|
+
identified_by = if worker_database_config[:password]
|
|
42
|
+
%{identified by %s} % connection.quote(worker_database_config[:password])
|
|
43
|
+
else
|
|
44
|
+
""
|
|
45
|
+
end
|
|
46
|
+
sql = %{grant all on #{worker_database}.* to %s@'localhost' #{identified_by} ; } %
|
|
47
|
+
connection.quote(worker_database_config[:username])
|
|
48
|
+
|
|
49
|
+
connection.execute sql
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# Drops database via ActiveRecord connection based on admin_configuration
|
|
54
|
+
#
|
|
55
|
+
def drop_database
|
|
56
|
+
admin_connection do |connection|
|
|
57
|
+
connection.drop_database worker_database
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Dumps schema from master database using mysqldump command
|
|
63
|
+
#
|
|
64
|
+
def dump_schema
|
|
65
|
+
config = command_line_config(master_database_config)
|
|
66
|
+
system "mysqldump -R #{config} > #{dump_file_name}"
|
|
67
|
+
raise "Error Dumping schema" unless $?.success?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Loads dumpfile into worker database using mysql command
|
|
72
|
+
#
|
|
73
|
+
def load_schema
|
|
74
|
+
config = command_line_config(worker_database_config)
|
|
75
|
+
system "mysql #{config} < #{dump_file_name}"
|
|
76
|
+
raise "Error Loading schema" unless $?.success?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
#
|
|
80
|
+
# Location to store dumpfile. The default assumes you are testing
|
|
81
|
+
# a Rails project. You should override this if you are not using Rails
|
|
82
|
+
# or would like the dump file to be something other than the default
|
|
83
|
+
#
|
|
84
|
+
def dump_file_name
|
|
85
|
+
"#{RAILS_ROOT}/db/deep_test_schema.sql"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def system(command) # :nodoc:
|
|
89
|
+
DeepTest.logger.info command
|
|
90
|
+
super command
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def command_line_config(config) # :nodoc:
|
|
94
|
+
command = ['-u', config[:username]]
|
|
95
|
+
command += ["-p#{config[:password]}"] if config[:password]
|
|
96
|
+
command += ['-h', config[:host]] if config[:host]
|
|
97
|
+
command += ['-P', config[:port]] if config[:port]
|
|
98
|
+
command += ['-S', config[:socket]] if config[:socket]
|
|
99
|
+
command += [config[:database]]
|
|
100
|
+
command.join(' ')
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def admin_connection # :nodoc:
|
|
104
|
+
conn = ActiveRecord::Base.mysql_connection(self.class.admin_configuration)
|
|
105
|
+
yield conn
|
|
106
|
+
ensure
|
|
107
|
+
conn.disconnect! if conn
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
module DeepTest
|
|
2
|
+
module Database
|
|
3
|
+
#
|
|
4
|
+
# SetupListener implementation for PostgreSQL.
|
|
5
|
+
#
|
|
6
|
+
class PostgresqlSetupListener < 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
|
+
|
|
17
|
+
self.admin_configuration = {
|
|
18
|
+
:adapter => "postgresql",
|
|
19
|
+
:host => "localhost",
|
|
20
|
+
:username => "postgres",
|
|
21
|
+
:database => "postgres"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Creates database and grants privileges (via +grant_privileges+)
|
|
26
|
+
# on it via ActiveRecord connection based on admin_configuration.
|
|
27
|
+
#
|
|
28
|
+
def create_database
|
|
29
|
+
admin_connection do |connection|
|
|
30
|
+
connection.create_database worker_database
|
|
31
|
+
grant_privileges connection
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Grants 'all' privilege on worker database to username and password
|
|
37
|
+
# specified by worker database config. If your application has
|
|
38
|
+
# special database privilege needs beyond 'all', you should override
|
|
39
|
+
# this method and grant them.
|
|
40
|
+
#
|
|
41
|
+
def grant_privileges(connection)
|
|
42
|
+
sql = "GRANT ALL PRIVILEGES ON DATABASE #{worker_database} TO #{worker_database_config[:username]};" # % [
|
|
43
|
+
# connection.quote(worker_database_config[:username])
|
|
44
|
+
# ]
|
|
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
|
+
|
|
64
|
+
# TODO: the -R switch on the mysql version of this will dump stored procs, etc. we'll
|
|
65
|
+
# need to do the same with pg before we push our mods back
|
|
66
|
+
# system "mysqldump -R #{config} > #{dump_file_name}"
|
|
67
|
+
system "pg_dump #{config} > #{dump_file_name}"
|
|
68
|
+
raise "Error Dumping schema" unless $?.success?
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
#
|
|
72
|
+
# Loads dumpfile into worker database using mysql command
|
|
73
|
+
#
|
|
74
|
+
def load_schema
|
|
75
|
+
config = command_line_config(worker_database_config)
|
|
76
|
+
system "psql -q #{config} < #{dump_file_name}"
|
|
77
|
+
raise "Error Loading schema" unless $?.success?
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
# Location to store dumpfile. The default assumes you are testing
|
|
82
|
+
# a Rails project. You should override this if you are not using Rails
|
|
83
|
+
# or would like the dump file to be something other than the default
|
|
84
|
+
#
|
|
85
|
+
def dump_file_name
|
|
86
|
+
"#{RAILS_ROOT}/db/deep_test_schema.sql"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def system(command) # :nodoc:
|
|
90
|
+
DeepTest.logger.info { command }
|
|
91
|
+
super command
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def command_line_config(config) # :nodoc:
|
|
95
|
+
command = ['-U', config[:username]]
|
|
96
|
+
command += ["-W#{config[:password]}"] if config[:password]
|
|
97
|
+
command += ['-h', config[:host]] if config[:host]
|
|
98
|
+
command += ['-p', config[:port]] if config[:port]
|
|
99
|
+
# TODO: socket issue with psql from the command line - it is passed to host switch,
|
|
100
|
+
# not a separate switch like mysql
|
|
101
|
+
# command += ['-S', config[:socket]] if config[:socket]
|
|
102
|
+
command += [config[:database]]
|
|
103
|
+
command += [config[:schema]]
|
|
104
|
+
command.join(' ')
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def admin_connection # :nodoc:
|
|
108
|
+
conn = ActiveRecord::Base.postgresql_connection(self.class.admin_configuration)
|
|
109
|
+
yield conn
|
|
110
|
+
ensure
|
|
111
|
+
conn.disconnect! if conn
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
@@ -0,0 +1,125 @@
|
|
|
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
|
+
disconnect_from_database
|
|
32
|
+
drop_database
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
drop_database
|
|
36
|
+
create_database
|
|
37
|
+
connect_to_database
|
|
38
|
+
load_schema
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#
|
|
42
|
+
# Called on each worker after creating database and before loading
|
|
43
|
+
# schema to initialize connections
|
|
44
|
+
#
|
|
45
|
+
def connect_to_database
|
|
46
|
+
ActiveRecord::Base.establish_connection(worker_database_config)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# Called in each worker to create the database named by
|
|
51
|
+
# +worker_database+.
|
|
52
|
+
#
|
|
53
|
+
def create_database
|
|
54
|
+
raise "Subclass must implement"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Called in each worker before the drop_database call as PostgreSQL
|
|
59
|
+
# will not allow a database with connections ot be dropped
|
|
60
|
+
#
|
|
61
|
+
def disconnect_from_database
|
|
62
|
+
ActiveRecord::Base.connection.disconnect!
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
#
|
|
66
|
+
# Called in each worker to drop the database created by
|
|
67
|
+
# +create_database+. This method is called twice, once before
|
|
68
|
+
# +create_database+ to ensure that no database exists and once
|
|
69
|
+
# at exit to clean as the worker process exits. This method
|
|
70
|
+
# must not fail if the database does not exist when it is called.
|
|
71
|
+
#
|
|
72
|
+
def drop_database
|
|
73
|
+
raise "Subclass must implement"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#
|
|
77
|
+
# Called before any workers are spawned to dump the schema that
|
|
78
|
+
# will be used for testing. When running distributed, this method
|
|
79
|
+
# is called on the local machine providing the tests to run.
|
|
80
|
+
#
|
|
81
|
+
# For distributed testing to work, the schema must be dumped in
|
|
82
|
+
# location accessible by all worker machines. The easiest way to
|
|
83
|
+
# accomplish this is to dump it to a location within the working copy.
|
|
84
|
+
#
|
|
85
|
+
def dump_schema
|
|
86
|
+
raise "Subclass must implement"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
#
|
|
91
|
+
# Called once in each worker as it is starting to load the schema
|
|
92
|
+
# dumped from dump_schema. Subclasses should load the schema definition
|
|
93
|
+
# into the +worker_database+
|
|
94
|
+
#
|
|
95
|
+
def load_schema
|
|
96
|
+
raise "Subclass must implement"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# ActiveRecord configuration for the worker database. By default,
|
|
101
|
+
# the same as +master_database_config+, except that points to
|
|
102
|
+
# +worker_database+ instead of the database named in the master config.
|
|
103
|
+
#
|
|
104
|
+
def worker_database_config
|
|
105
|
+
master_database_config.merge(:database => worker_database)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
#
|
|
109
|
+
# ActiveRecord configuration for the master database, based on
|
|
110
|
+
# RAILS_ENV. If not running Rails, you'll need to override this
|
|
111
|
+
# to provide the correct configuration.
|
|
112
|
+
#
|
|
113
|
+
def master_database_config
|
|
114
|
+
ActiveRecord::Base.configurations[RAILS_ENV].with_indifferent_access
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
#
|
|
118
|
+
# Unique name for database on machine that worker is running on.
|
|
119
|
+
#
|
|
120
|
+
def worker_database
|
|
121
|
+
"deep_test_worker_#{@worker.number}_pid_#{Process.pid}"
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|