xli-dtr 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/CHANGES +21 -0
  2. data/README.rdoc +39 -28
  3. data/Rakefile +1 -1
  4. data/TODO +1 -3
  5. data/bin/dtr +20 -13
  6. data/dtr.gemspec +3 -3
  7. data/lib/dtr/agent/brain.rb +45 -19
  8. data/lib/dtr/agent/herald.rb +8 -10
  9. data/lib/dtr/agent/process_root.rb +23 -0
  10. data/lib/dtr/agent/rails_ext.rb +57 -0
  11. data/lib/dtr/agent/runner.rb +19 -39
  12. data/lib/dtr/agent/sync_codebase.rb +10 -19
  13. data/lib/dtr/agent/sync_logger.rb +1 -0
  14. data/lib/dtr/agent/worker.rb +13 -61
  15. data/lib/dtr/agent/working_env_ext.rb +51 -17
  16. data/lib/dtr/agent/working_status.rb +34 -0
  17. data/lib/dtr/agent.rb +12 -5
  18. data/lib/dtr/facade.rb +19 -17
  19. data/lib/dtr/master.rb +2 -0
  20. data/lib/dtr/monitor.rb +2 -2
  21. data/lib/dtr/raketasks.rb +14 -19
  22. data/lib/dtr/shared/adapter/base.rb +118 -0
  23. data/lib/dtr/shared/adapter/mortality.rb +41 -0
  24. data/lib/dtr/shared/adapter.rb +2 -101
  25. data/lib/dtr/shared/configuration.rb +32 -14
  26. data/lib/dtr/shared/root.rb +20 -0
  27. data/lib/dtr/shared/sync_codebase/master_ext.rb +2 -2
  28. data/lib/dtr/shared/sync_codebase/sync_service.rb +7 -4
  29. data/lib/dtr/shared/utils/cmd.rb +4 -2
  30. data/lib/dtr/shared/utils/env_store.rb +16 -24
  31. data/lib/dtr/shared/working_env.rb +8 -0
  32. data/lib/dtr/shared.rb +1 -0
  33. data/lib/dtr/test_unit/drb_test_runner.rb +1 -1
  34. data/lib/dtr/test_unit/thread_safe_test_result.rb +56 -3
  35. data/lib/dtr.rb +2 -2
  36. data/test/acceptance/dtr_package_task_test.rb +3 -3
  37. data/test/acceptance/general_test.rb +3 -3
  38. data/test/acceptance/rails_ext_test.rb +86 -0
  39. data/test/acceptance/raketasks_test.rb +14 -0
  40. data/test/acceptance/sync_codebase_test.rb +8 -31
  41. data/test/acceptance/sync_logger_test.rb +6 -3
  42. data/test/agent_helper.rb +24 -16
  43. data/test/logger_stub.rb +3 -3
  44. data/test/test_helper.rb +12 -9
  45. data/test/unit/adapter_test.rb +1 -1
  46. data/test/unit/configuration_test.rb +36 -4
  47. data/test/unit/database_initializer_test.rb +36 -0
  48. data/test/unit/facade_test.rb +11 -1
  49. data/test/unit/thread_safe_test_result_test.rb +41 -0
  50. data/test/unit/working_env_test.rb +11 -21
  51. data/testdata/rails_projects/simple_project/README +256 -0
  52. data/testdata/rails_projects/simple_project/Rakefile +10 -0
  53. data/testdata/rails_projects/simple_project/app/controllers/application.rb +15 -0
  54. data/testdata/rails_projects/simple_project/app/controllers/products_controller.rb +5 -0
  55. data/testdata/rails_projects/simple_project/app/helpers/application_helper.rb +3 -0
  56. data/testdata/rails_projects/simple_project/app/helpers/products_helper.rb +2 -0
  57. data/testdata/rails_projects/simple_project/app/models/product.rb +5 -0
  58. data/testdata/rails_projects/simple_project/app/views/products/index.rhtml +7 -0
  59. data/testdata/rails_projects/simple_project/config/boot.rb +109 -0
  60. data/testdata/rails_projects/simple_project/config/database.yml +19 -0
  61. data/testdata/rails_projects/simple_project/config/database.yml.mysql +12 -0
  62. data/testdata/rails_projects/simple_project/config/environment.rb +67 -0
  63. data/testdata/rails_projects/simple_project/config/environments/development.rb +17 -0
  64. data/testdata/rails_projects/simple_project/config/environments/production.rb +22 -0
  65. data/testdata/rails_projects/simple_project/config/environments/test.rb +22 -0
  66. data/testdata/rails_projects/simple_project/config/initializers/inflections.rb +10 -0
  67. data/testdata/rails_projects/simple_project/config/initializers/mime_types.rb +5 -0
  68. data/testdata/rails_projects/simple_project/config/initializers/new_rails_defaults.rb +17 -0
  69. data/testdata/rails_projects/simple_project/config/routes.rb +43 -0
  70. data/testdata/rails_projects/simple_project/db/migrate/20081027133744_create_products.rb +13 -0
  71. data/testdata/rails_projects/simple_project/db/schema.rb +21 -0
  72. data/testdata/rails_projects/simple_project/doc/README_FOR_APP +2 -0
  73. data/testdata/rails_projects/simple_project/public/404.html +30 -0
  74. data/testdata/rails_projects/simple_project/public/422.html +30 -0
  75. data/testdata/rails_projects/simple_project/public/500.html +30 -0
  76. data/testdata/rails_projects/simple_project/public/dispatch.cgi +10 -0
  77. data/testdata/rails_projects/simple_project/public/dispatch.fcgi +24 -0
  78. data/testdata/rails_projects/simple_project/public/dispatch.rb +10 -0
  79. data/testdata/rails_projects/simple_project/public/favicon.ico +0 -0
  80. data/testdata/rails_projects/simple_project/public/images/rails.png +0 -0
  81. data/testdata/rails_projects/simple_project/public/index.html +274 -0
  82. data/testdata/rails_projects/simple_project/public/javascripts/application.js +2 -0
  83. data/testdata/rails_projects/simple_project/public/javascripts/controls.js +963 -0
  84. data/testdata/rails_projects/simple_project/public/javascripts/dragdrop.js +972 -0
  85. data/testdata/rails_projects/simple_project/public/javascripts/effects.js +1120 -0
  86. data/testdata/rails_projects/simple_project/public/javascripts/prototype.js +4225 -0
  87. data/testdata/rails_projects/simple_project/public/robots.txt +5 -0
  88. data/testdata/rails_projects/simple_project/script/about +4 -0
  89. data/testdata/rails_projects/simple_project/script/console +3 -0
  90. data/testdata/rails_projects/simple_project/script/dbconsole +3 -0
  91. data/testdata/rails_projects/simple_project/script/destroy +3 -0
  92. data/testdata/rails_projects/simple_project/script/generate +3 -0
  93. data/testdata/rails_projects/simple_project/script/performance/benchmarker +3 -0
  94. data/testdata/rails_projects/simple_project/script/performance/profiler +3 -0
  95. data/testdata/rails_projects/simple_project/script/performance/request +3 -0
  96. data/testdata/rails_projects/simple_project/script/plugin +3 -0
  97. data/testdata/rails_projects/simple_project/script/process/inspector +3 -0
  98. data/testdata/rails_projects/simple_project/script/process/reaper +3 -0
  99. data/testdata/rails_projects/simple_project/script/process/spawner +3 -0
  100. data/testdata/rails_projects/simple_project/script/runner +3 -0
  101. data/testdata/rails_projects/simple_project/script/server +3 -0
  102. data/testdata/rails_projects/simple_project/test/fixtures/products.yml +9 -0
  103. data/testdata/rails_projects/simple_project/test/functional/products_controller_test.rb +11 -0
  104. data/testdata/rails_projects/simple_project/test/test_helper.rb +38 -0
  105. data/testdata/rails_projects/simple_project/test/unit/product_test.rb +27 -0
  106. data/testdata/raketasks/Rakefile +1 -1
  107. metadata +90 -4
  108. data/testdata/verify_dir_pwd/Rakefile +0 -6
  109. data/testdata/verify_dir_pwd/verify_dir_pwd_test_case.rb +0 -10
