xli-dtr 0.0.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/CHANGES +7 -0
  2. data/README.rdoc +208 -0
  3. data/Rakefile +54 -63
  4. data/TODO +7 -16
  5. data/bin/dtr +26 -20
  6. data/dtr.gemspec +7 -10
  7. data/lib/dtr/agent/brain.rb +13 -22
  8. data/lib/dtr/agent/herald.rb +24 -14
  9. data/lib/dtr/agent/runner.rb +22 -35
  10. data/lib/dtr/agent/sync_codebase.rb +1 -1
  11. data/lib/dtr/agent/sync_logger.rb +38 -8
  12. data/lib/dtr/agent/test_case.rb +53 -0
  13. data/lib/dtr/agent/test_unit.rb +3 -5
  14. data/lib/dtr/agent/worker.rb +29 -32
  15. data/lib/dtr/agent/working_env_ext.rb +4 -2
  16. data/lib/dtr/agent.rb +2 -1
  17. data/lib/dtr/facade.rb +65 -0
  18. data/lib/dtr/master.rb +3 -3
  19. data/lib/dtr/monitor.rb +69 -11
  20. data/lib/dtr/raketasks.rb +91 -19
  21. data/lib/dtr/shared/adapter.rb +29 -26
  22. data/lib/dtr/shared/configuration.rb +39 -11
  23. data/lib/dtr/shared/message_decorator.rb +1 -1
  24. data/lib/dtr/shared/ruby_ext.rb +1 -25
  25. data/lib/dtr/shared/service/agent.rb +5 -1
  26. data/lib/dtr/shared/service/file.rb +1 -1
  27. data/lib/dtr/shared/service/rinda.rb +11 -3
  28. data/lib/dtr/shared/service/runner.rb +6 -5
  29. data/lib/dtr/shared/service/working_env.rb +1 -1
  30. data/lib/dtr/shared/service.rb +1 -1
  31. data/lib/dtr/shared/sync_codebase/{codebase.rb → copiable_package.rb} +13 -5
  32. data/lib/dtr/shared/sync_codebase/master_ext.rb +6 -18
  33. data/lib/dtr/shared/sync_codebase/package.rb +16 -2
  34. data/lib/dtr/shared/sync_codebase/sync_service.rb +7 -12
  35. data/lib/dtr/shared/sync_codebase.rb +2 -2
  36. data/lib/dtr/shared/sync_logger.rb +6 -14
  37. data/lib/dtr/shared/utils/cmd.rb +5 -5
  38. data/lib/dtr/shared/utils/env_store.rb +1 -1
  39. data/lib/dtr/shared/utils/logger.rb +33 -17
  40. data/lib/dtr/shared/utils.rb +1 -1
  41. data/lib/dtr/shared/working_env.rb +2 -2
  42. data/lib/dtr/shared.rb +1 -1
  43. data/lib/dtr/test_unit/drb_test_runner.rb +5 -14
  44. data/lib/dtr/test_unit/injection.rb +1 -2
  45. data/lib/dtr/test_unit/test_case_injection.rb +13 -13
  46. data/lib/dtr/test_unit/test_suite_injection.rb +24 -0
  47. data/lib/dtr/test_unit/testrunnermediator_injection.rb +11 -11
  48. data/lib/dtr/test_unit/thread_safe_test_result.rb +1 -3
  49. data/lib/dtr/test_unit/worker_club.rb +7 -7
  50. data/lib/dtr/test_unit.rb +2 -1
  51. data/lib/dtr/test_unit_injection.rb +1 -1
  52. data/lib/dtr.rb +5 -36
  53. data/test/acceptance/agent_working_env_test.rb +28 -34
  54. data/test/acceptance/dtr_package_task_test.rb +13 -3
  55. data/test/acceptance/general_test.rb +139 -83
  56. data/test/acceptance/raketasks_test.rb +23 -0
  57. data/test/acceptance/sync_codebase_test.rb +12 -13
  58. data/test/acceptance/sync_logger_test.rb +12 -21
  59. data/test/agent_helper.rb +8 -10
  60. data/test/logger_stub.rb +4 -0
  61. data/test/test_helper.rb +33 -5
  62. data/test/unit/adapter_test.rb +58 -16
  63. data/test/unit/configuration_test.rb +44 -0
  64. data/test/unit/facade_test.rb +41 -0
  65. data/test/unit/logger_test.rb +72 -0
  66. data/test/unit/test_unit_test.rb +0 -21
  67. data/testdata/Rakefile +1 -5
  68. data/testdata/hacked_run_method_test_case.rb +15 -0
  69. data/testdata/raketasks/Rakefile +7 -0
  70. data/testdata/raketasks/success_test_case.rb +6 -0
  71. data/testdata/sleep_3_secs_test_case.rb +9 -0
  72. 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
  73. metadata +33 -13
  74. data/README +0 -182
  75. data/install.rb +0 -88
  76. /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/raketasks.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.
