tap 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (244) hide show
  1. data/History +37 -30
  2. data/MIT-LICENSE +1 -1
  3. data/README +92 -44
  4. data/bin/tap +62 -75
  5. data/cmd/console.rb +42 -0
  6. data/cmd/destroy.rb +16 -0
  7. data/cmd/generate.rb +16 -0
  8. data/cmd/run.rb +126 -0
  9. data/doc/Class Reference +362 -0
  10. data/doc/Command Reference +153 -0
  11. data/doc/Tutorial +237 -0
  12. data/lib/tap.rb +6 -45
  13. data/lib/tap/app.rb +126 -500
  14. data/lib/tap/constants.rb +2 -29
  15. data/lib/tap/env.rb +555 -250
  16. data/lib/tap/file_task.rb +60 -103
  17. data/lib/tap/generator/base.rb +109 -0
  18. data/lib/tap/generator/destroy.rb +37 -0
  19. data/lib/tap/generator/generate.rb +61 -0
  20. data/lib/tap/generator/generators/command/command_generator.rb +16 -12
  21. data/lib/tap/generator/generators/command/templates/command.erb +13 -19
  22. data/lib/tap/generator/generators/config/config_generator.rb +18 -27
  23. data/lib/tap/generator/generators/config/templates/doc.erb +12 -0
  24. data/lib/tap/generator/generators/config/templates/nodoc.erb +8 -0
  25. data/lib/tap/generator/generators/file_task/file_task_generator.rb +16 -11
  26. data/lib/tap/generator/generators/file_task/templates/file.txt +11 -2
  27. data/lib/tap/generator/generators/file_task/templates/result.yml +6 -0
  28. data/lib/tap/generator/generators/file_task/templates/task.erb +24 -31
  29. data/lib/tap/generator/generators/file_task/templates/test.erb +18 -22
  30. data/lib/tap/generator/generators/root/root_generator.rb +45 -31
  31. data/lib/tap/generator/generators/root/templates/Rakefile +64 -41
  32. data/lib/tap/generator/generators/root/templates/gemspec +27 -0
  33. data/lib/tap/generator/generators/root/templates/tapfile +8 -0
  34. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -0
  35. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +1 -1
  36. data/lib/tap/generator/generators/root/templates/test/tapfile_test.rb +15 -0
  37. data/lib/tap/generator/generators/task/task_generator.rb +21 -28
  38. data/lib/tap/generator/generators/task/templates/task.erb +13 -23
  39. data/lib/tap/generator/generators/task/templates/test.erb +15 -18
  40. data/lib/tap/generator/manifest.rb +14 -0
  41. data/lib/tap/patches/rake/rake_test_loader.rb +0 -0
  42. data/lib/tap/patches/rake/testtask.rb +0 -0
  43. data/lib/tap/patches/ruby19/backtrace_filter.rb +0 -0
  44. data/lib/tap/patches/ruby19/parsedate.rb +0 -0
  45. data/lib/tap/root.rb +260 -21
  46. data/lib/tap/support/aggregator.rb +11 -11
  47. data/lib/tap/support/assignments.rb +172 -0
  48. data/lib/tap/support/audit.rb +20 -18
  49. data/lib/tap/support/batchable.rb +21 -10
  50. data/lib/tap/support/batchable_class.rb +107 -0
  51. data/lib/tap/support/class_configuration.rb +154 -239
  52. data/lib/tap/support/command_line.rb +97 -102
  53. data/lib/tap/support/comment.rb +270 -0
  54. data/lib/tap/support/configurable.rb +86 -65
  55. data/lib/tap/support/configurable_class.rb +296 -0
  56. data/lib/tap/support/configuration.rb +122 -0
  57. data/lib/tap/support/constant.rb +70 -0
  58. data/lib/tap/support/constant_utils.rb +127 -0
  59. data/lib/tap/support/declarations.rb +111 -0
  60. data/lib/tap/support/executable.rb +30 -17
  61. data/lib/tap/support/executable_queue.rb +0 -0
  62. data/lib/tap/support/framework.rb +71 -0
  63. data/lib/tap/support/framework_class.rb +199 -0
  64. data/lib/tap/support/instance_configuration.rb +147 -0
  65. data/lib/tap/support/lazydoc.rb +428 -0
  66. data/lib/tap/support/manifest.rb +89 -0
  67. data/lib/tap/support/run_error.rb +0 -0
  68. data/lib/tap/support/shell_utils.rb +33 -9
  69. data/lib/tap/support/summary.rb +30 -0
  70. data/lib/tap/support/tdoc.rb +339 -134
  71. data/lib/tap/support/tdoc/tdoc_html_generator.rb +0 -0
  72. data/lib/tap/support/tdoc/tdoc_html_template.rb +0 -0
  73. data/lib/tap/support/templater.rb +180 -0
  74. data/lib/tap/support/validation.rb +409 -76
  75. data/lib/tap/support/versions.rb +5 -3
  76. data/lib/tap/task.rb +78 -174
  77. data/lib/tap/tasks/dump.rb +56 -0
  78. data/lib/tap/tasks/rake.rb +93 -0
  79. data/lib/tap/test.rb +3 -3
  80. data/lib/tap/test/env_vars.rb +2 -2
  81. data/lib/tap/test/file_methods.rb +19 -20
  82. data/lib/tap/test/script_methods.rb +144 -0
  83. data/lib/tap/test/subset_methods.rb +1 -1
  84. data/lib/tap/test/tap_methods.rb +28 -62
  85. data/lib/tap/workflow.rb +22 -39
  86. metadata +48 -179
  87. data/Basic Overview +0 -151
  88. data/Command Reference +0 -99
  89. data/Rakefile +0 -127
  90. data/Tutorial +0 -287
  91. data/lib/tap/cmd/console.rb +0 -31
  92. data/lib/tap/cmd/destroy.rb +0 -20
  93. data/lib/tap/cmd/generate.rb +0 -20
  94. data/lib/tap/cmd/run.rb +0 -151
  95. data/lib/tap/dump.rb +0 -57
  96. data/lib/tap/generator.rb +0 -91
  97. data/lib/tap/generator/generators/command/USAGE +0 -6
  98. data/lib/tap/generator/generators/config/USAGE +0 -21
  99. data/lib/tap/generator/generators/config/templates/config.erb +0 -1
  100. data/lib/tap/generator/generators/file_task/USAGE +0 -3
  101. data/lib/tap/generator/generators/file_task/templates/file.yml +0 -3
  102. data/lib/tap/generator/generators/generator/USAGE +0 -0
  103. data/lib/tap/generator/generators/generator/generator_generator.rb +0 -21
  104. data/lib/tap/generator/generators/generator/templates/generator.erb +0 -32
  105. data/lib/tap/generator/generators/generator/templates/usage.erb +0 -1
  106. data/lib/tap/generator/generators/root/USAGE +0 -0
  107. data/lib/tap/generator/generators/root/templates/ReadMe.txt +0 -0
  108. data/lib/tap/generator/generators/root/templates/tap.yml +0 -80
  109. data/lib/tap/generator/generators/task/USAGE +0 -3
  110. data/lib/tap/generator/generators/workflow/USAGE +0 -0
  111. data/lib/tap/generator/generators/workflow/templates/task.erb +0 -16
  112. data/lib/tap/generator/generators/workflow/templates/test.erb +0 -7
  113. data/lib/tap/generator/generators/workflow/workflow_generator.rb +0 -6
  114. data/lib/tap/generator/options.rb +0 -26
  115. data/lib/tap/generator/usage.rb +0 -26
  116. data/lib/tap/support/batchable_methods.rb +0 -34
  117. data/lib/tap/support/command_line_methods.rb +0 -76
  118. data/lib/tap/support/configurable_methods.rb +0 -224
  119. data/lib/tap/support/logger.rb +0 -88
  120. data/lib/tap/support/rake.rb +0 -43
  121. data/lib/tap/support/tdoc/config_attr.rb +0 -362
  122. data/test/app/config/another/task.yml +0 -1
  123. data/test/app/config/batch.yml +0 -2
  124. data/test/app/config/empty.yml +0 -0
  125. data/test/app/config/erb.yml +0 -2
  126. data/test/app/config/some/task.yml +0 -1
  127. data/test/app/config/template.yml +0 -2
  128. data/test/app/config/version-0.1.yml +0 -1
  129. data/test/app/config/version.yml +0 -1
  130. data/test/app/lib/app_test_task.rb +0 -3
  131. data/test/app_test.rb +0 -1849
  132. data/test/env/test_configure/recurse_a.yml +0 -2
  133. data/test/env/test_configure/recurse_b.yml +0 -2
  134. data/test/env/test_configure/tap.yml +0 -23
  135. data/test/env/test_load_env_config/dir/tap.yml +0 -3
  136. data/test/env/test_load_env_config/recurse_a.yml +0 -2
  137. data/test/env/test_load_env_config/recurse_b.yml +0 -2
  138. data/test/env/test_load_env_config/tap.yml +0 -3
  139. data/test/env_test.rb +0 -198
  140. data/test/file_task/config/batch.yml +0 -2
  141. data/test/file_task/config/configured.yml +0 -1
  142. data/test/file_task/old_file_one.txt +0 -0
  143. data/test/file_task/old_file_two.txt +0 -0
  144. data/test/file_task_test.rb +0 -1291
  145. data/test/root/alt_lib/alt_module.rb +0 -4
  146. data/test/root/file.txt +0 -0
  147. data/test/root/glob/one.txt +0 -0
  148. data/test/root/glob/two.txt +0 -0
  149. data/test/root/lib/absolute_alt_filepath.rb +0 -2
  150. data/test/root/lib/alternative_filepath.rb +0 -2
  151. data/test/root/lib/another_module.rb +0 -2
  152. data/test/root/lib/nested/some_module.rb +0 -4
  153. data/test/root/lib/no_module_included.rb +0 -0
  154. data/test/root/lib/some/module.rb +0 -4
  155. data/test/root/lib/some_class.rb +0 -2
  156. data/test/root/lib/some_module.rb +0 -3
  157. data/test/root/load_path/load_path_module.rb +0 -2
  158. data/test/root/load_path/skip_module.rb +0 -2
  159. data/test/root/mtime/older.txt +0 -0
  160. data/test/root/unload/full_path.rb +0 -2
  161. data/test/root/unload/loaded_by_nested.rb +0 -2
  162. data/test/root/unload/nested/nested_load.rb +0 -6
  163. data/test/root/unload/nested/nested_with_ext.rb +0 -4
  164. data/test/root/unload/nested/relative_path.rb +0 -4
  165. data/test/root/unload/older.rb +0 -2
  166. data/test/root/unload/unload_base.rb +0 -9
  167. data/test/root/versions/another.yml +0 -0
  168. data/test/root/versions/file-0.1.2.yml +0 -0
  169. data/test/root/versions/file-0.1.yml +0 -0
  170. data/test/root/versions/file.yml +0 -0
  171. data/test/root_test.rb +0 -718
  172. data/test/support/aggregator_test.rb +0 -99
  173. data/test/support/audit_test.rb +0 -445
  174. data/test/support/batchable_test.rb +0 -74
  175. data/test/support/class_configuration_test.rb +0 -331
  176. data/test/support/command_line_test.rb +0 -58
  177. data/test/support/configurable/config/configured.yml +0 -2
  178. data/test/support/configurable_test.rb +0 -295
  179. data/test/support/executable_queue_test.rb +0 -103
  180. data/test/support/executable_test.rb +0 -38
  181. data/test/support/logger_test.rb +0 -31
  182. data/test/support/rake_test.rb +0 -37
  183. data/test/support/shell_utils_test.rb +0 -24
  184. data/test/support/tdoc_test.rb +0 -370
  185. data/test/support/validation_test.rb +0 -54
  186. data/test/support/versions_test.rb +0 -103
  187. data/test/tap_test_helper.rb +0 -57
  188. data/test/tap_test_suite.rb +0 -7
  189. data/test/task/config/batch.yml +0 -2
  190. data/test/task/config/batched.yml +0 -2
  191. data/test/task/config/configured.yml +0 -1
  192. data/test/task/config/example.yml +0 -1
  193. data/test/task_base_test.rb +0 -24
  194. data/test/task_syntax_test.rb +0 -300
  195. data/test/task_test.rb +0 -320
  196. data/test/test/env_vars_test.rb +0 -48
  197. data/test/test/file_methods/test_assert_files/expected/one.txt +0 -1
  198. data/test/test/file_methods/test_assert_files/expected/two.txt +0 -1
  199. data/test/test/file_methods/test_assert_files/input/one.txt +0 -1
  200. data/test/test/file_methods/test_assert_files/input/two.txt +0 -1
  201. data/test/test/file_methods/test_assert_files_can_have_no_expected_files_if_specified/input/one.txt +0 -1
  202. data/test/test/file_methods/test_assert_files_can_have_no_expected_files_if_specified/input/two.txt +0 -1
  203. data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/one.txt +0 -1
  204. data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/two.txt +0 -1
  205. data/test/test/file_methods/test_assert_files_fails_for_different_content/input/one.txt +0 -1
  206. data/test/test/file_methods/test_assert_files_fails_for_different_content/input/two.txt +0 -1
  207. data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/expected/one.txt +0 -1
  208. data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/one.txt +0 -1
  209. data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/two.txt +0 -1
  210. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/one.txt +0 -1
  211. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/two.txt +0 -1
  212. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/one.txt +0 -1
  213. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/two.txt +0 -1
  214. data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/one.txt +0 -1
  215. data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/two.txt +0 -1
  216. data/test/test/file_methods/test_method_glob/expected/file.yml +0 -0
  217. data/test/test/file_methods/test_method_glob/expected/file_1.txt +0 -0
  218. data/test/test/file_methods/test_method_glob/expected/file_2.txt +0 -0
  219. data/test/test/file_methods_doc/test_sub/expected/one.txt +0 -1
  220. data/test/test/file_methods_doc/test_sub/expected/two.txt +0 -1
  221. data/test/test/file_methods_doc/test_sub/input/one.txt +0 -1
  222. data/test/test/file_methods_doc/test_sub/input/two.txt +0 -1
  223. data/test/test/file_methods_doc_test.rb +0 -29
  224. data/test/test/file_methods_test.rb +0 -275
  225. data/test/test/subset_methods_test.rb +0 -171
  226. data/test/test/tap_methods/test_assert_files/expected/task/name/a.txt +0 -1
  227. data/test/test/tap_methods/test_assert_files/expected/task/name/b.txt +0 -1
  228. data/test/test/tap_methods/test_assert_files/input/a.txt +0 -1
  229. data/test/test/tap_methods/test_assert_files/input/b.txt +0 -1
  230. data/test/test/tap_methods_test.rb +0 -399
  231. data/test/workflow_test.rb +0 -120
  232. data/vendor/rails_generator.rb +0 -56
  233. data/vendor/rails_generator/base.rb +0 -263
  234. data/vendor/rails_generator/commands.rb +0 -581
  235. data/vendor/rails_generator/generated_attribute.rb +0 -42
  236. data/vendor/rails_generator/lookup.rb +0 -209
  237. data/vendor/rails_generator/manifest.rb +0 -53
  238. data/vendor/rails_generator/options.rb +0 -143
  239. data/vendor/rails_generator/scripts.rb +0 -83
  240. data/vendor/rails_generator/scripts/destroy.rb +0 -7
  241. data/vendor/rails_generator/scripts/generate.rb +0 -7
  242. data/vendor/rails_generator/scripts/update.rb +0 -12
  243. data/vendor/rails_generator/simple_logger.rb +0 -46
  244. data/vendor/rails_generator/spec.rb +0 -44