data/CHANGES CHANGED
@@ -1,5 +1,26 @@
1
1
  = DTR Changelog
2
2
 
3
+ == release 1.1.0
4
+ * Provided new setup test environment strategy for supporting running tests in multi-processes on one machine.
5
+ * DTR used to run setup agent environment command before runners started in same directory with runners.
6
+ * New version split runners into different directory to run test. And run setup agent command after runner started.
7
+ * Run 'rake db:drop db:create db:test:prepare' for runner to setup database environment before runner runs any test, when there is no agent setup environment command setted and there is 'config/database.yml.dtr' or 'config/database.yml' exists. If './config/database.yml.dtr' specified, it would be copy as ./config/database.yml for setup database. For Sqlite, there is no need to create a './config/database.yml.dtr' for dtr test task. The following is an example for mysql:
8
+ development:
9
+ database: development_<%= ENV['DTR_RUNNER_NAME'] %>
10
+ adapter: mysql
11
+ username: root
12
+ password:
13
+ host: localhost
14
+ test:
15
+ database: test_<%= ENV['DTR_RUNNER_NAME'] %>
16
+ adapter: mysql
17
+ username: root
18
+ password:
19
+ host: localhost
20
+ * Moved all DTR options into configuration file '.dtr_env_pstore', including runners, agent environment setup command and working_env.
21
+ * Removed dependence of Process.fork, so that agent works OS independent.
22
+ * Output agent runners stats info after all test finished.
23
+
3
24
  == release 1.0.0
4
25
  * support synchronizing codebase
5
26
  * lookup agents by broadcast
data/README.rdoc CHANGED
@@ -18,11 +18,12 @@ DTR has the following features:
18
18
 
19
19
  DTR works in two parts: Runner Agent and DTR Master.
20
20
 
21
- * Runner Agent is a DRb service hosting on distributed machines to run tests. For using 'fork' to create runner process, Runner Agent can't run on Windows directly. Requisites for running agent: Unix/Linux based OS System for forking sub-process; 'unzip' command for extracting codebase package.
21
+ * Runner Agent is a DRb service hosting on distributed machines to run tests.
22
+ Requisites for running agent: 'unzip' command for extracting codebase package.
22
23
 
23
24
  * DTR Master is the process finding runner service to run tests and collect test results. It works by loading 'dtr/test_unit_injection.rb' with all test files or defining a DTR::TestTask in your rake file. Requisites for running master: 'zip' command for creating codebase package.
24
25
 
25
- DTR (version >= 1.0.0) supports synchronizing codebase by a DTR::PackageTask defined in your rake tasks. The DTR::PackageTask is a similar task with Rake::PackageTask, the following is a simple example:
26
+ DTR (version >= 1.0.0) supports synchronizing codebase by a DTR::PackageTask defined in your rake tasks without any namespace. The DTR::PackageTask is a similar task with Rake::PackageTask, the following is a simple example:
26
27
 
27
28
  require 'dtr/raketasks'
28
29
  DTR::PackageTask.new do |p|
@@ -45,7 +46,11 @@ Note: Exclude('log/*') only excludes all files inside 'log' directory except 'lo
45
46
 
46
47
  == Rails plugin
47
48
 
48
- For Rails project, you just need copy dtr project directory into your project plugins directory. There are dtr tasks defined for you to run tests within dtr grid, which prefer you have 'config/database.yml.dtr' for setting up database. The test task is 'dtr:test'.
49
+ For Rails project, you can install dtr for your project by the following script:
50
+
51
+ ./script/plugin install git://github.com/xli/dtr.git
52
+
53
+ There are dtr tasks defined for you to run tests within dtr grid. The test task is named 'dtr:test'. The default dtr package task is very simple, for large project you may need to custom it to decreasing time of synchronizing codebase.
49
54
 