@@ -13,22 +13,77 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require "rubygems"
16
- require 'dtr'
17
- require 'dtr/shared/sync_codebase/package'
18
- require 'dtr/shared/ruby_ext'
19
16
  require 'rake'
20
17
  require 'rake/testtask'
21
18
  require 'rake/tasklib'
22
19
 
20
+ require 'dtr'
21
+ require 'dtr/shared/ruby_ext'
22
+ require 'dtr/shared/utils'
23
+ require 'dtr/shared/sync_codebase/package'
24
+
23
25
  module DTR
26
+ # Create tasks that run a set of tests with DTR injected.
27
+ # The TestTask will create the following targets:
28
+ #
29
+ # [<b>:dtr</b>]:
30
+ # Create a task that runs a set of tests by DTR master.
31
+ #
32
+ # [DTR::PackageTask]:
33
+ # Create a packaging task that will package the project into
34
+ # distributable files for running test on remote machine.
35
+ # All test files should be included.
36
+ #
37
+ # Example:
38
+ # require 'dtr/raketasks'
39
+ #
40
+ # DTR::TestTask.new do |t|
41
+ # t.libs << "test"
42
+ # t.test_files = FileList['test/test*.rb']
43
+ # t.verbose = true
44
+ # t.processes = 1 # default is 1
45
+ # t.package_files.include("lib/**/*") # default is FileList["**/*"]
46
+ # t.package_files.include("test/**/*")
47
+ # end
48
+ #
49
+ # This task inherits from Rake::TestTask, and adds 2 DTR specific
50
+ # options: processes and package_files.
51
+ #
24
52
  class TestTask < Rake::TestTask
53
+
54
+ #
55
+ # The option processes is used to start an DTR agent in same directory
56
+ # with master process. The number of processes is the size of runners
57
+ # launched by agent for running tests. If processes is set to 0,
58
+ # then there is no agent started locally.
59
+ # Default is 1.
25
60
  attr_accessor :processes
26
-
61
+
62
+ # List of files to be included in the package for running tests on
63
+ # remote agent.
64
+ # The agent, which starts in same directory on same machine with
65
+ # master process, would skip copying codebase.
66
+ # The default package files is Rake::FileList["**/*"].
67
+ attr_accessor :package_files
68
+
69
+ def initialize(name=:dtr)
70
+ @processes = 1
71
+ @package_files = Rake::FileList.new
72
+ super(name)
73
+ end
74
+
27
75
  def define
76
+ PackageTask.new do |p|
77
+ p.package_files = package_files
78
+ if p.package_files.empty?
79
+ p.package_files.include("**/*")
80
+ end
81
+ end
82
+
28
83
  @libs.unshift DTR.lib_path
29
84
  lib_path = @libs.join(File::PATH_SEPARATOR)
30
85
 
31
- desc "Run tests" + (@name==:test ? "" : " for #{@name}")
86
+ desc "Run tests with DTR injected"
32
87
  task @name do
33
88
  @agent = start_agent
34
89
  run_code = ''
