tap 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History +37 -30
- data/MIT-LICENSE +1 -1
- data/README +92 -44
- data/bin/tap +62 -75
- data/cmd/console.rb +42 -0
- data/cmd/destroy.rb +16 -0
- data/cmd/generate.rb +16 -0
- data/cmd/run.rb +126 -0
- data/doc/Class Reference +362 -0
- data/doc/Command Reference +153 -0
- data/doc/Tutorial +237 -0
- data/lib/tap.rb +6 -45
- data/lib/tap/app.rb +126 -500
- data/lib/tap/constants.rb +2 -29
- data/lib/tap/env.rb +555 -250
- data/lib/tap/file_task.rb +60 -103
- data/lib/tap/generator/base.rb +109 -0
- data/lib/tap/generator/destroy.rb +37 -0
- data/lib/tap/generator/generate.rb +61 -0
- data/lib/tap/generator/generators/command/command_generator.rb +16 -12
- data/lib/tap/generator/generators/command/templates/command.erb +13 -19
- data/lib/tap/generator/generators/config/config_generator.rb +18 -27
- data/lib/tap/generator/generators/config/templates/doc.erb +12 -0
- data/lib/tap/generator/generators/config/templates/nodoc.erb +8 -0
- data/lib/tap/generator/generators/file_task/file_task_generator.rb +16 -11
- data/lib/tap/generator/generators/file_task/templates/file.txt +11 -2
- data/lib/tap/generator/generators/file_task/templates/result.yml +6 -0
- data/lib/tap/generator/generators/file_task/templates/task.erb +24 -31
- data/lib/tap/generator/generators/file_task/templates/test.erb +18 -22
- data/lib/tap/generator/generators/root/root_generator.rb +45 -31
- data/lib/tap/generator/generators/root/templates/Rakefile +64 -41
- data/lib/tap/generator/generators/root/templates/gemspec +27 -0
- data/lib/tap/generator/generators/root/templates/tapfile +8 -0
- data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -0
- data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +1 -1
- data/lib/tap/generator/generators/root/templates/test/tapfile_test.rb +15 -0
- data/lib/tap/generator/generators/task/task_generator.rb +21 -28
- data/lib/tap/generator/generators/task/templates/task.erb +13 -23
- data/lib/tap/generator/generators/task/templates/test.erb +15 -18
- data/lib/tap/generator/manifest.rb +14 -0
- data/lib/tap/patches/rake/rake_test_loader.rb +0 -0
- data/lib/tap/patches/rake/testtask.rb +0 -0
- data/lib/tap/patches/ruby19/backtrace_filter.rb +0 -0
- data/lib/tap/patches/ruby19/parsedate.rb +0 -0
- data/lib/tap/root.rb +260 -21
- data/lib/tap/support/aggregator.rb +11 -11
- data/lib/tap/support/assignments.rb +172 -0
- data/lib/tap/support/audit.rb +20 -18
- data/lib/tap/support/batchable.rb +21 -10
- data/lib/tap/support/batchable_class.rb +107 -0
- data/lib/tap/support/class_configuration.rb +154 -239
- data/lib/tap/support/command_line.rb +97 -102
- data/lib/tap/support/comment.rb +270 -0
- data/lib/tap/support/configurable.rb +86 -65
- data/lib/tap/support/configurable_class.rb +296 -0
- data/lib/tap/support/configuration.rb +122 -0
- data/lib/tap/support/constant.rb +70 -0
- data/lib/tap/support/constant_utils.rb +127 -0
- data/lib/tap/support/declarations.rb +111 -0
- data/lib/tap/support/executable.rb +30 -17
- data/lib/tap/support/executable_queue.rb +0 -0
- data/lib/tap/support/framework.rb +71 -0
- data/lib/tap/support/framework_class.rb +199 -0
- data/lib/tap/support/instance_configuration.rb +147 -0
- data/lib/tap/support/lazydoc.rb +428 -0
- data/lib/tap/support/manifest.rb +89 -0
- data/lib/tap/support/run_error.rb +0 -0
- data/lib/tap/support/shell_utils.rb +33 -9
- data/lib/tap/support/summary.rb +30 -0
- data/lib/tap/support/tdoc.rb +339 -134
- data/lib/tap/support/tdoc/tdoc_html_generator.rb +0 -0
- data/lib/tap/support/tdoc/tdoc_html_template.rb +0 -0
- data/lib/tap/support/templater.rb +180 -0
- data/lib/tap/support/validation.rb +409 -76
- data/lib/tap/support/versions.rb +5 -3
- data/lib/tap/task.rb +78 -174
- data/lib/tap/tasks/dump.rb +56 -0
- data/lib/tap/tasks/rake.rb +93 -0
- data/lib/tap/test.rb +3 -3
- data/lib/tap/test/env_vars.rb +2 -2
- data/lib/tap/test/file_methods.rb +19 -20
- data/lib/tap/test/script_methods.rb +144 -0
- data/lib/tap/test/subset_methods.rb +1 -1
- data/lib/tap/test/tap_methods.rb +28 -62
- data/lib/tap/workflow.rb +22 -39
- metadata +48 -179
- data/Basic Overview +0 -151
- data/Command Reference +0 -99
- data/Rakefile +0 -127
- data/Tutorial +0 -287
- data/lib/tap/cmd/console.rb +0 -31
- data/lib/tap/cmd/destroy.rb +0 -20
- data/lib/tap/cmd/generate.rb +0 -20
- data/lib/tap/cmd/run.rb +0 -151
- data/lib/tap/dump.rb +0 -57
- data/lib/tap/generator.rb +0 -91
- data/lib/tap/generator/generators/command/USAGE +0 -6
- data/lib/tap/generator/generators/config/USAGE +0 -21
- data/lib/tap/generator/generators/config/templates/config.erb +0 -1
- data/lib/tap/generator/generators/file_task/USAGE +0 -3
- data/lib/tap/generator/generators/file_task/templates/file.yml +0 -3
- data/lib/tap/generator/generators/generator/USAGE +0 -0
- data/lib/tap/generator/generators/generator/generator_generator.rb +0 -21
- data/lib/tap/generator/generators/generator/templates/generator.erb +0 -32
- data/lib/tap/generator/generators/generator/templates/usage.erb +0 -1
- data/lib/tap/generator/generators/root/USAGE +0 -0
- data/lib/tap/generator/generators/root/templates/ReadMe.txt +0 -0
- data/lib/tap/generator/generators/root/templates/tap.yml +0 -80
- data/lib/tap/generator/generators/task/USAGE +0 -3
- data/lib/tap/generator/generators/workflow/USAGE +0 -0
- data/lib/tap/generator/generators/workflow/templates/task.erb +0 -16
- data/lib/tap/generator/generators/workflow/templates/test.erb +0 -7
- data/lib/tap/generator/generators/workflow/workflow_generator.rb +0 -6
- data/lib/tap/generator/options.rb +0 -26
- data/lib/tap/generator/usage.rb +0 -26
- data/lib/tap/support/batchable_methods.rb +0 -34
- data/lib/tap/support/command_line_methods.rb +0 -76
- data/lib/tap/support/configurable_methods.rb +0 -224
- data/lib/tap/support/logger.rb +0 -88
- data/lib/tap/support/rake.rb +0 -43
- data/lib/tap/support/tdoc/config_attr.rb +0 -362
- data/test/app/config/another/task.yml +0 -1
- data/test/app/config/batch.yml +0 -2
- data/test/app/config/empty.yml +0 -0
- data/test/app/config/erb.yml +0 -2
- data/test/app/config/some/task.yml +0 -1
- data/test/app/config/template.yml +0 -2
- data/test/app/config/version-0.1.yml +0 -1
- data/test/app/config/version.yml +0 -1
- data/test/app/lib/app_test_task.rb +0 -3
- data/test/app_test.rb +0 -1849
- data/test/env/test_configure/recurse_a.yml +0 -2
- data/test/env/test_configure/recurse_b.yml +0 -2
- data/test/env/test_configure/tap.yml +0 -23
- data/test/env/test_load_env_config/dir/tap.yml +0 -3
- data/test/env/test_load_env_config/recurse_a.yml +0 -2
- data/test/env/test_load_env_config/recurse_b.yml +0 -2
- data/test/env/test_load_env_config/tap.yml +0 -3
- data/test/env_test.rb +0 -198
- data/test/file_task/config/batch.yml +0 -2
- data/test/file_task/config/configured.yml +0 -1
- data/test/file_task/old_file_one.txt +0 -0
- data/test/file_task/old_file_two.txt +0 -0
- data/test/file_task_test.rb +0 -1291
- data/test/root/alt_lib/alt_module.rb +0 -4
- data/test/root/file.txt +0 -0
- data/test/root/glob/one.txt +0 -0
- data/test/root/glob/two.txt +0 -0
- data/test/root/lib/absolute_alt_filepath.rb +0 -2
- data/test/root/lib/alternative_filepath.rb +0 -2
- data/test/root/lib/another_module.rb +0 -2
- data/test/root/lib/nested/some_module.rb +0 -4
- data/test/root/lib/no_module_included.rb +0 -0
- data/test/root/lib/some/module.rb +0 -4
- data/test/root/lib/some_class.rb +0 -2
- data/test/root/lib/some_module.rb +0 -3
- data/test/root/load_path/load_path_module.rb +0 -2
- data/test/root/load_path/skip_module.rb +0 -2
- data/test/root/mtime/older.txt +0 -0
- data/test/root/unload/full_path.rb +0 -2
- data/test/root/unload/loaded_by_nested.rb +0 -2
- data/test/root/unload/nested/nested_load.rb +0 -6
- data/test/root/unload/nested/nested_with_ext.rb +0 -4
- data/test/root/unload/nested/relative_path.rb +0 -4
- data/test/root/unload/older.rb +0 -2
- data/test/root/unload/unload_base.rb +0 -9
- data/test/root/versions/another.yml +0 -0
- data/test/root/versions/file-0.1.2.yml +0 -0
- data/test/root/versions/file-0.1.yml +0 -0
- data/test/root/versions/file.yml +0 -0
- data/test/root_test.rb +0 -718
- data/test/support/aggregator_test.rb +0 -99
- data/test/support/audit_test.rb +0 -445
- data/test/support/batchable_test.rb +0 -74
- data/test/support/class_configuration_test.rb +0 -331
- data/test/support/command_line_test.rb +0 -58
- data/test/support/configurable/config/configured.yml +0 -2
- data/test/support/configurable_test.rb +0 -295
- data/test/support/executable_queue_test.rb +0 -103
- data/test/support/executable_test.rb +0 -38
- data/test/support/logger_test.rb +0 -31
- data/test/support/rake_test.rb +0 -37
- data/test/support/shell_utils_test.rb +0 -24
- data/test/support/tdoc_test.rb +0 -370
- data/test/support/validation_test.rb +0 -54
- data/test/support/versions_test.rb +0 -103
- data/test/tap_test_helper.rb +0 -57
- data/test/tap_test_suite.rb +0 -7
- data/test/task/config/batch.yml +0 -2
- data/test/task/config/batched.yml +0 -2
- data/test/task/config/configured.yml +0 -1
- data/test/task/config/example.yml +0 -1
- data/test/task_base_test.rb +0 -24
- data/test/task_syntax_test.rb +0 -300
- data/test/task_test.rb +0 -320
- data/test/test/env_vars_test.rb +0 -48
- data/test/test/file_methods/test_assert_files/expected/one.txt +0 -1
- data/test/test/file_methods/test_assert_files/expected/two.txt +0 -1
- data/test/test/file_methods/test_assert_files/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_can_have_no_expected_files_if_specified/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_can_have_no_expected_files_if_specified/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_different_content/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_different_content/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/expected/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/two.txt +0 -1
- data/test/test/file_methods/test_method_glob/expected/file.yml +0 -0
- data/test/test/file_methods/test_method_glob/expected/file_1.txt +0 -0
- data/test/test/file_methods/test_method_glob/expected/file_2.txt +0 -0
- data/test/test/file_methods_doc/test_sub/expected/one.txt +0 -1
- data/test/test/file_methods_doc/test_sub/expected/two.txt +0 -1
- data/test/test/file_methods_doc/test_sub/input/one.txt +0 -1
- data/test/test/file_methods_doc/test_sub/input/two.txt +0 -1
- data/test/test/file_methods_doc_test.rb +0 -29
- data/test/test/file_methods_test.rb +0 -275
- data/test/test/subset_methods_test.rb +0 -171
- data/test/test/tap_methods/test_assert_files/expected/task/name/a.txt +0 -1
- data/test/test/tap_methods/test_assert_files/expected/task/name/b.txt +0 -1
- data/test/test/tap_methods/test_assert_files/input/a.txt +0 -1
- data/test/test/tap_methods/test_assert_files/input/b.txt +0 -1
- data/test/test/tap_methods_test.rb +0 -399
- data/test/workflow_test.rb +0 -120
- data/vendor/rails_generator.rb +0 -56
- data/vendor/rails_generator/base.rb +0 -263
- data/vendor/rails_generator/commands.rb +0 -581
- data/vendor/rails_generator/generated_attribute.rb +0 -42
- data/vendor/rails_generator/lookup.rb +0 -209
- data/vendor/rails_generator/manifest.rb +0 -53
- data/vendor/rails_generator/options.rb +0 -143
- data/vendor/rails_generator/scripts.rb +0 -83
- data/vendor/rails_generator/scripts/destroy.rb +0 -7
- data/vendor/rails_generator/scripts/generate.rb +0 -7
- data/vendor/rails_generator/scripts/update.rb +0 -12
- data/vendor/rails_generator/simple_logger.rb +0 -46
- data/vendor/rails_generator/spec.rb +0 -44
|
@@ -1 +0,0 @@
|
|
|
1
|
-
key: two
|
data/test/app/config/batch.yml
DELETED
data/test/app/config/empty.yml
DELETED
|
File without changes
|
data/test/app/config/erb.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
key: one
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version: 0.1
|
data/test/app/config/version.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version: empty
|
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
|