50
55
  Your project directory name would be the default group name of dtr agents. You can specify an environment variable named 'DTR_GROUP' to change the group name. By default, dtr tasks would lookup the broadcast ip by 'ifconfig' command. If it doesn't work for you, you can specify an environment variable named 'BROADCAST_IP' to overwrite it.
51
56
 
@@ -72,6 +77,10 @@ Run the following if you haven't already:
72
77
  Install the gem:
73
78
 
74
79
  sudo gem install xli-dtr
80
+
81
+ == Documentation
82
+
83
+ http://dtr.rubyforge.org/
75
84
 
76
85
  == Running the DTR Test Suite
77
86
 
@@ -84,28 +93,30 @@ If you wish to run the unit and functional tests that come with DTR:
84
93
 
85
94
  == Simple Example
86
95
 
87
- Start DTR agent with providing 1 runner in group 'mysql-firefox' as follows:
96
+ Start DTR agent with providing 1 runner in group 'my_project_name' as follows:
88
97
 
89
- dtr -r runner1 -g mysql-firefox
98
+ dtr -r runner1 -g my_project_name
90
99
 
91
100
  Type "dtr --help" for an up-to-date option summary.
92
- Invoking <tt>dtr</tt> without any options causes dtr to show help too.
101
+ DTR stored your configuration automatically, and configurations would be picked up
102
+ automatically next time you start dtr.
93
103
 
94
- Most of time your project test suite need setup environment before run tests, you
95
- can set setup command by option '--setup', for example:
104
+ DTR supports Rails test environment setup, so you don't need to configure it unless
105
+ your test environment setup is different with Rails project default command. You can
106
+ setup environment as you need by option '--setup', for example:
96
107
 
97
108
  dtr -r runner1,runner2 --setup "rake db:test:prepare"
98
109
 
99
- You also can specify DTR_AGENT_ENV_SETUP_CMD in your master process environment to let all agents
100
- that are not started with '--setup' option specified to setup all agents environment.
101
-
102
- At last, you need define a DTR::TestTask:
110
+ If you installed dtr as your Rails project plugin, you don't need the following steps.
111
+ Otherwise, you need define a DTR::TestTask in your rake file:
103
112
 
104
- require 'dtr'
113
+ require 'dtr/raketasks'
105
114
 
106
- ENV['DTR_AGENT_ENV_SETUP_CMD'] = 'rake db:test:prepare'
115
+ # Uncomment the following code to specify DTR_AGENT_ENV_SETUP_CMD here to get all agents
116
+ # that are not started with '--setup' option specified to setup test environment.
117
+ # ENV['DTR_AGENT_ENV_SETUP_CMD'] = 'rake db:test:prepare'
107
118
  DTR.broadcast_list = ['broadcast_ip']
108
- DTR.group = 'mysql-firefox'
119
+ DTR.group = 'my_project_name'
109
120
 
110
121
  DTR::TestTask.new do |t|
111
122
  t.test_files = FileList['test/**/*_test.rb']
@@ -126,12 +137,13 @@ More details about DTR::TestTask and DTR::PackageTask, see the API doc:
126
137
  ri DTR::PackageTask
127
138
 
128
139
  Notes:
129
- * DTR broadcast_list and group configuration would be cached in the directory. Name of configuration file is '.dtr_env_pstore'.
130
- * For packaging codebase, DTR::PackageTask creates tasks: dtr_package, dtr_clobber_package and dtr_repackage; DTR Master just simply run a command 'rake dtr_repackage' to create the package and run 'rake dtr_clobber_package' to clean package. So make sure there are those tasks under root namespace in your rake tasks.
140
+
141
+ * DTR broadcast_list and group configuration would be cached in the directory. Name of configuration file is '.dtr_env_pstore'.
142
+ * For packaging codebase, DTR::PackageTask creates tasks: dtr_package, dtr_clobber_package and dtr_repackage; DTR Master just simply run a command 'rake dtr_repackage' to create the package and run 'rake dtr_clobber_package' to clean package. So make sure there are those tasks under root namespace in your rake tasks.
131
143
 
132
144
  == Run tests in multi-processes on one machine
133
145
 
134
- For running Runner in multi-processes.
146
+ For running agent runners in multi-processes with Master process on same machine and quit with Master process.
135
147
  The following is the test task example in the rake file:
136
148
 
137
149
  require 'dtr/raketasks'
@@ -173,20 +185,19 @@ DTR agent command is invoked from the command line using:
173
185
  -r runner1_name,runner2_name Start DTR test runner agent with unique runner names.
174
186
  -a, --broadcast_address ADDRESS Specify broadcast address for looking up dtr agent service, e.g. 192.168.255.255. Default is 'localhost'. DTR master and monitor would need this.
175
187
  -i, --setup COMMAND Set command for initializing test runner test environment, e.g. 'rake db:test:prepare'. Default is do nothing. You also can specify DTR_AGENT_ENV_SETUP_CMD in your master process environment to let all agents setup same environment.
176
- -d DIRECTORY Specify a directory as agent launching & working directory.
177
- --working_directory
178
188
  -m, --monitor Monitor the status of the dtr agents and master processes. Used for testing your dtr grid environment. CAUTION! monitoring agents causes all idle agents hang on by the monitor process.
179
189
  -v, --version Show version
180
190
  -h, --help Show this help doc
181
191
 