@@ -45,43 +100,59 @@ module DTR
45
100
  end
46
101
  ensure
47
102
  if defined?(@agent)
48
- Process.kill 'TERM', @agent rescue nil
103
+ DTR.kill_process @agent
49
104
  end
50
105
  end
51
106
  end
52
107
  self
53
108
  end
54
-
55
- def processes
56
- @processes ? @processes.to_i : 2
57
- end
58
-
109
+
59
110
  private
60
111
  def start_agent
61
112
  return if self.processes.to_i <= 0
62
113
  runner_names = []
63
114
  self.processes.to_i.times {|i| runner_names << "runner#{i}"}
64
115
 
65
- Process.fork do
116
+ DTR.fork_process do
66
117
  DTR_AGENT_OPTIONS[:runners] = runner_names if DTR_AGENT_OPTIONS[:runners].empty?
67
118
  DTR.start_agent
68
119
  end
69
120
  end
70
121
  end
71
122
 
72
- # The following task is copied & modified from 'rake/packagetask'
123
+ # Create a packaging task that will package the project into
124
+ # distributable files for running test on remote machine.
125
+ # It uses zip and unzip to package and unpackage files.
126
+ # All test files should be included.
127
+ #
128
+ # The PackageTask will create the following targets:
129
+ #
130
+ # [<b>:dtr_package</b>]
131
+ # Create all the requested package files.
132
+ #
133
+ # [<b>:dtr_clobber_package</b>]
134
+ # Delete all the package files. This target is automatically
135
+ # added to the main clobber target.
136
+ #
137
+ # [<b>:dtr_repackage</b>]
138
+ # Rebuild the package files from scratch, even if they are not out
139
+ # of date.
140
+ #
141
+ # Example:
142
+ #
143
+ # DTR::PackageTask.new do |p|
144
+ # p.package_files.include("lib/**/*.rb")
145
+ # p.package_files.include("test/**/*.rb")
146
+ # end
147
+ #
73
148
  class PackageTask < Rake::TaskLib
74
149
  include SyncCodebase::Package
75
150
  # List of files to be included in the package.
76
151
  attr_accessor :package_files
77
152
 
78
- # Tar command for gzipped or bzip2ed archives. The default is 'tar'.
79
- attr_accessor :tar_command
80
-
81
153
  # Create a Package Task with the given name and version.
82
154
  def initialize
83
155
  @package_files = Rake::FileList.new
84
- @tar_command = 'tar'
85
156
  yield self if block_given?
86
157
  define
87
158
  end
@@ -104,7 +175,7 @@ module DTR
104
175
 
105
176
  file "#{package_dir}/#{file}" => [package_dir_path] do
106
177
  chdir(package_dir) do
