dtr 0.0.4 → 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.
Files changed (93) hide show
  1. data/CHANGES +7 -0
  2. data/LICENSE.txt +203 -0
  3. data/README.rdoc +208 -0
  4. data/Rakefile +64 -205
  5. data/TODO +8 -2
  6. data/bin/dtr +27 -60
  7. data/dtr.gemspec +8 -11
  8. data/lib/dtr.rb +5 -94
  9. data/lib/dtr/agent.rb +38 -0
  10. data/lib/dtr/agent/brain.rb +57 -0
  11. data/lib/dtr/agent/herald.rb +60 -0
  12. data/lib/dtr/agent/runner.rb +87 -0
  13. data/lib/dtr/agent/sync_codebase.rb +44 -0
  14. data/lib/dtr/agent/sync_logger.rb +70 -0
  15. data/lib/dtr/agent/test_case.rb +53 -0
  16. data/lib/dtr/agent/test_unit.rb +40 -0
  17. data/lib/dtr/agent/worker.rb +89 -0
  18. data/lib/dtr/agent/working_env_ext.rb +47 -0
  19. data/lib/dtr/facade.rb +65 -0
  20. data/lib/dtr/master.rb +40 -0
  21. data/lib/dtr/monitor.rb +95 -0
  22. data/lib/dtr/raketasks.rb +155 -22
  23. data/lib/dtr/shared.rb +24 -0
  24. data/lib/dtr/shared/adapter.rb +115 -0
  25. data/lib/dtr/shared/configuration.rb +104 -0
  26. data/lib/dtr/shared/message_decorator.rb +28 -0
  27. data/lib/dtr/shared/ruby_ext.rb +129 -0
  28. data/lib/dtr/shared/service.rb +19 -0
  29. data/lib/dtr/shared/service/agent.rb +37 -0
  30. data/lib/dtr/shared/service/file.rb +28 -0
  31. data/lib/dtr/shared/service/rinda.rb +48 -0
  32. data/lib/dtr/shared/service/runner.rb +34 -0
  33. data/lib/dtr/shared/service/working_env.rb +28 -0
  34. data/lib/dtr/shared/sync_codebase.rb +18 -0
  35. data/lib/dtr/shared/sync_codebase/copiable_package.rb +40 -0
  36. data/lib/dtr/shared/sync_codebase/master_ext.rb +40 -0
  37. data/lib/dtr/shared/sync_codebase/package.rb +53 -0
  38. data/lib/dtr/shared/sync_codebase/sync_service.rb +36 -0
  39. data/lib/dtr/shared/sync_logger.rb +64 -0
  40. data/lib/dtr/shared/utils.rb +17 -0
  41. data/lib/dtr/shared/utils/cmd.rb +30 -0
  42. data/lib/dtr/shared/utils/env_store.rb +60 -0
  43. data/lib/dtr/shared/utils/logger.rb +87 -0
  44. data/lib/dtr/shared/working_env.rb +38 -0
  45. data/lib/dtr/test_unit.rb +9 -275
  46. data/lib/dtr/test_unit/drb_test_runner.rb +48 -0
  47. data/lib/dtr/test_unit/injection.rb +29 -0
  48. data/lib/dtr/test_unit/test_case_injection.rb +37 -0
  49. data/lib/dtr/test_unit/test_suite_injection.rb +24 -0
  50. data/lib/dtr/test_unit/testrunnermediator_injection.rb +72 -0
  51. data/lib/dtr/test_unit/thread_safe_test_result.rb +38 -0
  52. data/lib/dtr/test_unit/worker_club.rb +72 -0
  53. data/lib/dtr/test_unit_injection.rb +1 -2
  54. data/test/acceptance/agent_working_env_test.rb +86 -0
  55. data/test/acceptance/dtr_package_task_test.rb +36 -0
  56. data/test/acceptance/general_test.rb +331 -0
  57. data/test/acceptance/raketasks_test.rb +23 -0
  58. data/test/acceptance/sync_codebase_test.rb +66 -0
  59. data/test/acceptance/sync_logger_test.rb +32 -0
  60. data/test/agent_helper.rb +37 -0
  61. data/test/logger_stub.rb +34 -0
  62. data/test/test_helper.rb +71 -0
  63. data/test/unit/adapter_test.rb +149 -0
  64. data/test/unit/configuration_test.rb +44 -0
  65. data/test/unit/facade_test.rb +41 -0
  66. data/test/unit/logger_test.rb +72 -0
  67. data/test/unit/test_unit_test.rb +26 -0
  68. data/test/unit/working_env_test.rb +71 -0
  69. data/testdata/Rakefile +11 -0
  70. data/testdata/a_failed_test_case.rb +8 -0
  71. data/testdata/a_file_system_test_case.rb +8 -0
  72. data/testdata/a_test_case.rb +13 -0
  73. data/testdata/a_test_case2.rb +6 -0
  74. data/testdata/an_error_test_case.rb +9 -0
  75. data/testdata/another_project/Rakefile +6 -0
  76. data/testdata/another_project/passed_test_case.rb +7 -0
  77. data/testdata/hacked_run_method_test_case.rb +15 -0
  78. data/testdata/is_required_by_a_test.rb +9 -0
  79. data/testdata/lib/lib_test_case.rb +7 -0
  80. data/testdata/package_task_test_rakefile +8 -0
  81. data/testdata/raketasks/Rakefile +7 -0
  82. data/testdata/raketasks/success_test_case.rb +6 -0
  83. data/testdata/scenario_test_case.rb +34 -0
  84. data/testdata/setup_agent_env_test_case.rb +9 -0
  85. data/testdata/sleep_3_secs_test_case.rb +9 -0
  86. data/testdata/verify_dir_pwd/Rakefile +6 -0
  87. data/testdata/verify_dir_pwd/verify_dir_pwd_test_case.rb +10 -0
  88. metadata +101 -34
  89. data/README +0 -291
  90. data/install.rb +0 -88
  91. data/lib/dtr/base.rb +0 -172
  92. data/lib/dtr/runner.rb +0 -270
  93. data/lib/dtr/service_provider.rb +0 -160