182
- Notes:
183
- * DTR would always add 'localhost' into broadcast list.
184
- * Agent start by specifying runners by -r option, every runner would be started in different process for running test. e.g. dtr -r runner1,runner2
185
- * DTR master environment options:
186
- * DTR_MASTER_ENV: this variable would be copied into agent process for sharing info between master and agents. Normally used in agent setup environment command.
187
- * DTR_AGENT_ENV_SETUP_CMD: this variable would be applied as agent setup environment command when agent have no setup environment command specified by --setup option.
188
- * DTR_LOG_LEVEL: master process logger level, e.g. ENV['DTR_LOG_LEVEL'] = Logger::DEBUG. Agent process logs would be output in master process log file, so setting this option also changes agent logger level.
189
- * DTR_RUNNER_NAME: this environment variable would be provided in runner process for test environment to get the runner name to setup, e.g. setting up database configuration.
192
+ Notes:
193
+
194
+ * DTR would always add 'localhost' into broadcast list.
195
+ * Agent start by specifying runners by -r option, every runner would be started in different process for running test. e.g. dtr -r runner1,runner2
196
+ * DTR master environment options:
197
+ * DTR_MASTER_ENV: this variable would be copied into agent process for sharing info between master and agents. Normally used in agent setup environment command.
198
+ * DTR_AGENT_ENV_SETUP_CMD: this variable would be applied as agent setup environment command when agent have no setup environment command specified by --setup option.
199
+ * DTR_LOG_LEVEL: master process logger level, e.g. ENV['DTR_LOG_LEVEL'] = Logger::DEBUG. Agent process logs would be output in master process log file, so setting this option also changes agent logger level.
200
+ * DTR_RUNNER_NAME: this environment variable would be provided in runner process for test environment to get the runner name, e.g. setting up database configuration.
190
201
 
191
202
  Type "dtr --help" for an up-to-date option summary.
192
203
 
data/Rakefile CHANGED
@@ -101,7 +101,7 @@ else
101
101
  gem_content = <<-GEM
102
102
  Gem::Specification.new do |spec|
103
103
  spec.name = 'dtr'
104
- spec.version = "1.0.0"
104
+ spec.version = "1.1.0"
105
105
  spec.summary = "DTR is a distributed test runner to run tests on distributed computers for decreasing build time."
106
106
 
107
107
  #### Dependencies and requirements.
data/TODO CHANGED
@@ -3,12 +3,10 @@
3
3
  Send suggestions for this list to iam@li-xiao.com
4
4
 
5
5
  === To Do
6
+ Add teardown command for agent runners to run after all test finished and before runner quits. This and setup test environment command features provide ability to start & stop selenium proxy server, or start & stop test server.
6
7
 
7
8
  === TBD for next release
8
9
  should trigger started notification on test runner in agent Herald, for some tools are using this hook(e.g. inbrowser_test) to setup test environment.
9
10
  agent should wakeup when worker is dead, so that it could be picked up by another master process
10
- auto prepare database for each runner, so that run tests in multi-processes could be easy setup.
11
- provide a way to monitor agent runner efficiency
12
- use system instead of fork to launch sub process in agent, which makes dtr support windows and jruby
13
11
 
14
12
  (moved DONE list to CHANGES file)
data/bin/dtr CHANGED
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'optparse'
3
- require 'logger'
3
+
4
+ #add lib for test environment
5
+ if File.exists?(File.expand_path(File.dirname(__FILE__) + '/../lib/dtr.rb'))
6
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
7
+ end
8
+
4
9
  begin
5
10
  require 'dtr'
6
11
  rescue LoadError
@@ -17,7 +22,7 @@ Notes:
17
22
  * DTR_MASTER_ENV: this variable would be copied into agent process for sharing info between master and agents. Normally used in agent setup environment command.
18
23
  * DTR_AGENT_ENV_SETUP_CMD: this variable would be applied as agent setup environment command when agent have no setup environment command specified by --setup option.
19
24
  * DTR_LOG_LEVEL: master process logger level, e.g. ENV['DTR_LOG_LEVEL'] = Logger::DEBUG. Agent process logs would be output in master process log file, so setting this option also changes agent logger level.
20
- * DTR_RUNNER_NAME: this environment variable would be provided in runner process for test environment to get the runner name to setup, e.g. setting up database configuration.
25
+ * DTR_RUNNER_NAME: this environment variable would be provided in runner process for test environment to get the runner name, e.g. setting up database configuration.
21
26
 
22
27
  DTR is a distributed test runner program for decreasing time of running ruby tests based on ruby 'test/unit' package.
23
28
  For additional information, see http://dtr.rubyforge.org/
@@ -45,7 +50,7 @@ opts = OptionParser.new do |opts|
45
50
  end
46
51
 
47
52
  opts.on("-r runner1_name,runner2_name", Array, "Start DTR test runner agent with unique runner names.") do |names|
48
- DTR_AGENT_OPTIONS[:runners] = names.collect{|name| name.untaint}
53
+ DTR.agent_runners = names.collect{|name| name.untaint}
49
54
  end
50
55
 
51
56
  opts.on("-a", "--broadcast_address ADDRESS", "Specify broadcast address for looking up dtr agent service, e.g. 192.168.255.255. Default is 'localhost'. DTR master and monitor would need this.") do |address|
@@ -55,20 +60,22 @@ opts = OptionParser.new do |opts|
55
60
  end
56
61
 
57
62
  opts.on("-i", "--setup COMMAND", "Set command for initializing test runner test environment, e.g. 'rake db:test:prepare'. Default is do nothing. You also can specify DTR_AGENT_ENV_SETUP_CMD in your master process environment to let all agents setup same environment.") do |command|
58
- DTR_AGENT_OPTIONS[:agent_env_setup_cmd] = command.untaint
63
+ DTR.agent_env_setup_cmd = command.untaint
59
64
  end
60
65
 
61
- opts.on("-d", "--working_directory DIRECTORY", "Specify a directory as agent launching & working directory.") do |dir|
62
- DTR_AGENT_OPTIONS[:launching_dir] = dir
66
+ opts.on("-e", "--execute RUBY_SCRIPT", "Execute a ruby script with 'dtr/agent' loaded.") do |script|
67
+ $agent_script = script
63
68
  end
64
-
69
+
65
70
  opts.on_tail("-v", "--version", "Show version") do
66
71
  puts "dtr, version " + DTRVERSION
72
+ exit
67
73
  end
68
74
 
69
75
  opts.on_tail("-h", "--help", "Show this help doc") do
70
76
  puts opts
71
77
  puts NOTES
78
+ exit
72
79
  end
73
80
  end
74
81
 
@@ -81,11 +88,11 @@ if no_argv
81
88
  puts NOTES
82
89
  end
83
90
 
84
- if $monitor
91
+ if defined?($monitor)
85
92
  DTR.monitor