107
- sh %{#{@tar_command} #{flag}cvf #{file} #{package_name}}
178
+ do_work(package_cmd)
108
179
  end
109
180
  end
110
181
 
@@ -112,6 +183,7 @@ module DTR
112
183
 
113
184
  file package_dir_path do
114
185
  mkdir_p package_dir rescue nil
186
+ @package_files.exclude(package_dir)
115
187
  @package_files.each do |fn|
116
188
  f = File.join(package_dir_path, fn)
117
189
  fdir = File.dirname(f)
@@ -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,17 +16,16 @@ require 'timeout'
16
16
 
17
17
  module DTR
18
18
  module Adapter
19
- AGENT_PORT = 7788
20
-
21
19
  WAKEUP_MESSAGE = 'wakeup'
22
20
  SLEEP_MESSAGE = 'sleep'
23
21
 
24
22
  module Follower
25
23
  def wakeup?
26
- msg, host = listen
27
- if msg == Adapter::WAKEUP_MESSAGE
28
- port = host.split(':').last.to_i
29
- DTR.configuration.rinda_server_port = port
24
+ msg, host, group = listen
25
+ if group == DTR.configuration.group && msg == Adapter::WAKEUP_MESSAGE
26
+ ip, port = host.split(':')
27
+ DTR.configuration.rinda_server_port = port.to_i
28
+ DTR.configuration.broadcast_list = [ip]
30
29
  @wakeup_for_host = host
31
30
  true
32
31
  end
@@ -34,40 +33,48 @@ module DTR
34
33
 
35
34
  def sleep?
36
35
  return true unless defined?(@wakeup_for_host)
37
- msg, host = Timeout.timeout(DTR.configuration.follower_listen_sleep_timeout) do
38
- loop do
39
- msg, host = listen
40
- break if host == @wakeup_for_host
41
- end
42
- [msg, host]
36
+ Timeout.timeout(DTR.configuration.follower_listen_heartbeat_timeout) do
37
+ until (msg, host = listen) && host == @wakeup_for_host; end
38
+ msg == Adapter::SLEEP_MESSAGE
43
39
  end
44
- DTR.info "Received: #{msg} from #{host}"
45
- msg == Adapter::SLEEP_MESSAGE
46
40
  rescue Timeout::Error => e
47
- DTR.info "Timeout while listening command"
41
+ DTR.info {"Timeout while listening command"}
48
42
  true
49
43
  end
50
44
 
45
+ def relax
46
+ if defined?(@soc) && @soc
47
+ @soc.close rescue nil
48
+ end
49
+ end
50
+
51
51
  private
52
52
  def listen
53
53
  unless defined?(@soc)
54
54
  @soc = UDPSocket.open
55
- @soc.bind('', Adapter::AGENT_PORT)
55
+ @soc.bind('', DTR.configuration.agent_listen_port)
56
+ DTR.info("DTR Agent is listening on port #{DTR.configuration.agent_listen_port}")
56
57
  end
57
- @soc.recv(1024).split
58
+ message, client_address = @soc.recvfrom(400)
59
+ cmd, port, group = message.split
60
+
61
+ hostname = client_address[2]
62
+ host_ip = client_address[3]
63
+ DTR.info {"Received: #{cmd} for group #{group} from #{hostname}(#{host_ip}):#{port}"}
64
+ [cmd, "#{host_ip}:#{port}", group]
58
65
  end
59
66
  end
60
67
 
61
68
  module Master
62
69
  def hypnotize_agents
63
- yell_agents("#{Adapter::SLEEP_MESSAGE} #{host}")
70
+ yell_agents("#{Adapter::SLEEP_MESSAGE} #{DTR.configuration.rinda_server_port}")
64
71
  end
65
72
 
66
73
  def with_wakeup_agents(&block)
67
74
  heartbeat = Thread.new do
68
75
  loop do
69
76
  do_wakeup_agents
70
- sleep(DTR.configuration.master_yell_interval)
77
+ sleep(DTR.configuration.master_heartbeat_interval)
71
78
  end
72
79
  end
73
80
  #heartbeat thread should have high priority for agent is listening
@@ -80,7 +87,7 @@ module DTR
80
87
  end
81
88
 
82
89
  def do_wakeup_agents
83
- yell_agents("#{Adapter::WAKEUP_MESSAGE} #{host}")
90
+ yell_agents("#{Adapter::WAKEUP_MESSAGE} #{DTR.configuration.rinda_server_port} #{DTR.configuration.group}")
84
91
  end
85
92
 
86
93
  private
@@ -91,16 +98,12 @@ module DTR
91
98
  end
92
99
  end
93
100
 
94
- def host
95
- "#{Socket.gethostname}:#{DTR.configuration.rinda_server_port}"
96
- end
97
-
98
101
  def broadcast(it, msg)
99
102
  soc = UDPSocket.open
100
103
  begin
101
104
  soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
102
105
  DTR.debug {"broadcast sending #{msg} to #{it}"}
103
- soc.send(msg, 0, it, Adapter::AGENT_PORT)
106
+ soc.send(msg, 0, it, DTR.configuration.agent_listen_port)
104
107
  rescue
105
108
  nil
106
109
  ensure
@@ -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.
@@ -13,7 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require 'singleton'
16
- require 'rinda/rinda'
16
+ require 'rinda/ring'
17
17
  require 'rinda/tuplespace'
18
18
 
19
19
  module DTR
@@ -24,31 +24,59 @@ module DTR
24
24
 
25
25
  module_function :configuration
26
26
 
27
+ # DTR Configuration includes:
28
+ # For both master & agent process:
29
+ # * broadcast_list: broadcast ip list for looking for dtr services(agent and DTR master rinda server).
30
+ # * group: grouping agents for specific usage, master process should specify same group for catching agents to work
31
+ # For master process:
32
+ # * rinda_server_port: DTR would automatically detect unused port for master rinda server. The default port is 3344.
33
+ # * master_heartbeat_interval: master process heartbeat for keeping agents working. The default is 10 sec.
34
+ # For agent process:
35
+ # * agent_listen_port: agent listen master process command port, the default port is 7788.
36
+ # * follower_listen_heartbeat_timeout: agents would be going to sleep if listening master heartbeat timeout. The default is 15 sec.
37
+ #
38
+ # All configurations except rinda_server_port would be stored into pstore file .dtr_env_pstore in the DTR process launching directory.
39
+ #
27
40
  class Configuration
28
41
  include Singleton
29
42
  include Service::Rinda
30
43
 
31
- attr_accessor :broadcast_list, :rinda_server_port, :master_yell_interval, :follower_listen_sleep_timeout
44
+ attr_accessor :broadcast_list, :rinda_server_port, :agent_listen_port, :master_heartbeat_interval, :follower_listen_heartbeat_timeout
45
+ attr_reader :group
32
46
 
33
47
  def initialize
48
+ load
49
+ end
50
+
51
+ def load
34
52
  store = EnvStore.new
53
+ # always have 'localhost' in broadcast_list, for our master process would start rinda server locally,
54
+ # and dtr should work well on local machine when the machine leaves dtr grid network environment.
35
55
  @broadcast_list = ['localhost'].concat(store[:broadcast_list] || []).uniq
36
- @rinda_server_port = store[:port] || 3344
37
- @master_yell_interval = store[:master_yell_interval] || 10
38
- @follower_listen_sleep_timeout = store[:follower_listen_sleep_timeout] || 15
56
+ @rinda_server_port = 3344
57
+ @agent_listen_port = store[:agent_listen_port] || 7788
58
+ @master_heartbeat_interval = store[:master_heartbeat_interval] || 10
59
+ @follower_listen_heartbeat_timeout = store[:follower_listen_heartbeat_timeout] || 15
60
+ @group = store[:group]
39
61
  end
40
62
 
41
63
  def save
42
64
  store = EnvStore.new
43
65
  store[:broadcast_list] = @broadcast_list
44
- store[:port] = @rinda_server_port
45
- store[:master_yell_interval] = @master_yell_interval
46
- store[:follower_listen_sleep_timeout] = @follower_listen_sleep_timeout
66
+ store[:agent_listen_port] = @agent_listen_port
67
+ store[:master_heartbeat_interval] = @master_heartbeat_interval
68
+ store[:follower_listen_heartbeat_timeout] = @follower_listen_heartbeat_timeout
69
+ store[:group] = @group
70
+ end
71
+
72
+ def group=(group)
73
+ @group = group.blank? ? nil : group.gsub(' ', '_')
47
74
  end
48
75
 
49
76
  def with_rinda_server(&block)
77
+ DTR.do_println("Booting DTR service")
50
78
  start_service
51
- DTR.info '-- Booting DTR Rinda server...'
79
+ DTR.info {'-- Booting DTR Rinda server'}
52
80
  loop do
53
81
  begin
54
82
  Rinda::RingServer.new Rinda::TupleSpace.new, @rinda_server_port
@@ -57,7 +85,7 @@ module DTR
57
85
  @rinda_server_port += 1
58
86
  end
59
87
  end
60
- DTR.info "-- DTR Rinda server started on port #{@rinda_server_port}"
88
+ DTR.info {"-- DTR Rinda server started on port #{@rinda_server_port}"}
61
89
  block.call
62
90
  ensure
63
91
  stop_service rescue nil
@@ -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.
@@ -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.
@@ -12,30 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- class Null
16
- class << self
17
- def instance(overrides = {})
18
- self.new.define_overrides(overrides)
19
- end
20
- end
21
-
22
- #override Object#id for removing the warning
23
- def id
24
- nil
25
- end
26
-
27
- def method_missing(sym, *args, &block)
28
- nil
29
- end
30
-
31
- def define_overrides(overrides)
32
- overrides.each_pair do |key, value|
33
- (class << self; self; end;).send(:define_method, key, lambda { value })
34
- end
35
- self
36
- end
37
- end
38
-
39
15
  # from activesupport-2.1.1
40
16
  class Object
41
17
  def blank?
@@ -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.
@@ -28,6 +28,10 @@ module DTR
28
28
  }