@@ -1 +0,0 @@
1
- key: two
@@ -1,2 +0,0 @@
1
- - key: one
2
- - key: two
File without changes
@@ -1,2 +0,0 @@
1
- app: <%= app.object_id %>
2
- filepath: <%= filepath %>
@@ -1 +0,0 @@
1
- key: one
@@ -1,2 +0,0 @@
1
- - factor: 10
2
- - factor: 22
@@ -1 +0,0 @@
1
- version: 0.1
@@ -1 +0,0 @@
1
- version: empty
@@ -1,3 +0,0 @@
1
- require 'tap'
2
- class AppTestTask < Tap::Task
3
- end
data/test/app_test.rb DELETED
@@ -1,1849 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'tap_test_helper')
2
- require 'tap/app'
3
- require 'stringio'
4
- require 'logger'
5
-
6
- class AppTest < Test::Unit::TestCase
7
- include Tap
8
- include TapTestMethods
9
-
10
- acts_as_tap_test
11
-
12
- def setup
13
- super
14
- app.root = trs.root
15
- end
16
-
17
- #
18
- # instance tests
19
- #
20
-
21
- def test_instance_returns_current_instance_or_a_default_app
22
- a = App.new
23
- App.instance = a
24
- assert_equal a, App.instance
25
-
26
- App.instance = nil
27
- assert_equal App, App.instance.class
28
- end
29
-
30
- def test_instance_initializes_new_App_if_not_set
31
- Tap::App.instance = nil
32
- assert Tap::App.instance.kind_of?(Tap::App)
33
- end
34
-
35
- #
36
- # helpers
37
- #
38
-
39
- # def stub_gemspec(name, version)
40
- # spec = Gem::Specification.new
41
- # spec.name = name
42
- # spec.version = version
43
- # spec.loaded_from = "/path/to/gems"
44
- # spec
45
- # end
46
-
47
- def current_threads
48
- threads = []
49
- ObjectSpace.garbage_collect
50
- sleep 0.2 # sleep to give garbage collect time to run
51
-
52
- # JRuby limits ObjectSpace to only work for Class by default
53
- # so this line has to be made less elegant and a little slower
54
- # ObjectSpace.each_object(Thread) {|t| threads << t.object_id}
55
- ObjectSpace.each_object(Class) {|t| threads << t.object_id if t.kind_of?(Thread)}
56
- threads
57
- end
58
-
59
- # check that no new threads are created during the block
60
- def extended_test_with_thread_check
61
- extended_test do
62
- prior_threads = current_threads
63
- yield
64
- assert_equal prior_threads, current_threads
65
- end
66
- end
67
-
68
- def test_app_documentation
69
- pwd = app.root
70
- assert_equal(pwd, app.root)
71
- assert_equal( File.expand_path(pwd +'/config'), app[:config])
72
-
73
- some_task = Task.new 'some/task'
74
- assert_equal( App.instance , some_task.app )
75
- assert_equal( File.expand_path(pwd +'/config/some/task.yml') , some_task.config_file)
76
- assert_equal( {:key => 'one'}, some_task.config)
77
-
78
- another_task = Task.new 'another/task'
79
- assert_equal( App.instance , another_task.app )
80
- assert_equal( File.expand_path(pwd + '/config/another/task.yml') , another_task.config_file)
81
- assert_equal( {:key => 'two'}, another_task.config)
82
-
83
- ###
84
- t1 = Task.new {|task, input| input += 1 }
85
- t1.enq 0
86
- t1.enq 10
87
-
88
- app.run
89
- assert_equal [1, 11], app.results(t1)
90
-
91
- app.aggregator.clear
92
-
93
- t2= Task.new {|task, input| input += 10 }
94
- t1.on_complete {|_result| t2.enq(_result) }
95
-
96
- t1.enq 0
97
- t1.enq 10
98
-
99
- app.run
100
- assert_equal [], app.results(t1)
101
- assert_equal [11, 21], app.results(t2)
102
-
103
- ###
104
- t1 = Task.new {|task, input| input += 1 }
105
- t2 = Task.new {|task, input| input += 10 }
106
- assert_equal [t1, t2], Task.batch(t1, t2)
107
-
108
- t1.enq 0
109
- t2.enq 10
110
-
111
- app.run
112
- assert_equal [1, 11], app.results(t1)
113
- assert_equal [10, 20], app.results(t2)
114
-
115
- lock = Mutex.new
116
- array = []
117
- t1 = Task.new {|task| lock.synchronize { array << Thread.current.object_id }; sleep 0.1 }
118
- t2 = Task.new {|task| lock.synchronize { array << Thread.current.object_id }; sleep 0.1 }
119
-
120
- t1.multithread = true
121
- t1.enq
122
- t2.multithread = true
123
- t2.enq
124
-
125
- app.run
126
- assert_equal 2, array.length
127
- assert_not_equal array[0], array[1]
128
-
129
- array = []
130
- Task::Base.initialize(array, :push)
131
-
132
- array.enq(1)
133
- array.enq(2)
134
-
135
- assert array.empty?
136
- app.run
137
- assert_equal [1, 2], array
138
-
139
- array = []
140
- m = array._method(:push)
141
-
142
- app.enq(m, 1)
143
- app.mq(array, :push, 2)
144
-
145
- assert array.empty?
146
- app.run
147
- assert_equal [1, 2], array
148
-
149
- ###
150
- t1 = Tap::Task.new('add_one') {|task, input| input += 1 }
151
- t2 = Tap::Task.new('add_five') {|task, input| input += 5 }
152
-
153
- t1.on_complete do |_result|
154
- _result._current < 3 ? t1.enq(_result) : t2.enq(_result)
155
- end
156
-
157
- t1.enq(0)
158
- t1.enq(1)
159
- t1.enq(2)
160
-
161
- app.run
162
- assert_equal [8,8,8], app.results(t2)
163
-
164
- strio = StringIO.new("")
165
- app._results(t2).each do |_result|
166
- strio.puts "How #{_result._original} became #{_result._current}:"
167
- strio.puts _result._to_s
168
- strio.puts
169
- end
170
-
171
- assert_equal(
172
- %Q{How 2 became 8:
173
- o-[] 2
174
- o-[add_one] 3
175
- o-[add_five] 8
176
-
177
- How 1 became 8:
178
- o-[] 1
179
- o-[add_one] 2
180
- o-[add_one] 3
181
- o-[add_five] 8
182
-
183
- How 0 became 8:
184
- o-[] 0
185
- o-[add_one] 1
186
- o-[add_one] 2
187
- o-[add_one] 3
188
- o-[add_five] 8
189
-
190
- }, strio.string)
191
-
192
- end
193
-
194
- #
195
- # State test
196
- #
197
-
198
- def test_state_str_documentation
199
- assert_equal 'READY', App::State.state_str(0)
200
- assert_nil App::State.state_str(12)
201
- end
202
-
203
- #
204
- # initialization tests
205
- #
206
-
207
- def test_default_app
208
- app = App.new
209
-
210
- assert_equal Dir.pwd, app.root
211
- assert_equal({}, app.directories)
212
- assert_equal({}, app.options.marshal_dump)
213
- assert_equal({}, app.map)
214
- assert_equal(Support::ExecutableQueue, app.queue.class)
215
- assert app.queue.empty?
216
- assert_equal(Support::Aggregator, app.aggregator.class)
217
- assert app.aggregator.empty?
218
- assert_equal App::State::READY, app.state
219
- end
220
-
221
- #
222
- # task config tests
223
- #
224
-
225
- def test_config_returns_current_configurations
226
- app = App.new
227
- expected = {
228
- :root => Dir.pwd,
229
- :directories => {},
230
- :absolute_paths => {},
231
- :options => {},
232
- :logger => {
233
- :device => STDOUT,
234
- :level => 1, # corresponds to 'INFO'
235
- :datetime_format => '%H:%M:%S'}
236
- }
237
- assert_equal expected, app.config
238
-
239
- # now try with a variety of configurations changed
240
- app.options.trace = true
241
- app[:lib] = 'alt/lib'
242
- app[:abs, true] = '/absolute/path'
243
- strio = StringIO.new('')
244
- app.logger = Logger.new(strio)
245
-
246
- expected = {
247
- :root => Dir.pwd,
248
- :directories => {:lib => 'alt/lib'},
249
- :absolute_paths => {:abs => File.expand_path('/absolute/path')},
250
- :options => {:trace => true},
251
- :logger => {
252
- :device => strio,
253
- :level => 0,
254
- :datetime_format => nil}
255
- }
256
-
257
- assert_equal 0, app.logger.level
258
- assert_equal nil, app.logger.datetime_format
259
- assert_equal expected, app.config
260
- end
261
-
262
- #
263
- # reconfigure test
264
- #
265
-
266
- def test_reconfigure_documentation
267
- app = Tap::App.new :root => "/root", :directories => {:dir => 'path/to/dir'}
268
- app.reconfigure(
269
- :root => "./new/root",
270
- :logger => {:level => Logger::DEBUG})
271
-
272
- assert_equal File.expand_path("./new/root"), app.root
273
- assert_equal File.expand_path("./new/root/path/to/dir"), app[:dir]
274
- assert_equal Logger::DEBUG, app.logger.level
275
- end
276
-
277
- def test_reconfigure_root_sets_app_root
278
- app = App.new
279
-
280
- assert_equal Dir.pwd, app.root
281
- app.reconfigure :root => './alt/root'
282
- assert_equal File.expand_path('./alt/root'), app.root
283
- end
284
-
285
- def test_reconfigure_directories_sets_directories
286
- app = App.new
287
- assert_equal({}, app.directories)
288
- app.reconfigure :directories => {:lib => 'alt/lib'}
289
- assert_equal({:lib => 'alt/lib'}, app.directories)
290
- end
291
-
292
- def test_reconfigure_absolute_paths_sets_absolute_paths
293
- app = App.new
294
- assert_equal({}, app.absolute_paths)
295
- app.reconfigure :absolute_paths => {:log => '/path/to/log'}
296
- assert_equal({:log => File.expand_path('/path/to/log')}, app.absolute_paths)
297
- end
298
-
299
- def test_reconfigure_options_sets_options
300
- app = App.new
301
- assert_equal({}, app.options.marshal_dump)
302
- app.reconfigure :options => {:trace => true}
303
- assert_equal({:trace => true}, app.options.marshal_dump)
304
- end
305
-
306
- def test_reconfigure_logger_sets_logger
307
- app = App.new
308
- assert_equal STDOUT, app.logger.logdev.dev
309
- strio = StringIO.new('')
310
- app.reconfigure :logger => {:device => strio, :level => Logger::WARN}
311
- assert_equal strio, app.logger.logdev.dev
312
- assert_equal Logger::WARN, app.logger.level
313
- end
314
-
315
- def test_reconfigure_map_sets_map
316
- app = App.new
317
- assert_equal({}, app.map)
318
- app.reconfigure :map => {'some/task_name' => Tap::Task}
319
- assert_equal({'some/task_name' => Tap::Task}, app.map)
320
- end
321
-
322
- def test_reconfigure_sends_unhandled_options_to_block_if_given
323
- app = App.new
324
- was_in_block = false
325
- app.reconfigure(:unknown => 'value') do |key, value|
326
- assert_equal(:unknown, key)
327
- assert_equal('value', value)
328
- was_in_block = true
329
- end
330
- assert was_in_block
331
- end
332
-
333
- def test_reconfigure_raises_error_for_unhandled_options
334
- app = App.new
335
- assert_raise(ArgumentError) { app.reconfigure(:unknown => 'value') }
336
- end
337
-
338
- class AppHandlesConfig < App
339
- attr_accessor :handled_configs
340
- def initialize
341
- self.handled_configs = []
342
- end
343
- def handle_configuation(key, value)
344
- handled_configs.concat [key, value]
345
- true
346
- end
347
- end
348
-
349
- def test_reconfigure_sends_unhandled_options_to_handle_configuation_if_defined
350
- app = AppHandlesConfig.new
351
- was_in_block = false
352
- app.reconfigure(:unknown => 'value') do |key, value|
353
- was_in_block = true
354
- end
355
- assert_equal [:unknown, 'value'], app.handled_configs
356
- assert !was_in_block
357
- end
358
-
359
- class AppDoesNotHandleConfig < AppHandlesConfig
360
- def handle_configuation(key, value)
361
- handled_configs.concat [key, value]
362
- false
363
- end
364
- end
365
-
366
- def test_reconfigure_goes_to_block_if_handle_configuration_returns_false
367
- app = AppDoesNotHandleConfig.new
368
- was_in_block = false
369
- app.reconfigure(:unknown => 'value') do |key, value|
370
- was_in_block = true
371
- end
372
- assert_equal [:unknown, 'value'], app.handled_configs
373
- assert was_in_block
374
- end
375
-
376
- #
377
- # reload test
378
- #
379
-
380
- def test_reload_returns_unloaded_constants
381
- app = Tap::App.instance
382
-
383
- Dependencies.clear
384
- assert_equal [], app.reload
385
-
386
- begin
387
- assert !Object.const_defined?("AppTestTask")
388
-
389
- Dependencies.load_paths << app['lib']
390
- app_task_test_mod = AppTestTask
391
-
392
- assert Object.const_defined?("AppTestTask")
393
- assert_equal [:AppTestTask], app.reload.collect {|c| c.to_sym }
394
- assert !Object.const_defined?("AppTestTask")
395
- ensure
396
- Dependencies.clear
397
- Dependencies.load_paths.delete(app['lib'])
398
- end
399
- end
400
-
401
- #
402
- # lookup_const test
403
- #
404
-
405
- def test_lookup_const_does_not_mishandle_top_level_constants
406
- assert !Object.const_defined?('LookupModule')
407
- Object.const_set('LookupModule', Module.new)
408
- assert_raise(Tap::App::LookupError) { app.lookup_const('lookup_module/file') }
409
- end
410
-
411
- #
412
- # set logger tests
413
- #
414
-
415
- def test_set_logger_extends_logger_with_support_logger
416
- output = StringIO.new('')
417
- logger = Logger.new(output)
418
- assert !logger.respond_to?(:section_break)
419
-
420
- app.logger = logger
421
- assert logger.respond_to?(:section_break)
422
- end
423
-
424
- #
425
- # TODO -- Add logging tests
426
- #
427
-
428
- #
429
- # task_class tests
430
- #
431
-
432
- class TaskSubClass < Task
433
- end
434
-
435
- class AnotherTask < Task
436
- end
437
-
438
- def test_task_class_documentation
439
- t_class = app.task_class('tap/file_task')
440
- assert_equal Tap::FileTask, t_class
441
-
442
- app.map = {"mapped-task" => "Tap::FileTask"}
443
- t_class = app.task_class('mapped-task-1.0')
444
- assert_equal Tap::FileTask, t_class
445
- end
446
-
447
- #
448
- # task tests
449
- #
450
-
451
- def test_task_documentation
452
- t = app.task('tap/file_task')
453
- assert_equal Tap::FileTask, t.class
454
- assert_equal 'tap/file_task', t.name
455
-
456
- app.map = {"mapped-task" => "Tap::FileTask"}
457
-
458
- t = app.task('mapped-task-1.0', :key => 'value')
459
- assert_equal Tap::FileTask, t.class
460
- assert_equal "mapped-task-1.0", t.name
461
- assert_equal 'value', t.config[:key]
462
- end
463
-
464
- def test_task_looks_up_and_instantiates_task
465
- assert_equal TaskSubClass, app.task("AppTest::TaskSubClass").class
466
- end
467
-
468
- def test_task_instantiates_a_new_task_for_each_call
469
- t1 = app.task("AppTest::TaskSubClass")
470
- t2 = app.task("AppTest::TaskSubClass")
471
-
472
- assert_not_equal t1.object_id, t2.object_id
473
- end
474
-
475
- def test_task_translates_task_name_to_class_name_using_map_if_possible
476
- app.map["mapped_name"] = "AppTest::TaskSubClass"
477
- assert_equal TaskSubClass, app.task("mapped_name").class
478
- end
479
-
480
- def test_task_translates_task_name_to_class_name_using_camelize_by_default
481
- assert_equal TaskSubClass, app.task("app_test/task_sub_class").class
482
- end
483
-
484
- def test_task_name_and_version_is_respected
485
- t = app.task("app_test/task_sub_class-1.1")
486
- assert_equal TaskSubClass, t.class
487
- assert_equal "app_test/task_sub_class-1.1", t.name
488
- end
489
-
490
- def test_task_looks_up_task_classes_along_Dependencies_load_paths
491
- begin
492
- assert !Object.const_defined?("AppTestTask")
493
-
494
- Dependencies.load_paths << app['lib']
495
- t = app.task("AppTestTask")
496
-
497
- assert Object.const_defined?("AppTestTask")
498
- assert_equal AppTestTask, t.class
499
- ensure
500
- Dependencies.clear
501
- Dependencies.load_paths.delete(app['lib'])
502
- end
503
- end
504
-
505
- def test_task_raises_lookup_error_if_class_cannot_be_found
506
- assert_raise(App::LookupError) { app.task("NonExistant") }
507
- end
508
-
509
- #
510
- # task_class_name test
511
- #
512
-
513
- def test_task_class_name_documentation
514
- app.map = {"mapped-task" => "Tap::FileTask"}
515
- assert_equal "some/task_class", app.task_class_name('some/task_class')
516
- assert_equal "Tap::FileTask", app.task_class_name('mapped-task-1.0')
517
-
518
- t1 = Task.new
519
- assert_equal "Tap::Task", app.task_class_name(t1)
520
-
521
- t2 = ObjectWithExecute.new.extend Tap::Task::Base
522
- assert_equal "ObjectWithExecute", app.task_class_name(t2)
523
- end
524
-
525
- def test_task_class_name_returns_task_class_name
526
- task = Task.new
527
- assert_equal "Tap::Task", app.task_class_name(task)
528
-
529
- subtask = TaskSubClass.new
530
- assert_equal "AppTest::TaskSubClass", app.task_class_name(subtask)
531
-
532
- non_task = ObjectWithExecute.new
533
- non_task.extend Tap::Task::Base
534
- assert_equal "ObjectWithExecute", app.task_class_name(non_task)
535
- end
536
-
537
- def test_task_class_name_returns_deversioned_name
538
- assert_equal "app_test/task_sub_class", app.task_class_name("app_test/task_sub_class-1.1")
539
- end
540
-
541
- def test_task_class_name_resolves_names_using_map
542
- app.map = {"mapped-task" => "AnotherTask"}
543
- assert_equal "AnotherTask", app.task_class_name("mapped-task-1.1")
544
- end
545
-
546
- #
547
- # each_config_template tests
548
- #
549
-
550
- def test_each_config_template_documentation
551
- simple = output_tempfile
552
- File.open(simple, "w") {|f| f << "key: value"}
553
- assert_equal([{"key" => "value"}], app.each_config_template(simple))
554
-
555
- erb = output_tempfile
556
- File.open(erb, "w") {|f| f << "app: <%= app.object_id %>\nfilepath: <%= filepath %>"}
557
- assert_equal([{"app" => app.object_id, "filepath" => erb}], app.each_config_template(erb))
558
-
559
- batched_with_erb = output_tempfile
560
- File.open(batched_with_erb, "w") do |f|
561
- f << %Q{
562
- - key: <%= 1 %>
563
- - key: <%= 1 + 1 %>}
564
- end
565
- assert_equal([{"key" => 1}, {"key" => 2}], app.each_config_template(batched_with_erb))
566
- end
567
-
568
- def test_each_config_template_retrieves_templates_for_versioned_config_files
569
- filepath = app.filepath('config', "version.yml")
570
- assert File.exists?(filepath)
571
- assert_equal [{"version" => "empty"}], app.each_config_template(filepath)
572
-
573
- filepath = app.filepath('config', "version-0.1.yml")
574
- assert File.exists?(filepath)
575
- assert_equal [{"version" => 0.1}], app.each_config_template(filepath)
576
- end
577
-
578
- def test_each_config_template_can_load_an_array_of_templates
579
- filepath = app.filepath('config', "batch.yml")
580
- assert File.exists?(filepath)
581
- assert_equal [{"key" => "one"}, {"key" => "two"}], app.each_config_template(filepath)
582
- end
583
-
584
- def test_each_config_template_returns_empty_template_even_if_config_file_does_not_exist
585
- filepath = app.filepath('config', "non_existant.yml")
586
- assert !File.exists?(filepath)
587
- assert_equal [{}], app.each_config_template(filepath)
588
- end
589
-
590
- def test_each_config_template_returns_empty_template_if_config_file_is_empty
591
- filepath = app.filepath('config', "empty.yml")
592
- assert File.exists?(filepath)
593
- assert_equal "", File.read(filepath)
594
- assert_equal [{}], app.each_config_template(filepath)
595
- end
596
-
597
- def test_each_config_template_templates_using_erb
598
- filepath = app.filepath('config', "erb.yml")
599
- assert_equal [{"filepath" => filepath, "app" => app.object_id}], app.each_config_template(filepath)
600
- end
601
-
602
- #
603
- # config_filepath test
604
- #
605
-
606
- def test_config_filepath
607
- assert_equal nil, app.config_filepath(nil)
608
- assert_equal File.join(app['config'], "task/name.yml"), app.config_filepath("task/name")
609
- end
610
-
611
- #
612
- # ready test
613
- #
614
-
615
- def test_ready_sets_state_to_READY_unless_running
616
- app.instance_variable_set('@state', App::State::STOP)
617
- assert_not_equal App::State::READY, app.state
618
-
619
- assert_equal app, app.ready
620
- assert_equal App::State::READY, app.state
621
- end
622
-
623
- def test_ready_does_not_sets_state_to_READY_when_running
624
- was_in_block = false
625
-
626
- t = Tap::Task.new do |task|
627
- assert_equal App::State::RUN, app.state
628
- task.app.ready
629
- assert_equal App::State::RUN, app.state
630
-
631
- task.app.stop
632
- assert_equal App::State::STOP, app.state
633
- task.app.ready
634
- assert_equal App::State::STOP, app.state
635
-
636
- was_in_block = true
637
- end
638
-
639
- with_options :debug => true do
640
- t.enq
641
- app.run
642
- end
643
-
644
- assert was_in_block
645
- end
646
-
647
- #
648
- # run tests
649
- #
650
-
651
- def test_run_single_task
652
- t = Task.new(&add_one)
653
- with_options :debug => true do
654
- t.enq 1
655
- app.run
656
- end
657
-
658
- assert_audit_equal(ExpAudit[[nil, 1], [t,2]], app._results(t).first)
659
- assert_equal [1], runlist
660
- end
661
-
662
- def test_run_single_task_from_a_thread
663
- t = Task.new(&add_one)
664
- with_options :debug => true do
665
- t.enq 1
666
- th = Thread.new { app.run }
667
- th.join
668
- end
669
-
670
- assert_audit_equal(ExpAudit[[nil, 1], [t,2]], app._results(t).first)
671
- assert_equal [1], runlist
672
- end
673
-
674
- #
675
- # multithread test
676
- #
677
-
678
- def test_main_thread_execution_waits_for_multithread_execution
679
- extended_test do
680
- main_thread_ran = false
681
- check_thread_ran = false
682
- multithread_ran = false
683
-
684
- multithread_executing = false
685
- main_thread_did_not_wait = false
686
- multithread_did_not_wait = false
687
-
688
- t1 = Task.new do |task|
689
- main_thread_ran = true
690
- main_thread_did_not_wait = true if multithread_executing
691
- end
692
-
693
- t2 = Task.new do |task|
694
- check_thread_ran = true
695
- multithread_did_not_wait = true if multithread_executing
696
- end
697
- t2.multithread = true
698
-
699
- t3 = Task.new do |task|
700
- multithread_ran = true
701
- multithread_executing = true
702
-
703
- # sleep is necessary so the other threads
704
- # have an opportunity to execute
705
- sleep(0.1)
706
-
707
- multithread_executing = false
708
- end
709
- t3.multithread = true
710
-
711
- t3.enq
712
- t2.enq
713
- t1.enq
714
-
715
- with_options :debug => true do
716
- app.run
717
- end
718
-
719
- assert main_thread_ran
720
- assert multithread_ran
721
- assert check_thread_ran
722
- assert !main_thread_did_not_wait
723
- assert multithread_did_not_wait
724
- end
725
- end
726
-
727
- def test_multithread_execution_waits_for_main_thread_execution
728
- extended_test do
729
- main_thread_ran = false
730
- multithread_ran = false
731
-
732
- multithread_did_not_wait = false
733
- main_thread_executing = false
734
-
735
- t1 = Task.new do |task|
736
- multithread_ran = true
737
- multithread_did_not_wait = true if main_thread_executing
738
- end
739
- t1.multithread = true
740
-
741
- t2 = Task.new do |task|
742
- main_thread_ran = true
743
- main_thread_executing = true
744
-
745
- # sleep is necessary so the other threads
746
- # have an opportunity to execute
747
- sleep(0.1)
748
-
749
- main_thread_executing = false
750
- end
751
-
752
- t2.enq
753
- t1.enq
754
-
755
- with_options :debug => true do
756
- app.run
757
- end
758
-
759
- assert main_thread_ran
760
- assert multithread_ran
761
- assert !multithread_did_not_wait
762
- end
763
- end
764
-
765
- def test_only_max_threads_will_be_executed_at_a_time
766
- extended_test do
767
- max_threads = 0
768
- n_threads = 0
769
-
770
- # the logic of this test is that if app executes
771
- # in a multithreaded manner, then max_threads will
772
- # be greater than 1. Furthermore, if the max_threads
773
- # option is respected, then max_threads shouldn't be
774
- # greater than 2.
775
- block = lambda do |task|
776
- n_threads += 1
777
- max_threads = n_threads if n_threads > max_threads
778
-
779
- # sleep is necessary so the other threads
780
- # have an opportunity to execute
781
- sleep(0.1)
782
-
783
- n_threads -= 1
784
- nil
785
- end
786
-
787
- t1 = Task.new(&block)
788
- t2 = Task.new(&block)
789
- t3 = Task.new(&block)
790
-
791
- with_options(:max_threads => 2) do
792
- [t1,t2,t3].each do |t|
793
- t.enq
794
- t.multithread = true
795
- end
796
-
797
- with_options :debug => true do
798
- app.run
799
- end
800
-
801
- assert_equal 2, max_threads
802
- end
803
- end
804
- end
805
-
806
- def test_no_new_threads_appear_after_clean_multithread_exit
807
- extended_test_with_thread_check do
808
- max_threads = 0
809
- n_threads = 0
810
-
811
- tasks = Array.new(3) do
812
- Task.new do |task|
813
- n_threads += 1
814
- max_threads = n_threads if n_threads > max_threads
815
- sleep 0.1
816
- n_threads -= 1
817
- end
818
- end
819
- tasks.each do |task|
820
- task.multithread = true
821
- task.enq
822
- end
823
-
824
- app.run
825
-
826
- assert_equal 3, max_threads
827
- end
828
- end
829
-
830
- # JRuby inconsistent test?
831
- # 2 max_threads expected but was 1
832
- def test_no_new_threads_appear_after_clean_main_thread_exit
833
- extended_test_with_thread_check do
834
- max_threads = 0
835
- n_threads = 0
836
-
837
- tasks = Array.new(3) do
838
- Task.new do |task|
839
- n_threads += 1
840
- max_threads = n_threads if n_threads > max_threads
841
- sleep 0.1
842
- n_threads -= 1
843
- end
844
- end
845
- non_threaded = tasks.shift
846
- tasks.each do |task|
847
- task.multithread = true
848
- task.enq
849
- end
850
- non_threaded.enq
851
-
852
- app.run
853
-
854
- assert_equal 2, max_threads
855
- end
856
- end
857
-
858
- #
859
- # stop test
860
- #
861
-
862
- def test_stop_prevents_non_executing_tasks_from_executing_on_main_thread
863
- extended_test_with_thread_check do
864
- count = 0
865
- tasks = Array.new(5) do
866
- Task.new do |task|
867
- count += 1
868
- app.stop if count == 2
869
- end
870
- end
871
- tasks.each do |task|
872
- task.enq
873
- end
874
-
875
- # under these conditions, 2 tasks should be
876
- # executed on 2 threads, and 2 additional tasks
877
- # dequeued into the thread queue. on stop, the 2
878
- # executing tasks should finish normally, and NO MORE
879
- # tasks executed. The waiting tasks will be requeued.
880
- with_options :max_threads => 2, :debug => true do
881
- app.run
882
- end
883
-
884
- assert_equal 2, count
885
- assert_equal 3, app.queue.size
886
-
887
- queued_tasks = []
888
- while !app.queue.empty?
889
- task, inputs = app.queue.deq
890
- queued_tasks << task
891
- end
892
-
893
- # check that the requeued tasks are in order
894
- assert_equal tasks[2...5], queued_tasks
895
- end
896
- end
897
-
898
- def test_stop_prevents_non_executing_tasks_from_executing_on_threads_and_requeues_thread_queue
899
- extended_test_with_thread_check do
900
- count = 0
901
- tasks = Array.new(5) do
902
- Task.new do |task|
903
- count += 1
904
- sleep 0.1
905
- app.stop if count == 2
906
- sleep 0.1
907
- end
908
- end
909
- tasks.each do |task|
910
- task.multithread = true
911
- task.enq
912
- end
913
-
914
- # under these conditions, 2 tasks should be
915
- # executed on 2 threads, and 2 additional tasks
916
- # dequeued into the thread queue. on stop, the 2
917
- # executing tasks should finish normally, and NO MORE
918
- # tasks executed. The waiting tasks will be requeued.
919
- with_options :max_threads => 2, :debug => true do
920
- app.run
921
- end
922
-
923
- assert_equal 2, count
924
- assert_equal 3, app.queue.size
925
-
926
- queued_tasks = []
927
- while !app.queue.empty?
928
- task, inputs = app.queue.deq
929
- queued_tasks << task
930
- end
931
-
932
- # check that the requeued tasks are in order
933
- assert_equal tasks[2...5], queued_tasks
934
- end
935
- end
936
-
937
- #
938
- # terminate test
939
- #
940
-
941
- def test_terminate_from_main_thread_raises_run_error
942
- extended_test_with_thread_check do
943
- was_terminated = true
944
- task = Task.new do |t|
945
- app.terminate
946
- t.check_terminate
947
- was_terminated = false
948
- end
949
-
950
- task.enq
951
- with_options :debug => true do
952
- begin
953
- app.run
954
- flunk "no error was raised"
955
- rescue
956
- assert $!.kind_of?(Tap::Support::RunError)
957
- assert $!.errors.empty?
958
- end
959
- end
960
-
961
- assert was_terminated
962
- end
963
- end
964
-
965
- def test_terminate_from_main_thread_when_error_is_handled_still_raises_error
966
- extended_test_with_thread_check do
967
- terminate_error_handled = false
968
- task = Task.new do |t|
969
- begin
970
- app.terminate
971
- t.check_terminate
972
- rescue
973
- terminate_error_handled = true
974
- end
975
- end
976
-
977
- task.enq
978
- with_options :debug => true do
979
- begin
980
- app.run
981
- flunk "no error was raised"
982
- rescue
983
- assert $!.kind_of?(Tap::Support::RunError)
984
- assert $!.errors.empty?
985
- end
986
- end
987
-
988
- assert terminate_error_handled
989
- end
990
- end
991
-
992
- def test_terminate_raises_error_on_each_execution_thread_and_requeues_thread_queue
993
- extended_test_with_thread_check do
994
- count = 0
995
- some_thread_was_not_terminated = false
996
- tasks = Array.new(5) do
997
- Task.new do |task|
998
- count += 1
999
- app.terminate if count == 2
1000
- sleep 0.8
1001
- task.check_terminate
1002
- some_thread_was_not_terminated = true
1003
- end
1004
- end
1005
- tasks.each do |task|
1006
- task.multithread = true
1007
- task.enq
1008
- end
1009
-
1010
- # under these conditions, 2 tasks should be
1011
- # executed on 2 threads, and 2 additional tasks
1012
- # dequeued into the thread queue. on stop, the 2
1013
- # executing tasks should be terminated, and NO MORE
1014
- # tasks executed. The waiting tasks will be requeued.
1015
- with_options :max_threads => 2, :debug => true do
1016
- begin
1017
- app.run
1018
- flunk "no error was raised"
1019
- rescue
1020
- assert $!.kind_of?(Tap::Support::RunError)
1021
- assert $!.errors.empty?
1022
- end
1023
- end
1024
-
1025
- assert_equal 2, count
1026
- assert_equal 3, app.queue.size
1027
- assert !some_thread_was_not_terminated
1028
-
1029
- queued_tasks = []
1030
- while !app.queue.empty?
1031
- task, inputs = app.queue.deq
1032
- queued_tasks << task
1033
- end
1034
-
1035
- # check that the requeued tasks are in order
1036
- assert_equal tasks[2...5], queued_tasks
1037
- end
1038
- end
1039
-
1040
- # JRuby inconsistent test
1041
- # RESOLVED? 2008/01/29
1042
- # -- still can be an issue, if the sleep time is too short --
1043
- def test_terminate_on_thread_when_error_is_handled_still_raises_error
1044
- extended_test_with_thread_check do
1045
- count = 0
1046
- some_thread_was_not_terminated = false
1047
- handled_count = 0
1048
-
1049
- tasks = Array.new(5) do
1050
- Task.new do |task|
1051
- count += 1
1052
- begin
1053
- app.terminate if count == 2
1054
- sleep 0.8
1055
- task.check_terminate
1056
- some_thread_was_not_terminated = true
1057
- rescue
1058
- handled_count += 1
1059
- end
1060
- end
1061
- end
1062
- tasks.each do |task|
1063
- task.multithread = true
1064
- task.enq
1065
- end
1066
-
1067
- # under these conditions, 2 tasks should be
1068
- # executed on 2 threads, and 2 additional tasks
1069
- # dequeued into the thread queue. on stop, the 2
1070
- # executing tasks should be terminated, and NO MORE
1071
- # tasks executed. The waiting tasks will be requeued.
1072
- with_options :max_threads => 2, :debug => true do
1073
- begin
1074
- app.run
1075
- flunk "no error was raised"
1076
- rescue
1077
- assert $!.kind_of?(Tap::Support::RunError)
1078
- assert $!.errors.empty?
1079
- end
1080
- end
1081
-
1082
- assert !some_thread_was_not_terminated
1083
- assert_equal 2, count
1084
- assert_equal 2, handled_count
1085
- assert_equal 3, app.queue.size
1086
- end
1087
- end
1088
-
1089
- #
1090
- # info tests
1091
- #
1092
-
1093
- def test_info_provides_information_string
1094
- assert_equal 'state: 0 (READY) queue: 0 thread_queue: 0 threads: 0 results: 0', app.info
1095
- end
1096
-
1097
- # TODO -- JRuby inconsistent test
1098
- # RESOLVED? 2007/01/30
1099
- def test_info_can_be_called_during_a_run
1100
- extended_test do
1101
- lock = Monitor.new
1102
- count = 0
1103
- info_str = nil
1104
-
1105
- tasks = Array.new(5) do
1106
- Task.new do |task|
1107
-
1108
- lock.synchronize do
1109
- count += 1
1110
- if count == 2
1111
- info_str = app.info
1112
- app.stop
1113
- end
1114
- end
1115
-
1116
- sleep 0.8
1117
- end
1118
- end
1119
- tasks.each do |task|
1120
- task.enq
1121
- task.multithread = true
1122
- end
1123
-
1124
- with_options :max_threads => 2 do
1125
- app.run
1126
- end
1127
-
1128
- # There is some ambiguity in the info string -- tasks
1129
- # could be waiting in the queue or in the thread queue
1130
- # and additionally, the thread queue may have nils to
1131
- # signal the threads to terminate
1132
- assert info_str =~ /state: 1 \(RUN\) queue: \d thread_queue: \d threads: 2 results: \d/, info_str
1133
- assert_equal 'state: 0 (READY) queue: 3 thread_queue: 0 threads: 0 results: 2', app.info
1134
- end
1135
- end
1136
-
1137
- #
1138
- # enq test
1139
- #
1140
-
1141
- def test_enq
1142
- t = Task.new
1143
- assert app.queue.empty?
1144
- app.enq(t)
1145
- assert_equal [[t, []]], app.queue.to_a
1146
- end
1147
-
1148
- def test_enq_enques_each_task_in_task_batch
1149
- t1 = Task.new
1150
- t2 = t1.initialize_batch_obj
1151
-
1152
- assert app.queue.empty?
1153
- app.enq(t1)
1154
- assert_equal [[t1, []], [t2, []]], app.queue.to_a
1155
- end
1156
-
1157
- def test_enq_allows_methods
1158
- m = []._method(:push)
1159
- assert app.queue.empty?
1160
- app.enq(m)
1161
- assert_equal [[m, []]], app.queue.to_a
1162
- end
1163
-
1164
- def test_enq_returns_enqued_task
1165
- t = Task.new
1166
- assert_equal t, app.enq(t)
1167
- end
1168
-
1169
- #
1170
- # mq test
1171
- #
1172
-
1173
- def test_mq
1174
- a = []
1175
- assert app.queue.empty?
1176
- m = app.mq(a, :push, 1, 2)
1177
- assert_equal [[m, [1,2]]], app.queue.to_a
1178
- end
1179
-
1180
- # #
1181
- # # on_complete tests
1182
- # #
1183
- #
1184
- # def test_on_complete
1185
- # t1 = Task.new(&add_one)
1186
- # t2 = Task.new(&add_one)
1187
- # t3 = Task.new(&add_one)
1188
- #
1189
- # app.on_complete(t1) do |result|
1190
- # t2.enq result
1191
- # t3.enq result
1192
- # end
1193
- # with_options :debug => true do
1194
- # t1.enq 0
1195
- # app.run
1196
- # end
1197
- #
1198
- # assert_equal [0,1,1], runlist
1199
- # assert_audit_equal(ExpAudit[[nil,0],[t1,1],[t2,2]], app._results(t2).first)
1200
- # assert_audit_equal(ExpAudit[[nil,0],[t1,1],[t3,2]], app._results(t3).first)
1201
- # end
1202
-
1203
- #
1204
- # sequence tests
1205
- #
1206
-
1207
- def test_run_sequence
1208
- t1 = Task.new(&add_one)
1209
- t2 = Task.new(&add_one)
1210
-
1211
- app.sequence(t1,t2)
1212
- with_options :debug => true do
1213
- t1.enq 0
1214
- app.run
1215
- end
1216
-
1217
- assert_equal [0,1], runlist
1218
- assert_audit_equal(ExpAudit[[nil,0],[t1,1],[t2,2]], app._results(t2).first)
1219
- end
1220
-
1221
- def test_run_sequence_from_trailing_task
1222
- t1 = Task.new(&add_one)
1223
- t2 = Task.new(&add_one)
1224
-
1225
- app.sequence(t1,t2)
1226
- with_options :debug => true do
1227
- t2.enq 1
1228
- app.run
1229
- end
1230
-
1231
- assert_equal [1], runlist
1232
- assert_equal 0, app._results(t1).length
1233
- assert_audit_equal(ExpAudit[[nil,1],[t2,2]], app._results(t2).first)
1234
- end
1235
-
1236
- #
1237
- # fork tests
1238
- #
1239
-
1240
- def test_run_fork
1241
- t1 = Task.new(&add_one)
1242
- t2 = Task.new(&add_one)
1243
- t3 = Task.new(&add_one)
1244
-
1245
- app.fork(t1, t2, t3)
1246
- with_options :debug => true do
1247
- t1.enq 0
1248
- app.run
1249
- end
1250
-
1251
- assert_equal [0,1,1], runlist
1252
- assert_audit_equal(ExpAudit[[nil,0],[t1,1],[t2,2]], app._results(t2).first)
1253
- assert_audit_equal(ExpAudit[[nil,0],[t1,1],[t3,2]], app._results(t3).first)
1254
- end
1255
-
1256
- #
1257
- # merge tests
1258
- #
1259
-
1260
- def test_run_merge
1261
- t1 = Task.new(&add_one)
1262
- t2 = Task.new(&add_one)
1263
- t3 = Task.new(&add_one)
1264
-
1265
- app.merge(t3, t1, t2)
1266
- with_options :debug => true do
1267
- t1.enq 0
1268
- t2.enq 10
1269
- app.run
1270
- end
1271
-
1272
- assert_equal [0,10,1,11], runlist
1273
-
1274
- assert_audits_equal([
1275
- ExpAudit[[nil,0],[t1,1],[t3,2]],
1276
- ExpAudit[[nil,10],[t2,11],[t3,12]]
1277
- ], app._results(t3))
1278
- end
1279
-
1280
- #
1281
- # run batched task tests
1282
- #
1283
-
1284
- def test_run_batched_task
1285
- t1 = Task.new('template') do |task, input|
1286
- runlist << input
1287
- input + task.config[:factor]
1288
- end
1289
- assert_equal 2, t1.batch.length
1290
-
1291
- t1_0 = t1.batch[0]
1292
- t1_1 = t1.batch[1]
1293
-
1294
- assert_equal 10, t1_0.config[:factor]
1295
- assert_equal 22, t1_1.config[:factor]
1296
-
1297
- with_options :debug => true do
1298
- t1.enq 0
1299
- app.run
1300
- end
1301
-
1302
- # note same input fed to each template
1303
- assert_equal [0,0], runlist
1304
-
1305
- assert_audits_equal([
1306
- ExpAudit[[nil,0],[t1_0,10]],
1307
- ExpAudit[[nil,0],[t1_1,22]]
1308
- ], app._results(*t1.batch))
1309
- end
1310
-
1311
- def test_run_batched_task_with_existing_audit_trails
1312
- t1 = Task.new('template') do |task, input|
1313
- runlist << input
1314
- input + task.config[:factor]
1315
- end
1316
- assert_equal 2, t1.batch.length
1317
-
1318
- t1_0 = t1.batch[0]
1319
- t1_1 = t1.batch[1]
1320
-
1321
- assert_equal 10, t1_0.config[:factor]
1322
- assert_equal 22, t1_1.config[:factor]
1323
-
1324
- a = Support::Audit.new(0, :a)
1325
- with_options :debug => true do
1326
- t1.enq a
1327
- app.run
1328
- end
1329
-
1330
- # note same input fed to each template
1331
- assert_equal [0,0], runlist
1332
-
1333
- assert_audits_equal([
1334
- ExpAudit[[:a,0],[t1_0,10]],
1335
- ExpAudit[[:a,0],[t1_1,22]]
1336
- ], app._results(t1.batch))
1337
- end
1338
-
1339
- # TODO -- JRuby inconsistent test
1340
- # RESOLVED? 2007/01/30
1341
- def test_multithread_batched_tasks_execute_cosynchronously
1342
- extended_test do
1343
- lock = Monitor.new
1344
- max_threads = 0
1345
- n_threads = 0
1346
-
1347
- block = lambda do |task|
1348
- lock.synchronize do
1349
- n_threads += 1
1350
- max_threads = n_threads if n_threads > max_threads
1351
- end
1352
-
1353
- # sleep is necessary so the other threads
1354
- # have an opportunity to execute
1355
- sleep(0.1)
1356
-
1357
- lock.synchronize { n_threads -= 1 }
1358
- nil
1359
- end
1360
-
1361
- t1 = Task.new(&block)
1362
- t1.initialize_batch_obj
1363
-
1364
- assert_equal 2, t1.batch.length
1365
- t1.multithread = true
1366
- t1.enq
1367
-
1368
- with_options :debug => true do
1369
- app.run
1370
- end
1371
- assert_equal 2, max_threads
1372
- end
1373
- end
1374
-
1375
- def test_fork_in_batched_task
1376
- t1, t2, t3 = Array.new(3) do
1377
- t = Task.new(nil, :factor => 10) do |task, input|
1378
- runlist << input
1379
- input + task.config[:factor]
1380
- end
1381
- t.initialize_batch_obj(nil, :factor => 22)
1382
- end
1383
-
1384
- app.fork(t1, t2, t3)
1385
- with_options :debug => true do
1386
- t1.enq 0
1387
- app.run
1388
- end
1389
-
1390
- assert_equal [
1391
- 0,0, # once for each t1 template
1392
- 10,10, 10,10, # first result into t2, t3 tasks
1393
- 22,22, 22,22 # second result into t2, t3 tasks
1394
- ], runlist
1395
-
1396
- t1_0 = t1.batch[0]
1397
- t1_1 = t1.batch[1]
1398
-
1399
- t2_0 = t2.batch[0]
1400
- t2_1 = t2.batch[1]
1401
-
1402
- t3_0 = t3.batch[0]
1403
- t3_1 = t3.batch[1]
1404
-
1405
- # check t2 results
1406
- assert_audits_equal([
1407
- ExpAudit[[nil,0],[t1_0,10],[t2_0,20]],
1408
- ExpAudit[[nil,0],[t1_1,22],[t2_0,32]],
1409
- ExpAudit[[nil,0],[t1_0,10],[t2_1,32]],
1410
- ExpAudit[[nil,0],[t1_1,22],[t2_1,44]]
1411
- ], app._results(t2.batch))
1412
-
1413
- # check t3 results
1414
- assert_audits_equal([
1415
- ExpAudit[[nil,0],[t1_0,10],[t3_0,20]],
1416
- ExpAudit[[nil,0],[t1_1,22],[t3_0,32]],
1417
- ExpAudit[[nil,0],[t1_0,10],[t3_1,32]],
1418
- ExpAudit[[nil,0],[t1_1,22],[t3_1,44]]
1419
- ], app._results(t3.batch))
1420
- end
1421
-
1422
- def test_merge_batched_task
1423
- t1, t2, t3 = Array.new(3) do
1424
- t = Task.new(nil, :factor => 10) do |task, input|
1425
- runlist << input
1426
- input + task.config[:factor]
1427
- end
1428
- t.initialize_batch_obj(nil, :factor => 22)
1429
- end
1430
-
1431
- app.merge(t3, t1, t2)
1432
- t1.enq(0)
1433
- t2.enq(2)
1434
- with_options :debug => true do
1435
- app.run
1436
- end
1437
-
1438
- assert_equal [
1439
- 0,0, # 1 input to each t1
1440
- 2,2, # 2 input to each t2
1441
- 10,10,22,22, # t1 outputs to each t3
1442
- 12,12,24,24 # t2 outputs to each t3
1443
- ], runlist
1444
-
1445
- t1_0 = t1.batch[0]
1446
- t1_1 = t1.batch[1]
1447
-
1448
- t2_0 = t2.batch[0]
1449
- t2_1 = t2.batch[1]
1450
-
1451
- t3_0 = t3.batch[0]
1452
- t3_1 = t3.batch[1]
1453
-
1454
- # check results
1455
- assert_audits_equal([
1456
- ExpAudit[[nil,0],[t1_0,10],[t3_0,20]],
1457
- ExpAudit[[nil,0],[t1_1,22],[t3_0,32]],
1458
- ExpAudit[[nil,2],[t2_0,12],[t3_0,22]],
1459
- ExpAudit[[nil,2],[t2_1,24],[t3_0,34]],
1460
- ExpAudit[[nil,0],[t1_0,10],[t3_1,32]],
1461
- ExpAudit[[nil,0],[t1_1,22],[t3_1,44]],
1462
- ExpAudit[[nil,2],[t2_0,12],[t3_1,34]],
1463
- ExpAudit[[nil,2],[t2_1,24],[t3_1,46]]
1464
- ], app._results(t3.batch))
1465
- end
1466
-
1467
- #
1468
- # other run tests
1469
- #
1470
-
1471
- def test_feedback_loop
1472
- t1 = Task.new(&add_one)
1473
- t2 = Task.new(&add_one)
1474
- t3 = Task.new(&add_one)
1475
-
1476
- # distribute the results of t1 based on value
1477
- t1.on_complete do |result|
1478
- if result._current < 4
1479
- t2.enq result
1480
- else
1481
- t3.enq result
1482
- end
1483
- end
1484
-
1485
- # set the results of t2 to reinvoke the workflow
1486
- app.sequence(t2, t1)
1487
-
1488
- with_options :debug => true do
1489
- t1.enq(0)
1490
- t1.enq(2)
1491
- app.run
1492
- end
1493
-
1494
- assert_equal [0,2,1,3,2,4,3,5,4,5], runlist
1495
-
1496
- assert_audits_equal([
1497
- ExpAudit[[nil,2],[t1,3],[t2,4],[t1,5],[t3,6]],
1498
- ExpAudit[[nil,0],[t1,1],[t2,2],[t1,3],[t2,4],[t1,5],[t3,6]]
1499
- ], app._results(t3.batch))
1500
- end
1501
-
1502
- #
1503
- # _results test
1504
- #
1505
-
1506
- def test__results_returns_audited_results_for_listed_sources
1507
- t1 = Task.new {|task, input| input + 1 }
1508
- a1 = t1._execute(0)
1509
-
1510
- t2 = Task.new {|task, input| input + 1 }
1511
- a2 = t2._execute(1)
1512
-
1513
- app.aggregator.store a1
1514
- app.aggregator.store a2
1515
- assert_equal [a1], app._results(t1)
1516
- assert_equal [a2, a1], app._results(t2, t1)
1517
- assert_equal [a1, a1], app._results(t1, t1)
1518
- end
1519
-
1520
- #
1521
- # results test
1522
- #
1523
-
1524
- def test_results_documentation
1525
- t1 = Task.new {|task, input| input += 1 }
1526
- t2 = Task.new {|task, input| input += 10 }
1527
- t3 = t2.initialize_batch_obj
1528
-
1529
- t1.enq(0)
1530
- t2.enq(1)
1531
-
1532
- app.run
1533
- assert_equal [1, 11, 11], app.results(t1, t2.batch)
1534
- assert_equal [11, 1], app.results(t2, t1)
1535
- end
1536
-
1537
- def test_results_returns_current_values_of__results
1538
- t1 = Task.new {|task, input| input + 1 }
1539
- a1 = t1._execute(0)
1540
-
1541
- t2 = Task.new {|task, input| input + 1 }
1542
- a2 = t2._execute(1)
1543
-
1544
- app.aggregator.store a1
1545
- app.aggregator.store a2
1546
- assert_equal [1], app.results(t1)
1547
- assert_equal [2, 1], app.results(t2, t1)
1548
- assert_equal [1, 1], app.results(t1, t1)
1549
- end
1550
-
1551
- def test_results_for_various_objects
1552
- t1 = Task.new {|task, input| input}
1553
-
1554
- t1.enq({:key => 'value'})
1555
- t1.enq([1,2,3])
1556
- t1.enq(2)
1557
- t1.enq("str")
1558
-
1559
- app.run
1560
- assert_equal [{:key => 'value'}, [1,2,3], 2, "str"], app.results(t1)
1561
- end
1562
-
1563
- #
1564
- # synchronization tests
1565
- #
1566
-
1567
- def test_task_may_be_queued_from_task_while_task_is_running
1568
- count = 0
1569
- counter = Task.new do |task|
1570
- count += 1
1571
- counter.enq if count < 3
1572
- end
1573
-
1574
- with_options :debug => true do
1575
- counter.enq
1576
- app.run
1577
- end
1578
-
1579
- assert_equal 3, count
1580
- end
1581
-
1582
- def test_task_can_queue_from_within_threaded_and_unthreaded_tasks
1583
- threaded_count = 0
1584
- threaded = Task.new do |task|
1585
- runlist << "t"
1586
- threaded_count += 1
1587
- threaded.enq if threaded_count < 3
1588
- end
1589
-
1590
- not_threaded_count = 0
1591
- not_threaded = Task.new do |task|
1592
- runlist << "n"
1593
- not_threaded_count += 1
1594
- not_threaded.enq if not_threaded_count < 3
1595
- end
1596
-
1597
- threaded.multithread = true
1598
- threaded.enq
1599
- not_threaded.enq
1600
-
1601
- with_options :debug => true do
1602
- app.run
1603
- end
1604
-
1605
- assert_equal [
1606
- "t", "n",
1607
- "t", "n",
1608
- "t", "n"], runlist
1609
- assert_equal 3, threaded_count
1610
- assert_equal 3, not_threaded_count
1611
- end
1612
-
1613
- def test_run_is_allowed_within_non_threaded_task
1614
- t2 = Task.new(&add_one)
1615
- t1 = Task.new do |task, input|
1616
- runlist << input
1617
- t2.enq input
1618
- app.run
1619
-
1620
- input += 1
1621
- end
1622
-
1623
- with_options :debug => true do
1624
- t1.enq 0
1625
- app.run
1626
- end
1627
-
1628
- assert_equal [0,0], runlist
1629
- assert_audit_equal(ExpAudit[[nil,0],[t1,1]], app._results(t1).first)
1630
- assert_audit_equal(ExpAudit[[nil,0],[t2,1]], app._results(t2).first)
1631
- end
1632
-
1633
- def test_run_is_allowed_within_threaded_task
1634
- t2 = Task.new(&add_one)
1635
- t1 = Task.new do |task, input|
1636
- runlist << input
1637
- t2.enq input
1638
- app.run
1639
-
1640
- input += 1
1641
- end
1642
-
1643
- t1.multithread = true
1644
- t2.multithread = true
1645
- with_options :debug => true do
1646
- t1.enq 0
1647
- app.run
1648
- end
1649
-
1650
- assert_equal [0,0], runlist
1651
- assert_audit_equal(ExpAudit[[nil,0],[t1,1]], app._results(t1).first)
1652
- assert_audit_equal(ExpAudit[[nil,0],[t2,1]], app._results(t2).first)
1653
- end
1654
-
1655
- #
1656
- # error tests
1657
- #
1658
-
1659
- def set_stringio_logger
1660
- output = StringIO.new('')
1661
- app.logger = Logger.new(output)
1662
- output.string
1663
- end
1664
-
1665
- def test_unhandled_exception_on_main_thread_is_logged_by_default
1666
- task = Task.new {|t| raise "error"}
1667
-
1668
- string = set_stringio_logger
1669
- task.enq
1670
- app.run
1671
-
1672
- assert string =~ /RuntimeError error/
1673
- end
1674
-
1675
- def test_unhandled_exception_raises_run_error_on_main_thread_when_debug
1676
- task = Task.new {|t| raise "error"}
1677
-
1678
- with_options :debug => true do
1679
- begin
1680
- task.enq
1681
- app.run
1682
- flunk "no error was raised"
1683
- rescue
1684
- assert $!.kind_of?(Tap::Support::RunError)
1685
- assert_equal 1 , $!.errors.length
1686
- assert $!.errors[0].kind_of?(RuntimeError)
1687
- assert_equal "error", $!.errors[0].message
1688
- end
1689
- end
1690
- end
1691
-
1692
- def test_unhandled_exception_on_thread_is_logged_by_default
1693
- task = Task.new {|t| raise "error"}
1694
- task.multithread = true
1695
-
1696
- string = set_stringio_logger
1697
- task.enq
1698
- app.run
1699
-
1700
- assert string =~ /RuntimeError error/
1701
- end
1702
-
1703
- # Ruby inconsistent test
1704
- # <"error"> expected but was
1705
- # <"Tap::App::TerminateError">.
1706
- # RESOLVED? -- 2008/01/29
1707
- #
1708
- def test_unhandled_exception_raises_run_error_on_thread_when_debug
1709
- task = Task.new {|t| raise "error"}
1710
- task.multithread = true
1711
-
1712
- with_options :debug => true do
1713
- begin
1714
- task.enq
1715
- app.run
1716
- flunk "no error was raised"
1717
- rescue
1718
- assert $!.kind_of?(Tap::Support::RunError)
1719
- assert_equal 1 , $!.errors.length
1720
- assert $!.errors[0].kind_of?(RuntimeError)
1721
- assert_equal "error", $!.errors[0].message
1722
- end
1723
- end
1724
- end
1725
-
1726
- # Ruby inconsistent test
1727
- # <"error"> expected but was
1728
- # <"Tap::App::TerminateError">.
1729
- # RESOLVED? -- 2008/01/29
1730
- #
1731
- def test_unhandled_exception_on_thread_teminates_threads
1732
- extended_test do
1733
- count = 0
1734
- terminated_count = 0
1735
-
1736
- tasks = Array.new(2) do
1737
- Task.new do |t|
1738
- # count to make sure the tasks actually executed
1739
- count += 1
1740
-
1741
- terminated_count += 1
1742
- sleep 0.8
1743
- t.check_terminate
1744
-
1745
- # this should not happen
1746
- terminated_count -= 1
1747
- end
1748
- end
1749
- terr = Task.new {|t| raise "error"}
1750
-
1751
- tasks << terr
1752
- tasks.each do |task|
1753
- task.multithread = true
1754
- task.enq
1755
- end
1756
-
1757
- with_options :debug => true do
1758
- begin
1759
- app.run
1760
- flunk "no error was raised"
1761
- rescue
1762
- assert $!.kind_of?(Tap::Support::RunError)
1763
- assert_equal 1 , $!.errors.length
1764
- assert $!.errors[0].kind_of?(RuntimeError)
1765
- assert_equal "error", $!.errors[0].message
1766
- end
1767
- end
1768
-
1769
- assert_equal 2, count
1770
- assert_equal 2, terminated_count
1771
- end
1772
- end
1773
-
1774
- # Ruby inconsistent test
1775
- # <"error"> expected but was
1776
- # <"Tap::App::TerminateError">.
1777
- #
1778
- # <"term error 0"> expected but was
1779
- # <"term error 1">.
1780
- # RESOLVED? -- 2008/01/29
1781
- #
1782
- # JRuby inconsistent test
1783
- # RESOLVED? -- 2008/01/30
1784
- #
1785
- def test_exceptions_from_handling_termination_error_are_collected
1786
- extended_test do
1787
- lock = Monitor.new
1788
- count = 0
1789
- count_in_threaded_error_handling = 0
1790
-
1791
- tasks = Array.new(2) do
1792
- Task.new do |t|
1793
- n = nil
1794
- lock.synchronize do
1795
- n = count
1796
- count += 1
1797
- end
1798
-
1799
- sleep 0.8
1800
-
1801
- begin
1802
- t.check_terminate
1803
- rescue
1804
- lock.synchronize { count_in_threaded_error_handling += 1 }
1805
- raise "term error #{n}"
1806
- end
1807
- end
1808
- end
1809
- terr = Task.new {|t| raise "error"}
1810
-
1811
- tasks << terr
1812
- tasks.each do |task|
1813
- task.multithread = true
1814
- task.enq
1815
- end
1816
-
1817
- with_options :debug => true do
1818
- begin
1819
- app.run
1820
- flunk "no error was raised"
1821
- rescue
1822
- assert $!.kind_of?(Tap::Support::RunError)
1823
- assert_equal 3, $!.errors.length
1824
- $!.errors.each {|error| assert error.kind_of?(RuntimeError) }
1825
- messages = $!.errors.collect {|error| error.message}.sort
1826
- assert_equal ["error", "term error 0", "term error 1"], messages
1827
- end
1828
-
1829
- assert_equal 2, count
1830
- assert_equal 2, count_in_threaded_error_handling
1831
- end
1832
- end
1833
- end
1834
-
1835
- #
1836
- # benchmarks
1837
- #
1838
-
1839
- def test_run_speed
1840
- t = Tap::Task.new
1841
- benchmark_test(20) do |x|
1842
- n = 10000
1843
-
1844
- x.report("10k enq ") { n.times { t.enq(1) } }
1845
- x.report("10k run ") { n.times {}; app.run }
1846
- x.report("10k _execute ") { n.times { t._execute(1) } }
1847
- end
1848
- end
1849
- end