@@ -0,0 +1,18 @@
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
+ require 'dtr/shared/sync_codebase/package'
16
+ require 'dtr/shared/sync_codebase/copiable_package'
17
+ require 'dtr/shared/sync_codebase/sync_service'
18
+ require 'dtr/shared/sync_codebase/master_ext'
@@ -0,0 +1,40 @@
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 SyncCodebase
17
+ class CopiablePackage
18
+ include DRbUndumped
19
+ include Package
20
+
21
+ CHUNK_SIZE = 1024*1024
22
+
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
30
+ remote_io.write(chunk)
31
+ end
32
+ end
33
+ end
34
+
35
+ def codebase_package
36
+ File.join(package_dir, package_file)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
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 SyncCodebase
17
+ # Inject synchronizing codebase ability into Master#with_dtr_master
18
+ # Packaging codebase by rake task dtr_repackage (See DTR::PackageTask)
19
+ module MasterExt
20
+ include Service::File
21
+
22
+ def self.included(base)
23
+ base.alias_method_chain :with_dtr_master, :sync_codebase
24
+ end
25
+
26
+ def with_dtr_master_with_sync_codebase(&block)
27
+ with_dtr_master_without_sync_codebase do
28
+ DTR.do_println("Packaging codebase")
29
+ raise 'Packaging for dtr task failed, see log for details!' unless Cmd.execute('rake dtr_repackage --trace')
30
+ begin
31
+ provide_file CopiablePackage.new
32
+ block.call
33
+ ensure
34
+ Cmd.execute('rake dtr_clobber_package --trace')
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -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 SyncCodebase
17
+ module Package
18
+ def package_dir
19
+ 'dtr_pkg'
20
+ end
21
+
22
+ def package_name
23
+ 'codebase-dump'
24
+ end
25
+
26
+ def package_dir_path
27
+ "#{package_dir}/#{package_name}"
28
+ end
29
+
30
+ def package_file
31
+ "#{package_name}.zip"
32
+ end
33
+
34
+ def package_copy_file
35
+ "copy_#{package_file}"
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
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,36 @@
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 SyncCodebase
17
+ module SyncService
18
+ include Package
19
+ include Service::File
20
+ def sync_codebase
21
+ DTR.info("Start sync codebase, clean #{File.join(Dir.pwd, package_name)}")
22
+ FileUtils.rm_rf(File.join(Dir.pwd, package_name))
23
+
24
+ DTR.info("Lookup codebase package file")
25
+ package = lookup_file
26
+ DTR.info("Receiving package file and writing to #{package_copy_file}")
27
+ File.open(package_copy_file, 'w') do |f|
28
+ package.copy_into(f)
29
+ end
30
+ do_work(unpackage_cmd)
31
+ DTR.info("sync codebase finished, clean #{package_copy_file}")
32
+ FileUtils.rm_f(package_copy_file)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,64 @@
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
+ require 'delegate'
16
+
17
+ module DTR
18
+ module SyncLogger
19
+ class UndumpedLogger
20
+ include DRbUndumped
21
+
22
+ def initialize(logger)
23
+ @logger = logger
24
+ end
25
+
26
+ def debug(message=nil, &block)
27
+ @logger.send(:debug, message, &block)
28
+ end
29
+
30
+ def info(message=nil, &block)
31
+ @logger.send(:info, message, &block)
32
+ end
33
+
34
+ def error(message=nil, &block)
35
+ @logger.send(:error, message, &block)
36
+ end
37
+
38
+ def datetime_format=(format)
39
+ @logger.datetime_format = format
40
+ end
41
+
42
+ def level=(level)
43
+ @logger.level = level
44
+ end
45
+
46
+ def level
47
+ @logger.level
48
+ end
49
+ end
50
+
51
+ module Provider
52
+ def self.included(base)
53
+ base.alias_method_chain :with_rinda_server, :providing_sync_logger
54
+ end
55
+
56
+ def with_rinda_server_with_providing_sync_logger(&block)
57
+ with_rinda_server_without_providing_sync_logger do
58
+ lookup_ring.write [:logger, UndumpedLogger.new(DTR.logger)]
59
+ block.call
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,17 @@
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
+ require 'dtr/shared/utils/logger'
16
+ require 'dtr/shared/utils/env_store'
17
+ require 'dtr/shared/utils/cmd'
@@ -0,0 +1,30 @@
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
+ class CmdInterrupt < StandardError; end
17
+
18
+ class Cmd
19
+ def self.execute(cmd)
20
+ return true if cmd.nil? || cmd.empty?
21
+ DTR.info {"Executing: #{cmd.inspect}"}
22
+ output = %x[#{cmd} 2>&1]
23
+ # don't put the following message into a block which maybe passed to remote process
24
+ status = $?.exitstatus
25
+ DTR.info {"Execution is done, status: #{status}"}
26
+ DTR.error "#{cmd.inspect} output:\n#{output}" if status != 0
27
+ $?.exitstatus == 0
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,60 @@
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
+ require 'pstore'
16
+
17
+ module DTR
18
+ class EnvStore
19
+ FILE_NAME = '.dtr_env_pstore' unless defined?(FILE_NAME)
20
+
21
+ def self.destroy
22
+ File.delete(FILE_NAME) if File.exist?(FILE_NAME)
23
+ end
24
+
25
+ def [](key)
26
+ return nil unless File.exist?(FILE_NAME)
27
+
28
+ repository = PStore.new(FILE_NAME)
29
+ repository.transaction(true) do
30
+ repository[key]
31
+ end
32
+ end
33
+
34
+ def []=(key, value)
35
+ repository = PStore.new(FILE_NAME)
36
+ repository.transaction do
37
+ repository[key] = value
38
+ end
39
+ end
40
+
41
+ def <<(key_value)
42
+ key, value = key_value
43
+ repository = PStore.new(FILE_NAME)
44
+ repository.transaction do
45
+ repository[key] = (repository[key] || []) << value
46
+ end
47
+ end
48
+
49
+ def shift(key)
50
+ repository = PStore.new(FILE_NAME)
51
+ repository.transaction do
52
+ if array = repository[key]
53
+ array.shift
54
+ repository[key] = array
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,87 @@
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
+ require 'logger'
16
+ require 'fileutils'
17
+
18
+ module DTR
19
+ module LoggerExt
20
+ DATETIME_FORMAT = "%m-%d %H:%M:%S"
21
+
22
+ LOGGER_LEVEL = {:info => Logger::INFO, :error => Logger::ERROR, :debug => Logger::DEBUG}
23
+
24
+ module OutputErrorIntoConsole
25
+ def self.included(base)
26
+ base.alias_method_chain :error, :output_into_console
27
+ end
28
+
29
+ def error_with_output_into_console(message = nil, &block)
30
+ $stderr.puts "\n" + format_message(format_severity(Logger::ERROR), Time.now, nil, message || block.call)
31
+ error_without_output_into_console(message, &block)
32
+ end
33
+ end
34
+ Logger.send(:include, OutputErrorIntoConsole)
35
+
36
+ def logger(file=nil)
37
+ @logger ||= create_default_logger(file)
38
+ end
39
+
40
+ def logger=(logger)
41
+ @logger = logger
42
+ end
43
+
44
+ def create_default_logger(file)
45
+ dir = 'log'
46
+ FileUtils.mkdir_p(dir)
47
+ log_file = File.join(dir, file || 'dtr.log')
48
+ do_println "DTR logfile at #{Dir.pwd}/#{log_file}"
49
+ logger = Logger.new(log_file, 1, 5*1024*1024)
50
+ logger.datetime_format = DATETIME_FORMAT
51
+ logger.level = (ENV['DTR_LOG_LEVEL'] || Logger::INFO).to_i
52
+ logger
53
+ end
54
+
55
+ def do_print(str)
56
+ unless ENV['DTR_ENV'] == 'test'
57
+ print str
58
+ end
59
+ end
60
+
61
+ def do_println(str)
62
+ do_print("#{str}\n")
63
+ end
64
+
65
+ def debug(message=nil, &block)
66
+ output(:debug, message, &block)
67
+ end
68
+
69
+ def info(message=nil, &block)
70
+ output(:info, message, &block)
71
+ end
72
+
73
+ def error(message=nil, &block)
74
+ output(:error, message, &block)
75
+ end
76
+
77
+ def output(level, msg=nil, &block)
78
+ return if LOGGER_LEVEL[level] < logger.level
79
+
80
+ msg = block.call if block_given?
81
+ # puts "log: #{msg}"
82
+ logger.send(level, msg)
83
+ end
84
+ end
85
+
86
+ extend LoggerExt
87
+ end