29
29
  lookup_ring.write [:agent, agent]
30
30
  end
31
+
32
+ def all_agents_info
33
+ lookup_ring.read_all([:agent, nil]).collect{|t|t[1]}
34
+ end
31
35
  end
32
36
  end
33
37
  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.
@@ -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,8 +20,16 @@ module DTR
20
20
  module Rinda
21
21
 
22
22
  def start_service
23
- DTR.info "-- Start drb service..."
24
- DRb.start_service
23
+ DTR.info {"-- Start drb service..."}
24
+ #todo need figure why agents couldn't be killed directly when start drb service by DRb.start_service
25
+ if ENV['DTR_ENV'] == 'test'
26
+ DRb.start_service("druby://#{Socket.gethostname}:0")
27
+ else
28
+ DRb.start_service
29
+ end
30
+ rescue
31
+ # for ruby 1.8.7 need specify uri
32
+ DRb.start_service("druby://#{Socket.gethostname}:0")
25
33
  end
26
34
 
27
35
  def stop_service
@@ -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,14 +20,15 @@ module DTR
20
20
  include Rinda
21
21
 
22
22
  def provide_runner(runner)
23
- renewer = ::Rinda::SimpleRenewer.new
24
- tuple = [:name, 'DTR::Runner'.to_sym, runner, "DTR remote runner #{Process.pid}-#{runner.name}"]
25
- lookup_ring.write(tuple, renewer)
23
+ tuple = ['DTR::Runner'.to_sym, runner, "DTR remote runner #{Process.pid}-#{runner.name}"]
24
+ #expires after 1 sec for we don't need runner service anymore if there is no one is waiting for taking it
25
+ lookup_ring.write(tuple, 1)
26
26
  end