86
- end
87
- if DTR_AGENT_OPTIONS[:runners] && !DTR_AGENT_OPTIONS[:runners].empty?
88
- Dir.chdir(DTR_AGENT_OPTIONS[:launching_dir] || '.') do
89
- DTR.start_agent
90
- end
93
+ elsif defined?($agent_script)
94
+ require 'dtr/agent'
95
+ eval($agent_script)
96
+ elsif DTR.agent_runners && !DTR.agent_runners.empty?
97
+ DTR.start_agent
91
98
  end
data/dtr.gemspec CHANGED
@@ -1,12 +1,12 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'dtr'
3
- spec.version = "1.0.0"
3
+ spec.version = "1.1.0"
4
4
  spec.summary = "DTR is a distributed test runner to run tests on distributed computers for decreasing build time."
5
5
 
6
6
  #### Dependencies and requirements.
7
- spec.files = ["lib/dtr/agent/brain.rb", "lib/dtr/agent/herald.rb", "lib/dtr/agent/runner.rb", "lib/dtr/agent/sync_codebase.rb", "lib/dtr/agent/sync_logger.rb", "lib/dtr/agent/test_case.rb", "lib/dtr/agent/test_unit.rb", "lib/dtr/agent/worker.rb", "lib/dtr/agent/working_env_ext.rb", "lib/dtr/agent.rb", "lib/dtr/facade.rb", "lib/dtr/master.rb", "lib/dtr/monitor.rb", "lib/dtr/raketasks.rb", "lib/dtr/shared/adapter.rb", "lib/dtr/shared/configuration.rb", "lib/dtr/shared/message_decorator.rb", "lib/dtr/shared/ruby_ext.rb", "lib/dtr/shared/service/agent.rb", "lib/dtr/shared/service/file.rb", "lib/dtr/shared/service/rinda.rb", "lib/dtr/shared/service/runner.rb", "lib/dtr/shared/service/working_env.rb", "lib/dtr/shared/service.rb", "lib/dtr/shared/sync_codebase/copiable_package.rb", "lib/dtr/shared/sync_codebase/master_ext.rb", "lib/dtr/shared/sync_codebase/package.rb", "lib/dtr/shared/sync_codebase/sync_service.rb", "lib/dtr/shared/sync_codebase.rb", "lib/dtr/shared/sync_logger.rb", "lib/dtr/shared/utils/cmd.rb", "lib/dtr/shared/utils/env_store.rb", "lib/dtr/shared/utils/logger.rb", "lib/dtr/shared/utils.rb", "lib/dtr/shared/working_env.rb", "lib/dtr/shared.rb", "lib/dtr/test_unit/drb_test_runner.rb", "lib/dtr/test_unit/injection.rb", "lib/dtr/test_unit/test_case_injection.rb", "lib/dtr/test_unit/test_suite_injection.rb", "lib/dtr/test_unit/testrunnermediator_injection.rb", "lib/dtr/test_unit/thread_safe_test_result.rb", "lib/dtr/test_unit/worker_club.rb", "lib/dtr/test_unit.rb", "lib/dtr/test_unit_injection.rb", "lib/dtr.rb", "bin/dtr", "CHANGES", "dtr.gemspec", "lib", "LICENSE.TXT", "Rakefile", "README.rdoc", "TODO"]
7
+ spec.files = ["lib/dtr/agent/brain.rb", "lib/dtr/agent/herald.rb", "lib/dtr/agent/process_root.rb", "lib/dtr/agent/rails_ext.rb", "lib/dtr/agent/runner.rb", "lib/dtr/agent/sync_codebase.rb", "lib/dtr/agent/sync_logger.rb", "lib/dtr/agent/test_case.rb", "lib/dtr/agent/test_unit.rb", "lib/dtr/agent/worker.rb", "lib/dtr/agent/working_env_ext.rb", "lib/dtr/agent/working_status.rb", "lib/dtr/agent.rb", "lib/dtr/facade.rb", "lib/dtr/master.rb", "lib/dtr/monitor.rb", "lib/dtr/raketasks.rb", "lib/dtr/shared/adapter/base.rb", "lib/dtr/shared/adapter/mortality.rb", "lib/dtr/shared/adapter.rb", "lib/dtr/shared/configuration.rb", "lib/dtr/shared/message_decorator.rb", "lib/dtr/shared/root.rb", "lib/dtr/shared/ruby_ext.rb", "lib/dtr/shared/service/agent.rb", "lib/dtr/shared/service/file.rb", "lib/dtr/shared/service/rinda.rb", "lib/dtr/shared/service/runner.rb", "lib/dtr/shared/service/working_env.rb", "lib/dtr/shared/service.rb", "lib/dtr/shared/sync_codebase/copiable_package.rb", "lib/dtr/shared/sync_codebase/master_ext.rb", "lib/dtr/shared/sync_codebase/package.rb", "lib/dtr/shared/sync_codebase/sync_service.rb", "lib/dtr/shared/sync_codebase.rb", "lib/dtr/shared/sync_logger.rb", "lib/dtr/shared/utils/cmd.rb", "lib/dtr/shared/utils/env_store.rb", "lib/dtr/shared/utils/logger.rb", "lib/dtr/shared/utils.rb", "lib/dtr/shared/working_env.rb", "lib/dtr/shared.rb", "lib/dtr/test_unit/drb_test_runner.rb", "lib/dtr/test_unit/injection.rb", "lib/dtr/test_unit/test_case_injection.rb", "lib/dtr/test_unit/test_suite_injection.rb", "lib/dtr/test_unit/testrunnermediator_injection.rb", "lib/dtr/test_unit/thread_safe_test_result.rb", "lib/dtr/test_unit/worker_club.rb", "lib/dtr/test_unit.rb", "lib/dtr/test_unit_injection.rb", "lib/dtr.rb", "bin/dtr", "CHANGES", "dtr.gemspec", "lib", "LICENSE.TXT", "Rakefile", "README.rdoc", "TODO"]
8
8
 
