xli-dtr 0.0.5 → 1.0.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/CHANGES +7 -0
- data/README.rdoc +208 -0
- data/Rakefile +54 -63
- data/TODO +7 -16
- data/bin/dtr +26 -20
- data/dtr.gemspec +7 -10
- data/lib/dtr/agent/brain.rb +13 -22
- data/lib/dtr/agent/herald.rb +24 -14
- data/lib/dtr/agent/runner.rb +22 -35
- data/lib/dtr/agent/sync_codebase.rb +1 -1
- data/lib/dtr/agent/sync_logger.rb +38 -8
- data/lib/dtr/agent/test_case.rb +53 -0
- data/lib/dtr/agent/test_unit.rb +3 -5
- data/lib/dtr/agent/worker.rb +29 -32
- data/lib/dtr/agent/working_env_ext.rb +4 -2
- data/lib/dtr/agent.rb +2 -1
- data/lib/dtr/facade.rb +65 -0
- data/lib/dtr/master.rb +3 -3
- data/lib/dtr/monitor.rb +69 -11
- data/lib/dtr/raketasks.rb +91 -19
- data/lib/dtr/shared/adapter.rb +29 -26
- data/lib/dtr/shared/configuration.rb +39 -11
- data/lib/dtr/shared/message_decorator.rb +1 -1
- data/lib/dtr/shared/ruby_ext.rb +1 -25
- data/lib/dtr/shared/service/agent.rb +5 -1
- data/lib/dtr/shared/service/file.rb +1 -1
- data/lib/dtr/shared/service/rinda.rb +11 -3
- data/lib/dtr/shared/service/runner.rb +6 -5
- data/lib/dtr/shared/service/working_env.rb +1 -1
- data/lib/dtr/shared/service.rb +1 -1
- data/lib/dtr/shared/sync_codebase/{codebase.rb → copiable_package.rb} +13 -5
- data/lib/dtr/shared/sync_codebase/master_ext.rb +6 -18
- data/lib/dtr/shared/sync_codebase/package.rb +16 -2
- data/lib/dtr/shared/sync_codebase/sync_service.rb +7 -12
- data/lib/dtr/shared/sync_codebase.rb +2 -2
- data/lib/dtr/shared/sync_logger.rb +6 -14
- data/lib/dtr/shared/utils/cmd.rb +5 -5
- data/lib/dtr/shared/utils/env_store.rb +1 -1
- data/lib/dtr/shared/utils/logger.rb +33 -17
- data/lib/dtr/shared/utils.rb +1 -1
- data/lib/dtr/shared/working_env.rb +2 -2
- data/lib/dtr/shared.rb +1 -1
- data/lib/dtr/test_unit/drb_test_runner.rb +5 -14
- data/lib/dtr/test_unit/injection.rb +1 -2
- data/lib/dtr/test_unit/test_case_injection.rb +13 -13
- data/lib/dtr/test_unit/test_suite_injection.rb +24 -0
- data/lib/dtr/test_unit/testrunnermediator_injection.rb +11 -11
- data/lib/dtr/test_unit/thread_safe_test_result.rb +1 -3
- data/lib/dtr/test_unit/worker_club.rb +7 -7
- data/lib/dtr/test_unit.rb +2 -1
- data/lib/dtr/test_unit_injection.rb +1 -1
- data/lib/dtr.rb +5 -36
- data/test/acceptance/agent_working_env_test.rb +28 -34
- data/test/acceptance/dtr_package_task_test.rb +13 -3
- data/test/acceptance/general_test.rb +139 -83
- data/test/acceptance/raketasks_test.rb +23 -0
- data/test/acceptance/sync_codebase_test.rb +12 -13
- data/test/acceptance/sync_logger_test.rb +12 -21
- data/test/agent_helper.rb +8 -10
- data/test/logger_stub.rb +4 -0
- data/test/test_helper.rb +33 -5
- data/test/unit/adapter_test.rb +58 -16
- data/test/unit/configuration_test.rb +44 -0
- data/test/unit/facade_test.rb +41 -0
- data/test/unit/logger_test.rb +72 -0
- data/test/unit/test_unit_test.rb +0 -21
- data/testdata/Rakefile +1 -5
- data/testdata/hacked_run_method_test_case.rb +15 -0
- data/testdata/raketasks/Rakefile +7 -0
- data/testdata/raketasks/success_test_case.rb +6 -0
- data/testdata/sleep_3_secs_test_case.rb +9 -0
- data/testdata/{should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process → verify_dir_pwd}/verify_dir_pwd_test_case.rb +1 -1
- metadata +33 -13
- data/README +0 -182
- data/install.rb +0 -88
- /data/testdata/{should_not_sync_codebase_and_setup_working_dir_when_agent_is_in_same_dir_with_master_process → verify_dir_pwd}/Rakefile +0 -0
data/lib/dtr/agent/herald.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -16,6 +16,9 @@ module DTR
|
|
16
16
|
|
17
17
|
module Agent
|
18
18
|
class Herald
|
19
|
+
class WorkingEnvError < StandardError
|
20
|
+
end
|
21
|
+
|
19
22
|
include Service::WorkingEnv
|
20
23
|
include Service::Agent
|
21
24
|
|
@@ -24,26 +27,33 @@ module DTR
|
|
24
27
|
@agent_env_setup_cmd = agent_env_setup_cmd
|
25
28
|
@runners = runners
|
26
29
|
@env_store = EnvStore.new
|
30
|
+
start_service
|
27
31
|
start_off
|
32
|
+
ensure
|
33
|
+
stop_service
|
28
34
|
end
|
29
35
|
|
30
36
|
def start_off
|
31
|
-
|
32
|
-
DTR.info "=> Herald starts off..."
|
37
|
+
DTR.info {"=> Herald starts off..."}
|
33
38
|
provide_agent_info(@agent_env_setup_cmd, @runners)
|
34
39
|
|
40
|
+
@env_store[@working_env_key] = fetch_working_env
|
41
|
+
rescue WorkingEnvError
|
42
|
+
DTR.error $!.message
|
43
|
+
exit(-1)
|
44
|
+
rescue
|
45
|
+
DTR.error $!.message
|
46
|
+
DTR.error $!.backtrace.join("\n")
|
47
|
+
exit(-1)
|
48
|
+
end
|
49
|
+
|
50
|
+
def fetch_working_env
|
35
51
|
working_env = lookup_working_env
|
36
|
-
DTR.info "=> Got working environment created at #{working_env[:created_at]} by #{working_env[:host]}"
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
if working_env.setup_env(@agent_env_setup_cmd)
|
43
|
-
@env_store[@working_env_key] = working_env
|
44
|
-
else
|
45
|
-
DTR.info {'Setup working environment failed, no runner started.'}
|
46
|
-
end
|
52
|
+
DTR.info {"=> Got working environment created at #{working_env[:created_at]} by #{working_env[:host]}"}
|
53
|
+
|
54
|
+
raise WorkingEnvError.new("No test files need to load?(working env: #{working_env})") if working_env[:files].blank?
|
55
|
+
raise WorkingEnvError.new('Setup working environment failed, no runner started.') unless working_env.setup_env(@agent_env_setup_cmd)
|
56
|
+
working_env
|
47
57
|
end
|
48
58
|
end
|
49
59
|
end
|
data/lib/dtr/agent/runner.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -20,7 +20,6 @@ module DTR
|
|
20
20
|
|
21
21
|
def self.start(name, env)
|
22
22
|
self.new(name, env).start
|
23
|
-
DTR.info "=> Runner #{name} provided"
|
24
23
|
DRb.thread.join if DRb.thread
|
25
24
|
end
|
26
25
|
|
@@ -30,8 +29,6 @@ module DTR
|
|
30
29
|
@name = name
|
31
30
|
@identifier = env[:identifier]
|
32
31
|
@env = env
|
33
|
-
@started = 0
|
34
|
-
@run_finished = 0
|
35
32
|
end
|
36
33
|
|
37
34
|
def start
|
@@ -39,59 +36,49 @@ module DTR
|
|
39
36
|
start_service
|
40
37
|
DTR.info("=> Starting runner #{name} at #{Dir.pwd}, pid: #{Process.pid}")
|
41
38
|
init_environment
|
42
|
-
|
39
|
+
provide
|
40
|
+
DTR.info {"=> Runner #{name} provided"}
|
41
|
+
rescue Exception
|
42
|
+
DTR.error($!.message)
|
43
|
+
DTR.error($!.backtrace.join("\n"))
|
43
44
|
end
|
44
45
|
|
45
46
|
def init_environment
|
46
|
-
DTR.info "#{name}: Initialize working environment..."
|
47
|
+
DTR.info {"#{name}: Initialize working environment..."}
|
48
|
+
ENV['DTR_RUNNER_NAME'] = name
|
49
|
+
|
47
50
|
@env[:libs].select{ |lib| !$LOAD_PATH.include?(lib) && File.exists?(lib) }.each do |lib|
|
48
51
|
$LOAD_PATH << lib
|
49
|
-
DTR.debug "#{name}: appended lib: #{lib}"
|
52
|
+
DTR.debug {"#{name}: appended lib: #{lib}"}
|
50
53
|
end
|
51
|
-
DTR.info "#{name}: libs loaded"
|
52
|
-
DTR.debug "#{name}: $LOAD_PATH: #{$LOAD_PATH.inspect}"
|
54
|
+
DTR.info {"#{name}: libs loaded"}
|
55
|
+
DTR.debug {"#{name}: $LOAD_PATH: #{$LOAD_PATH.inspect}"}
|
53
56
|
|
54
57
|
@env[:files].each do |f|
|
55
58
|
begin
|
56
59
|
load f unless f =~ /^-/
|
57
|
-
DTR.debug "#{name}: loaded #{f}"
|
60
|
+
DTR.debug {"#{name}: loaded #{f}"}
|
58
61
|
rescue LoadError => e
|
59
|
-
DTR.error "#{name}: No such file to load -- #{f}"
|
60
|
-
DTR.debug "Environment: #{@env}"
|
62
|
+
DTR.error {"#{name}: No such file to load -- #{f}"}
|
63
|
+
DTR.debug {"Environment: #{@env}"}
|
61
64
|
end
|
62
65
|
end
|
63
|
-
DTR.info "#{name}: test files loaded"
|
66
|
+
DTR.info {"#{name}: test files loaded"}
|
64
67
|
end
|
65
68
|
|
66
69
|
def run(test, result, &progress_block)
|
67
|
-
DTR.
|
68
|
-
|
69
|
-
|
70
|
-
test.run(result, &progress_block)
|
71
|
-
rescue DRb::DRbConnError => e
|
72
|
-
DTR.info "Rescued DRb::DRbConnError(#{e.message}), while running test: #{test.name}. The master process may be stopped."
|
73
|
-
rescue Exception => e
|
74
|
-
DTR.error "Unexpected exception: #{e.message}"
|
75
|
-
DTR.error e.backtrace.join("\n")
|
76
|
-
result.add_error(Test::Unit::Error.new(test.name, e))
|
77
|
-
result.add_run
|
78
|
-
progress_block.call(Test::Unit::TestCase::FINISHED, test.name)
|
70
|
+
DTR.debug {"#{name}: running #{test}..."}
|
71
|
+
Agent::TestCase.new(test, result, &progress_block).run
|
72
|
+
DTR.debug {"#{name}: done #{test}"}
|
79
73
|
ensure
|
80
|
-
|
81
|
-
|
82
|
-
provide_runner(self)
|
74
|
+
provide
|
75
|
+
DTR.debug {"=> Runner #{name} provided"}
|
83
76
|
end
|
84
77
|
|
85
|
-
def
|
86
|
-
DTR.info "#{self} is rebooting. Ran #{@started} tests, finished #{@run_finished}."
|
78
|
+
def provide
|
87
79
|
provide_runner(self)
|
88
80
|
end
|
89
81
|
|
90
|
-
def shutdown
|
91
|
-
DTR.info "#{self} is shutting down. Ran #{@started} tests, finished #{@run_finished}."
|
92
|
-
stop_service rescue exit!
|
93
|
-
end
|
94
|
-
|
95
82
|
def to_s
|
96
83
|
"Runner #{@name}"
|
97
84
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -15,12 +15,12 @@
|
|
15
15
|
module DTR
|
16
16
|
module SyncLogger
|
17
17
|
|
18
|
-
# Synchronizer loads SyncLogger
|
19
|
-
# Any process need sync logs with master process should start service first
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
18
|
+
# Synchronizer loads SyncLogger provided by master process from Rinda server.
|
19
|
+
# Any process need sync logs with master process should start service first,
|
20
|
+
# so that local logger could be replaced by SyncLogger.
|
21
|
+
# For logs would be sent back to master process, all messages would be sent
|
22
|
+
# as string message. The message logged as block would be converted to string
|
23
|
+
# message.
|
24
24
|
module Synchronizer
|
25
25
|
def self.included(base)
|
26
26
|
base.alias_method_chain :start_service, :sync_logger
|
@@ -30,10 +30,40 @@ module DTR
|
|
30
30
|
start_service_without_sync_logger
|
31
31
|
if logger_tuple = lookup_ring.read_all([:logger, nil]).first
|
32
32
|
sync_logger = logger_tuple[1]
|
33
|
-
DTR.logger = sync_logger
|
33
|
+
DTR.logger = MessageDecoratedLogger.new(sync_logger)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
+
|
38
|
+
class MessageDecoratedLogger
|
39
|
+
include MessageDecorator
|
40
|
+
|
41
|
+
def initialize(logger)
|
42
|
+
@logger = logger
|
43
|
+
end
|
44
|
+
|
45
|
+
def debug(message=nil, &block)
|
46
|
+
with_decorating_message(:debug, message, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def info(message=nil, &block)
|
50
|
+
with_decorating_message(:info, message, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def error(message=nil, &block)
|
54
|
+
with_decorating_message(:error, message, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def level
|
58
|
+
@logger_level ||= @logger.level
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def with_decorating_message(level, msg, &block)
|
63
|
+
raise 'Should not use block to send log remotely' if block_given?
|
64
|
+
@logger.send(level, decorate_message(msg))
|
65
|
+
end
|
66
|
+
end
|
37
67
|
end
|
38
68
|
|
39
69
|
Service::Rinda.send(:include, SyncLogger::Synchronizer)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module DTR
|
16
|
+
module Agent
|
17
|
+
class UnknownTestError < StandardError
|
18
|
+
end
|
19
|
+
class TestCase
|
20
|
+
def initialize(test, result, &progress_block)
|
21
|
+
@test = test
|
22
|
+
@result = result
|
23
|
+
@progress_block = progress_block
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
if @test.is_a?(DRb::DRbUnknown)
|
28
|
+
add_error(UnknownTestError.new("No such test loaded: #{@test.name}"))
|
29
|
+
else
|
30
|
+
@test.run(@result, &@progress_block)
|
31
|
+
end
|
32
|
+
rescue DRb::DRbConnError => e
|
33
|
+
msg = "Rescued DRb::DRbConnError(#{e.message}), while running test: #{test}. The master process may be stopped."
|
34
|
+
DTR.do_println(msg)
|
35
|
+
DTR.info {msg}
|
36
|
+
rescue Exception => e
|
37
|
+
unexpected_error(e)
|
38
|
+
end
|
39
|
+
|
40
|
+
def unexpected_error(e)
|
41
|
+
DTR.error "Unexpected exception: #{e.message}"
|
42
|
+
DTR.error e.backtrace.join("\n")
|
43
|
+
add_error(e)
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_error(e)
|
47
|
+
@result.add_error(Test::Unit::Error.new(@test.name, RemoteError.new(e)))
|
48
|
+
@result.add_run
|
49
|
+
@progress_block.call(Test::Unit::TestCase::FINISHED, @test.name)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/dtr/agent/test_unit.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -35,8 +35,6 @@ module DTR
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
# set run to true first, so that test auto runner wouldn't work
|
38
39
|
Test::Unit.run = true
|
39
|
-
|
40
|
-
class Test::Unit::TestCase
|
41
|
-
include DTR::Agent::TestCaseExt
|
42
|
-
end
|
40
|
+
Test::Unit::TestCase.send(:include, DTR::Agent::TestCaseExt)
|
data/lib/dtr/agent/worker.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -15,6 +15,8 @@
|
|
15
15
|
module DTR
|
16
16
|
|
17
17
|
module Agent
|
18
|
+
# Worker works during one dtr test task running.
|
19
|
+
# Worker manages Herald & Runner processes life cycle.
|
18
20
|
class Worker
|
19
21
|
def initialize(runner_names, agent_env_setup_cmd)
|
20
22
|
@runner_names = runner_names.is_a?(Array) ? runner_names : [runner_names.to_s]
|
@@ -26,13 +28,13 @@ module DTR
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def launch
|
29
|
-
DTR.info "=> Agent worker started at: #{Dir.pwd}, pid: #{Process.pid}"
|
31
|
+
DTR.info {"=> Agent worker started at: #{Dir.pwd}, pid: #{Process.pid}"}
|
30
32
|
setup
|
31
33
|
begin
|
32
34
|
run
|
33
35
|
ensure
|
34
36
|
teardown
|
35
|
-
DTR.info "Agent worker is dieing"
|
37
|
+
DTR.info {"Agent worker is dieing"}
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
@@ -42,50 +44,45 @@ module DTR
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def teardown
|
45
|
-
|
47
|
+
unless @runner_pids.blank?
|
48
|
+
@runner_pids.each{ |pid| DTR.kill_process pid }
|
49
|
+
DTR.info {"=> All runners(#{@runner_pids.join(", ")}) were killed." }
|
50
|
+
@runner_pids = []
|
51
|
+
end
|
46
52
|
if @herald
|
47
|
-
|
53
|
+
DTR.kill_process @herald
|
48
54
|
@herald = nil
|
49
|
-
DTR.info "=> Herald is killed."
|
55
|
+
DTR.info {"=> Herald is killed."}
|
50
56
|
end
|
51
57
|
end
|
52
58
|
|
53
59
|
def run
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
60
|
+
herald
|
61
|
+
runners
|
62
|
+
DTR.info {"=> All agent worker sub processes exited."}
|
63
|
+
end
|
64
|
+
|
65
|
+
def herald
|
66
|
+
@herald = DTR.fork_process { Herald.new @working_env_key, @agent_env_setup_cmd, @runner_names }
|
67
|
+
Process.waitpid @herald
|
68
|
+
exit(-1) unless $?.exitstatus == 0
|
69
|
+
end
|
70
|
+
|
71
|
+
def runners
|
58
72
|
working_env = @env_store[@working_env_key]
|
59
73
|
|
60
74
|
@runner_names.each do |name|
|
61
|
-
@runner_pids <<
|
75
|
+
@runner_pids << DTR.fork_process {
|
76
|
+
at_exit {
|
77
|
+
# exit anyway, for DRb may hang on the process to be a deadwalk
|
78
|
+
exit!
|
79
|
+
}
|
62
80
|
working_env.within do
|
63
81
|
Runner.start name, working_env
|
64
82
|
end
|
65
83
|
}
|
66
84
|
end
|
67
85
|
Process.waitall
|
68
|
-
DTR.info "=> All agent worker sub processes exited."
|
69
|
-
end
|
70
|
-
|
71
|
-
def kill_all_runners
|
72
|
-
unless @runner_pids.blank?
|
73
|
-
@runner_pids.each{ |pid| Process.kill 'TERM', pid rescue nil }
|
74
|
-
DTR.info "=> All runners(#{@runner_pids.join(", ")}) were killed."
|
75
|
-
@runner_pids = []
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def drb_fork
|
80
|
-
Process.fork do
|
81
|
-
begin
|
82
|
-
yield
|
83
|
-
rescue Interrupt, SystemExit, SignalException
|
84
|
-
rescue Exception => e
|
85
|
-
DTR.error "Worker drb fork is stopped by Exception => #{e.class.name}, message => #{e.message}"
|
86
|
-
DTR.info e.backtrace.join("\n")
|
87
|
-
end
|
88
|
-
end
|
89
86
|
end
|
90
87
|
end
|
91
88
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -14,6 +14,7 @@
|
|
14
14
|
|
15
15
|
module DTR
|
16
16
|
module Agent
|
17
|
+
# Provides working environment setup beheaviours for Herald & Runner process
|
17
18
|
module WorkingEnvExt
|
18
19
|
def within
|
19
20
|
ENV['DTR_MASTER_ENV'] = self[:dtr_master_env]
|
@@ -35,7 +36,8 @@ module DTR
|
|
35
36
|
|
36
37
|
def working_dir
|
37
38
|
return @working_dir if defined?(@working_dir)
|
38
|
-
|
39
|
+
project_specific_len = 20
|
40
|
+
project_name = self[:pwd].length > project_specific_len ? self[:pwd][-project_specific_len..-1] : self[:pwd]
|
39
41
|
@working_dir = File.join(escape(self[:host]), escape(project_name))
|
40
42
|
FileUtils.mkdir_p(@working_dir)
|
41
43
|
@working_dir
|
data/lib/dtr/agent.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -21,6 +21,7 @@ require 'dtr/agent/brain'
|
|
21
21
|
require 'dtr/agent/worker'
|
22
22
|
require 'dtr/agent/test_unit'
|
23
23
|
require 'dtr/agent/herald'
|
24
|
+
require 'dtr/agent/test_case'
|
24
25
|
require 'dtr/agent/runner'
|
25
26
|
|
26
27
|
module DTR
|
data/lib/dtr/facade.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module DTR
|
16
|
+
module Facade
|
17
|
+
def start_agent
|
18
|
+
launch_agent(DTR_AGENT_OPTIONS[:runners], DTR_AGENT_OPTIONS[:agent_env_setup_cmd])
|
19
|
+
end
|
20
|
+
|
21
|
+
def launch_agent(names, setup=nil)
|
22
|
+
require 'dtr/agent'
|
23
|
+
names = names || "DTR(#{Time.now})"
|
24
|
+
DTR::Agent.start(names, setup)
|
25
|
+
end
|
26
|
+
|
27
|
+
def lib_path
|
28
|
+
File.expand_path(File.dirname(__FILE__) + '/../')
|
29
|
+
end
|
30
|
+
|
31
|
+
def broadcast_list=(list)
|
32
|
+
require 'dtr/shared'
|
33
|
+
DTR.configuration.broadcast_list = list
|
34
|
+
DTR.configuration.save
|
35
|
+
end
|
36
|
+
|
37
|
+
def agent_listen_port=(port)
|
38
|
+
require 'dtr/shared'
|
39
|
+
DTR.configuration.agent_listen_port = port
|
40
|
+
DTR.configuration.save
|
41
|
+
end
|
42
|
+
|
43
|
+
def group=(group)
|
44
|
+
require 'dtr/shared'
|
45
|
+
DTR.configuration.group = group
|
46
|
+
DTR.configuration.save
|
47
|
+
end
|
48
|
+
|
49
|
+
def monitor
|
50
|
+
require 'dtr/monitor'
|
51
|
+
DTR.logger('dtr_monitor.log')
|
52
|
+
Monitor.new.start
|
53
|
+
end
|
54
|
+
|
55
|
+
# For safe fork & kill sub process, should use Process.kill and Process.fork
|
56
|
+
# At least have problem on ruby 1.8.6 114 with Kernel#kill & fork
|
57
|
+
def kill_process(pid)
|
58
|
+
Process.kill 'TERM', pid rescue nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def fork_process(&block)
|
62
|
+
Process.fork(&block)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/dtr/master.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -21,8 +21,8 @@ module DTR
|
|
21
21
|
ActiveRecord::Base.clear_active_connections! rescue nil
|
22
22
|
end
|
23
23
|
|
24
|
-
DTR.info ""
|
25
|
-
DTR.info "--------------------beautiful line--------------------------"
|
24
|
+
DTR.info {""}
|
25
|
+
DTR.info {"--------------------beautiful line--------------------------"}
|
26
26
|
DTR.info {"Master process started at #{Time.now}"}
|
27
27
|
|
28
28
|
DTR.configuration.with_rinda_server do
|
data/lib/dtr/monitor.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007-2008 Li Xiao
|
1
|
+
# Copyright (c) 2007-2008 Li Xiao <iam@li-xiao.com>
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -15,23 +15,81 @@
|
|
15
15
|
require 'dtr/master'
|
16
16
|
|
17
17
|
module DTR
|
18
|
+
|
19
|
+
# Monitor provides a way to monitor agent/master process working status.
|
18
20
|
class Monitor
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
|
22
|
+
class AgentsMonitor
|
23
|
+
include Adapter::Master
|
24
|
+
|
25
|
+
def start
|
26
|
+
DTR.fork_process do
|
27
|
+
monitor
|
28
|
+
end
|
29
|
+
end
|
30
|
+
def monitor
|
31
|
+
DTR.configuration.with_rinda_server do
|
32
|
+
with_wakeup_agents do
|
33
|
+
begin
|
34
|
+
sleep
|
35
|
+
rescue Interrupt
|
36
|
+
end
|
37
|
+
end
|
25
38
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class MasterMonitor
|
43
|
+
include Adapter::Follower
|
44
|
+
include Service::Agent
|
45
|
+
|
46
|
+
def start
|
47
|
+
DTR.fork_process do
|
29
48
|
begin
|
30
|
-
|
49
|
+
loop do
|
50
|
+
monitor
|
51
|
+
end
|
52
|
+
rescue Errno::EADDRINUSE
|
53
|
+
puts "There is DTR agent started on this machine."
|
54
|
+
puts "Shutdown it for monitoring working DTR Master info."
|
31
55
|
rescue Interrupt
|
56
|
+
ensure
|
57
|
+
relax
|
32
58
|
end
|
33
59
|
end
|
34
60
|
end
|
61
|
+
|
62
|
+
def monitor
|
63
|
+
msg, from_host, group = listen
|
64
|
+
unless ["127.0.0.1:#{DTR.configuration.rinda_server_port}"].include?(from_host)
|
65
|
+
puts "Master process message from #{from_host}: #{msg} for group #{group}"
|
66
|
+
ip, port = from_host.split(':')
|
67
|
+
with_configuration(ip, port) do
|
68
|
+
start_service
|
69
|
+
puts "Agents working for #{from_host}: "
|
70
|
+
puts all_agents_info.collect{|i| " #{i.strip}"}.join("\n")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def with_configuration(ip, port)
|
76
|
+
my_port = DTR.configuration.rinda_server_port
|
77
|
+
my_broadcast_list = DTR.configuration.broadcast_list
|
78
|
+
DTR.configuration.rinda_server_port = port.to_i
|
79
|
+
DTR.configuration.broadcast_list = [ip]
|
80
|
+
yield
|
81
|
+
ensure
|
82
|
+
DTR.configuration.broadcast_list = my_broadcast_list
|
83
|
+
DTR.configuration.rinda_server_port = my_port
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def start
|
88
|
+
MasterMonitor.new.start
|
89
|
+
AgentsMonitor.new.start
|
90
|
+
puts "Monitor process started at #{Time.now}"
|
91
|
+
Process.waitall
|
92
|
+
rescue Interrupt
|
35
93
|
end
|
36
94
|
end
|
37
95
|
end
|