27
27
 
28
28
  def lookup_runner
29
- lookup(:take, [:name, 'DTR::Runner'.to_sym, nil, nil])[2]
29
+ lookup(:take, ['DTR::Runner'.to_sym, nil, nil])[1]
30
30
  end
31
+
31
32
  end
32
33
  end
33
34
  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.
@@ -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.
@@ -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,19 +14,27 @@
14
14
 
15
15
  module DTR
16
16
  module SyncCodebase
17
- class Codebase
17
+ class CopiablePackage
18
18
  include DRbUndumped
19
19
  include Package
20
20
 
21
21
  CHUNK_SIZE = 1024*1024
22
22
 
23
- def write(remote_io)
24
- File.open(File.join(package_dir, package_file), "rb") do |f|
25
- while chunk = f.read(CHUNK_SIZE) and chunk.length > 0
23
+ def initialize
24
+ raise "Package(#{codebase_package}) doesn't exist!" unless File.exist?(codebase_package)
25
+ end
26
+
27
+ def copy_into(remote_io)
28
+ File.open(codebase_package, "rb") do |f|
29
+ while (chunk = f.read(CHUNK_SIZE) || '') && chunk.length > 0
26
30
  remote_io.write(chunk)
27
31
  end
28
32
  end
29
33
  end