9
- spec.test_files = ["test/acceptance/agent_working_env_test.rb", "test/acceptance/dtr_package_task_test.rb", "test/acceptance/general_test.rb", "test/acceptance/raketasks_test.rb", "test/acceptance/sync_codebase_test.rb", "test/acceptance/sync_logger_test.rb", "test/agent_helper.rb", "test/logger_stub.rb", "test/test_helper.rb", "test/unit/adapter_test.rb", "test/unit/configuration_test.rb", "test/unit/facade_test.rb", "test/unit/logger_test.rb", "test/unit/test_unit_test.rb", "test/unit/working_env_test.rb", "testdata/a_failed_test_case.rb", "testdata/a_file_system_test_case.rb", "testdata/a_test_case.rb", "testdata/a_test_case2.rb", "testdata/an_error_test_case.rb", "testdata/another_project", "testdata/another_project/passed_test_case.rb", "testdata/another_project/Rakefile", "testdata/hacked_run_method_test_case.rb", "testdata/is_required_by_a_test.rb", "testdata/lib", "testdata/lib/lib_test_case.rb", "testdata/package_task_test_rakefile", "testdata/Rakefile", "testdata/raketasks", "testdata/raketasks/Rakefile", "testdata/raketasks/success_test_case.rb", "testdata/scenario_test_case.rb", "testdata/setup_agent_env_test_case.rb", "testdata/sleep_3_secs_test_case.rb", "testdata/verify_dir_pwd", "testdata/verify_dir_pwd/Rakefile", "testdata/verify_dir_pwd/verify_dir_pwd_test_case.rb"]
9
+ spec.test_files = ["test/acceptance/agent_working_env_test.rb", "test/acceptance/dtr_package_task_test.rb", "test/acceptance/general_test.rb", "test/acceptance/rails_ext_test.rb", "test/acceptance/raketasks_test.rb", "test/acceptance/sync_codebase_test.rb", "test/acceptance/sync_logger_test.rb", "test/agent_helper.rb", "test/logger_stub.rb", "test/test_helper.rb", "test/unit/adapter_test.rb", "test/unit/configuration_test.rb", "test/unit/database_initializer_test.rb", "test/unit/facade_test.rb", "test/unit/logger_test.rb", "test/unit/test_unit_test.rb", "test/unit/thread_safe_test_result_test.rb", "test/unit/working_env_test.rb", "testdata/a_failed_test_case.rb", "testdata/a_file_system_test_case.rb", "testdata/a_test_case.rb", "testdata/a_test_case2.rb", "testdata/an_error_test_case.rb", "testdata/another_project", "testdata/another_project/passed_test_case.rb", "testdata/another_project/Rakefile", "testdata/hacked_run_method_test_case.rb", "testdata/is_required_by_a_test.rb", "testdata/lib", "testdata/lib/lib_test_case.rb", "testdata/package_task_test_rakefile", "testdata/rails_projects", "testdata/rails_projects/simple_project", "testdata/rails_projects/simple_project/app", "testdata/rails_projects/simple_project/app/controllers", "testdata/rails_projects/simple_project/app/controllers/application.rb", "testdata/rails_projects/simple_project/app/controllers/products_controller.rb", "testdata/rails_projects/simple_project/app/helpers", "testdata/rails_projects/simple_project/app/helpers/application_helper.rb", "testdata/rails_projects/simple_project/app/helpers/products_helper.rb", "testdata/rails_projects/simple_project/app/models", "testdata/rails_projects/simple_project/app/models/product.rb", "testdata/rails_projects/simple_project/app/views", "testdata/rails_projects/simple_project/app/views/products", "testdata/rails_projects/simple_project/app/views/products/index.rhtml", "testdata/rails_projects/simple_project/config", "testdata/rails_projects/simple_project/config/boot.rb", "testdata/rails_projects/simple_project/config/database.yml", "testdata/rails_projects/simple_project/config/database.yml.mysql", "testdata/rails_projects/simple_project/config/environment.rb", "testdata/rails_projects/simple_project/config/environments", "testdata/rails_projects/simple_project/config/environments/development.rb", "testdata/rails_projects/simple_project/config/environments/production.rb", "testdata/rails_projects/simple_project/config/environments/test.rb", "testdata/rails_projects/simple_project/config/initializers", "testdata/rails_projects/simple_project/config/initializers/inflections.rb", "testdata/rails_projects/simple_project/config/initializers/mime_types.rb", "testdata/rails_projects/simple_project/config/initializers/new_rails_defaults.rb", "testdata/rails_projects/simple_project/config/routes.rb", "testdata/rails_projects/simple_project/db", "testdata/rails_projects/simple_project/db/migrate", "testdata/rails_projects/simple_project/db/migrate/20081027133744_create_products.rb", "testdata/rails_projects/simple_project/db/schema.rb", "testdata/rails_projects/simple_project/doc", "testdata/rails_projects/simple_project/doc/README_FOR_APP", "testdata/rails_projects/simple_project/public", "testdata/rails_projects/simple_project/public/404.html", "testdata/rails_projects/simple_project/public/422.html", "testdata/rails_projects/simple_project/public/500.html", "testdata/rails_projects/simple_project/public/dispatch.cgi", "testdata/rails_projects/simple_project/public/dispatch.fcgi", "testdata/rails_projects/simple_project/public/dispatch.rb", "testdata/rails_projects/simple_project/public/favicon.ico", "testdata/rails_projects/simple_project/public/images", "testdata/rails_projects/simple_project/public/images/rails.png", "testdata/rails_projects/simple_project/public/index.html", "testdata/rails_projects/simple_project/public/javascripts", "testdata/rails_projects/simple_project/public/javascripts/application.js", "testdata/rails_projects/simple_project/public/javascripts/controls.js", "testdata/rails_projects/simple_project/public/javascripts/dragdrop.js", "testdata/rails_projects/simple_project/public/javascripts/effects.js", "testdata/rails_projects/simple_project/public/javascripts/prototype.js", "testdata/rails_projects/simple_project/public/robots.txt", "testdata/rails_projects/simple_project/Rakefile", "testdata/rails_projects/simple_project/README", "testdata/rails_projects/simple_project/script", "testdata/rails_projects/simple_project/script/about", "testdata/rails_projects/simple_project/script/console", "testdata/rails_projects/simple_project/script/dbconsole", "testdata/rails_projects/simple_project/script/destroy", "testdata/rails_projects/simple_project/script/generate", "testdata/rails_projects/simple_project/script/performance", "testdata/rails_projects/simple_project/script/performance/benchmarker", "testdata/rails_projects/simple_project/script/performance/profiler", "testdata/rails_projects/simple_project/script/performance/request", "testdata/rails_projects/simple_project/script/plugin", "testdata/rails_projects/simple_project/script/process", "testdata/rails_projects/simple_project/script/process/inspector", "testdata/rails_projects/simple_project/script/process/reaper", "testdata/rails_projects/simple_project/script/process/spawner", "testdata/rails_projects/simple_project/script/runner", "testdata/rails_projects/simple_project/script/server", "testdata/rails_projects/simple_project/test", "testdata/rails_projects/simple_project/test/fixtures", "testdata/rails_projects/simple_project/test/fixtures/products.yml", "testdata/rails_projects/simple_project/test/functional", "testdata/rails_projects/simple_project/test/functional/products_controller_test.rb", "testdata/rails_projects/simple_project/test/test_helper.rb", "testdata/rails_projects/simple_project/test/unit", "testdata/rails_projects/simple_project/test/unit/product_test.rb", "testdata/Rakefile", "testdata/raketasks", "testdata/raketasks/Rakefile", "testdata/raketasks/success_test_case.rb", "testdata/scenario_test_case.rb", "testdata/setup_agent_env_test_case.rb", "testdata/sleep_3_secs_test_case.rb", "testdata/verify_dir_pwd"]
10
10
 
11
11
  #### Load-time details: library and application (you will need one or both).
12
12
 
@@ -15,42 +15,68 @@
15
15
  module DTR
16
16
  module Agent
17
17
 
18
- class Brain
18
+ class Brain < ProcessRoot
19
19
  include Adapter::Follower
20
20
 
21
- def initialize(runner_names, agent_env_setup_cmd)
22
- raise 'No runner? What can I do for you?' if runner_names.blank?
23
- @runner_names = runner_names
24
- @agent_env_setup_cmd = agent_env_setup_cmd
21
+ def initialize
22
+ super
23
+ raise 'No runner? What can I do for you?' if DTR.configuration.agent_runners.blank?
25
24
  DTR.info {""}
26
25
  DTR.info {"--------------------beautiful line--------------------------"}
27
- DTR.info {"=> Agent environment setup command: #{@agent_env_setup_cmd}"}
28
- DTR.info {"=> Runner names: #{@runner_names.join(', ')}"}
29
- DTR.info {"=> Broadcast list: #{DTR.configuration.broadcast_list.inspect}"}
26
+ DTR.info {"=> Agent environment setup command: #{DTR.configuration.agent_env_setup_cmd}"}
27
+ DTR.info {"=> Runners: #{DTR.configuration.agent_runners.join(', ')}"}
30
28
  DTR.info {"=> Listening port: #{DTR.configuration.agent_listen_port}"}
31
29
  DTR.info {"=> Group: #{DTR.configuration.group}"}
30
+ DTR.info {"=> Dir.pwd: #{Dir.pwd}"}
31
+ DTR.info {"=> Follower listen heartbeat timeout: #{DTR.configuration.follower_listen_heartbeat_timeout}"}
32
32
  end
33
33
 
34
34
  def hypnotize
35
- loop do
36
- if wakeup?
37
- DTR.info {"Agent brain wakes up"}
38
- work(DTR.fork_process { Worker.new(@runner_names, @agent_env_setup_cmd).launch })
39
- DTR.info {"Agent brain is going to sleep"}
35
+ with_relaxation do
36
+ loop do
37
+ do_once
40
38
  end
41
39
  end
40
+ end
41
+
42
+ def hypnotize_once
43
+ with_relaxation do
44
+ do_once
45
+ end
46
+ end
47
+
48
+ private
49
+ def do_once
50
+ if wakeup?
51
+ DTR.info {"Agent brain wakes up"}
52
+
53
+ if DTR.run_script("DTR::Agent::Herald.new")
54
+ fang_gou
55
+ else
56
+ DTR.info {"=> No runner started."}
57
+ end
58
+
59
+ DTR.info {"Agent brain is going to sleep"}
60
+ end
61
+ end
62
+
63
+ def with_relaxation
64
+ yield
42
65
  rescue Interrupt, SystemExit, SignalException
66
+ DTR.info {$!.message}
43
67
  ensure
44
68
  relax
69
+ DTR.info {"Agent brain is dieing."}
45
70
  end
46
71
 
47
- def work(worker)
48
- until sleep?
49
- #keep worker working :D
72
+ def fang_gou
73
+ DTR.configuration.runners_should_be_working
74
+ Worker.new.watch_runners do
75
+ until sleep?
76
+ DTR.configuration.runners_should_be_working
77
+ end
78
+ DTR.configuration.agent_is_going_to_sleep
50
79
  end
51
- ensure
52
- DTR.info {"Killing worker"}
53
- DTR.kill_process worker
54
80
  end
55
81
  end
56
82
  end
@@ -15,18 +15,15 @@
15
15
  module DTR
16
16
 
17
17
  module Agent
18
- class Herald
18
+ class Herald < ProcessRoot
19
19
  class WorkingEnvError < StandardError
20
20
  end
21
21
 
22
22
  include Service::WorkingEnv
23
23
  include Service::Agent
24
24
 
25
- def initialize(working_env_key, agent_env_setup_cmd, runners)
26
- @working_env_key = working_env_key
27
- @agent_env_setup_cmd = agent_env_setup_cmd
28
- @runners = runners
29
- @env_store = EnvStore.new
25
+ def initialize
26
+ super
30
27
  start_service
31
28
  start_off
32
29
  ensure
@@ -34,10 +31,10 @@ module DTR
34
31
  end
35
32
 
36
33
  def start_off