34
+
35
+ def codebase_package
36
+ File.join(package_dir, package_file)
37
+ end
30
38
  end
31
39
  end
32
40
  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.
@@ -12,10 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'test/unit/testresult'
16
-
17
15
  module DTR
18
16
  module SyncCodebase
17
+ # Inject synchronizing codebase ability into Master#with_dtr_master
18
+ # Packaging codebase by rake task dtr_repackage (See DTR::PackageTask)
19
19
  module MasterExt
20
20
  include Service::File
21
21
 
@@ -25,22 +25,10 @@ module DTR
25
25
 
26
26
  def with_dtr_master_with_sync_codebase(&block)
27
27
  with_dtr_master_without_sync_codebase do
28
- unless Cmd.execute('rake dtr_repackage --trace')
29
- $stderr.puts %{
30
- Execute dtr_repackage rake task failed, see log for details.
31
- For running DTR test task, you must define a DTR::PackageTask task in your rakefile for DTR need package and synchronize your codebase within grid.
32
- Example:
33
- require 'dtr/raketasks'
34
- DTR::PackageTask.new do |p|
35
- p.package_files.include("**/*")
36
- p.package_files.exclude("tmp")
37
- p.package_files.exclude("log")
38
- end
39
- }
40
- return Test::Unit::TestResult.new
41
- end
28
+ DTR.do_println("Packaging codebase")
29
+ raise 'Packaging for dtr task failed, see log for details!' unless Cmd.execute('rake dtr_repackage --trace')
42
30
  begin
43
- provide_file Codebase.new
31
+ provide_file CopiablePackage.new
44
32
  block.call
45
33
  ensure
46
34
  Cmd.execute('rake dtr_clobber_package --trace')
@@ -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.
@@ -28,12 +28,26 @@ module DTR
28
28
  end
29
29
 
30
30
  def package_file
31
- "#{package_name}.tar.bz2"
31
+ "#{package_name}.zip"
32
32
  end
33
33
 
34
34
  def package_copy_file
35
35
  "copy_#{package_file}"
36
36
  end
37
+
38
+ def unpackage_cmd
39
+ "unzip #{package_copy_file}"
40
+ end
41
+
42
+ def package_cmd
43
+ "zip -r #{package_file} #{package_name}"
44
+ end
45
+
46
+ def do_work(cmd)
47
+ unless Cmd.execute(cmd)
48
+ raise "Execute command: #{cmd} failed. See log for details."
49
+ end
50
+ end
37
51
  end
38
52
  end
39
53
  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.
@@ -18,21 +18,16 @@ module DTR
18
18
  include Package
19
19
  include Service::File
20
20
  def sync_codebase
21
- DTR.info("start sync codebase, clean #{File.join(Dir.pwd, package_name)}")
21
+ DTR.info("Start sync codebase, clean #{File.join(Dir.pwd, package_name)}")
22
22
  FileUtils.rm_rf(File.join(Dir.pwd, package_name))
23
23
 
24
- DTR.info("lookup codebase file")
25
- codebase = lookup_file
26
- DTR.info("receiving codebase: #{package_copy_file}")
24
+ DTR.info("Lookup codebase package file")
25
+ package = lookup_file
26
+ DTR.info("Receiving package file and writing to #{package_copy_file}")
27
27
  File.open(package_copy_file, 'w') do |f|
28
- codebase.write(f)
29
- end
30
- unless File.exists?(package_copy_file)
31
- raise "#{package_copy_file} does not exist, sync codebase failed."
32
- end
33
- unless Cmd.execute("tar -xjf #{package_copy_file}")
34
- raise "Extracting #{package_copy_file} by 'tar' failed."
28
+ package.copy_into(f)
35
29
  end
30
+ do_work(unpackage_cmd)
36
31
  DTR.info("sync codebase finished, clean #{package_copy_file}")
37
32
  FileUtils.rm_f(package_copy_file)
38
33
  end