37
- DTR.info {"=> Herald starts off..."}
38
- provide_agent_info(@agent_env_setup_cmd, @runners)
34
+ DTR.info {"=> Herald starts off at #{DTR.root}"}
35
+ provide_agent_info(DTR.configuration.agent_env_setup_cmd, DTR.configuration.agent_runners)
39
36
 
40
- @env_store[@working_env_key] = fetch_working_env
37
+ DTR.configuration.working_env = fetch_working_env
41
38
  rescue WorkingEnvError
42
39
  DTR.error $!.message
43
40
  exit(-1)
@@ -52,7 +49,8 @@ module DTR
52
49
  DTR.info {"=> Got working environment created at #{working_env[:created_at]} by #{working_env[:host]}"}
53
50
 
54
51
  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)
52
+
53
+ working_env.synchronize_for(DTR.configuration.agent_runners)
56
54
  working_env
57
55
  end
58
56
  end
@@ -0,0 +1,23 @@
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 ProcessRoot
18
+ def initialize(*args)
19
+ DTR.root = Dir.pwd
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,57 @@
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
+ module RailsExt
18
+ module DatabaseInitializer
19
+ def preparing_database_command
20
+ dtr_database_config_exists = File.exist?('config/database.yml.dtr')
21
+ default_database_config_exists = File.exist?('config/database.yml')
22
+
23
+ if !dtr_database_config_exists && !default_database_config_exists
24
+ DTR.info("No config/database.yml.dtr and config/database.yml exists, bypass database initialization.")
25
+ return
26
+ end
27
+
28
+ if dtr_database_config_exists
29
+ DTR.info("Found config/database.yml.dtr, use it as database configuration")
30
+ FileUtils.cp('config/database.yml.dtr', 'config/database.yml')
31
+ end
32
+ DTR.info("Clean databases")
33
+ Cmd.execute("rake --trace db:drop DTR_RUNNER_NAME=#{ENV['DTR_RUNNER_NAME']}", :error_output_log_level => :debug)
34
+
35
+ # Counldn't add --trace here, for Test::Unit detected --trace as a invalid option, don't know why
36
+ "rake db:create db:migrate db:test:prepare DTR_RUNNER_NAME=#{ENV['DTR_RUNNER_NAME']}"
37
+ end
38
+ end
39
+
40
+ module WorkingEnvExt
41
+ include DatabaseInitializer
42
+
43
+ def self.included(base)
44
+ base.alias_method_chain :setup_environment, :preparing_database
45
+ end
46
+
47
+ def setup_environment_with_preparing_database
48
+ if setup_environment_command.blank? && File.directory?('config')
49
+ DTR.debug("No setup environment command found but found 'config' directory, try default preparing database command")
50
+ self[:agent_env_setup_cmd] = preparing_database_command
51
+ end
52
+ setup_environment_without_preparing_database
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -14,65 +14,45 @@
14
14
 
15
15
  module DTR
16
16
  module Agent
17
- class Runner
17
+ class Runner < ProcessRoot
18
18
  include DRbUndumped
19
19
  include Service::Runner
20
20
 
21
- def self.start(name, env)
22
- self.new(name, env).start
23
- DRb.thread.join if DRb.thread
24
- end
25
-
26
- attr_reader :name, :identifier
21
+ attr_reader :name
27
22
 
28
- def initialize(name, env)
23
+ def initialize(name)
24
+ super
29
25
  @name = name
30
- @identifier = env[:identifier]
31
- @env = env
32
26
  end
33
27
 
34
28
  def start
35
29
  #start service first, so that all logs can be sync with master process
36
30
  start_service
37
- DTR.info("=> Starting runner #{name} at #{Dir.pwd}, pid: #{Process.pid}")
38
- init_environment
39
- provide
40
- DTR.info {"=> Runner #{name} provided"}
41
- rescue Exception
42
- DTR.error($!.message)
43
- DTR.error($!.backtrace.join("\n"))
44
- end
45
31
 
46
- def init_environment
47
- DTR.info {"#{name}: Initialize working environment..."}
48
32
  ENV['DTR_RUNNER_NAME'] = name
49
-
50
- @env[:libs].select{ |lib| !$LOAD_PATH.include?(lib) && File.exists?(lib) }.each do |lib|
51
- $LOAD_PATH << lib
52
- DTR.debug {"#{name}: appended lib: #{lib}"}
53
- end
54
- DTR.info {"#{name}: libs loaded"}
55
- DTR.debug {"#{name}: $LOAD_PATH: #{$LOAD_PATH.inspect}"}
56
-
57
- @env[:files].each do |f|
58
- begin
59
- load f unless f =~ /^-/
60
- DTR.debug {"#{name}: loaded #{f}"}
61
- rescue LoadError => e
62
- DTR.error {"#{name}: No such file to load -- #{f}"}
63
- DTR.debug {"Environment: #{@env}"}
33
+ DTR.info "Start #{self} at #{DTR.root}, pid: #{Process.pid}"
34
+ DTR.configuration.working_env.load_environment do
35
+ provide
36
+ DTR.info {"=> Runner provided"}
37
+ while DTR.configuration.runners_should_be_working?
38
+ sleep(1)
64
39
  end
65
40
  end
66
- DTR.info {"#{name}: test files loaded"}
41
+ rescue
42
+ DTR.error($!.message)
43
+ DTR.error($!.backtrace.join("\n"))
44
+ ensure
45
+ #make sure exit process for drb may cause this process hang on
46
+ exit!(0)
67
47
  end
68
48
 
69
49
  def run(test, result, &progress_block)
70
- DTR.debug {"#{name}: running #{test}..."}
50
+ DTR.debug {"running #{test}..."}
71
51
  Agent::TestCase.new(test, result, &progress_block).run
72
- DTR.debug {"#{name}: done #{test}"}
52
+ DTR.debug {"done #{test}"}
73
53
  ensure
74
54
  provide
75
- DTR.debug {"=> Runner #{name} provided"}
55
+ DTR.debug {"=> Runner provided"}
76
56
  end
77
57
 
78
58
  def provide