scout-gear 7.3.0 → 8.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +44 -16
  3. data/Rakefile +6 -1
  4. data/VERSION +1 -1
  5. data/bin/scout +21 -7
  6. data/doc/lib/scout/path.md +35 -0
  7. data/doc/lib/scout/workflow/task.md +13 -0
  8. data/lib/rbbt-scout.rb +1 -0
  9. data/lib/scout/cmd.rb +24 -25
  10. data/lib/scout/concurrent_stream.rb +59 -39
  11. data/lib/scout/config.rb +1 -1
  12. data/lib/scout/exceptions.rb +10 -0
  13. data/lib/scout/log/color.rb +15 -12
  14. data/lib/scout/log/progress/report.rb +8 -6
  15. data/lib/scout/log/progress/util.rb +61 -54
  16. data/lib/scout/log/progress.rb +1 -1
  17. data/lib/scout/log/trap.rb +107 -0
  18. data/lib/scout/log.rb +115 -52
  19. data/lib/scout/meta_extension.rb +47 -6
  20. data/lib/scout/misc/digest.rb +12 -3
  21. data/lib/scout/misc/format.rb +24 -7
  22. data/lib/scout/misc/insist.rb +1 -1
  23. data/lib/scout/misc/monitor.rb +22 -0
  24. data/lib/scout/misc/system.rb +58 -0
  25. data/lib/scout/named_array.rb +73 -3
  26. data/lib/scout/offsite/ssh.rb +171 -0
  27. data/lib/scout/offsite/step.rb +83 -0
  28. data/lib/scout/offsite/sync.rb +55 -0
  29. data/lib/scout/offsite.rb +3 -0
  30. data/lib/scout/open/lock/lockfile.rb +587 -0
  31. data/lib/scout/open/lock.rb +9 -2
  32. data/lib/scout/open/remote.rb +16 -1
  33. data/lib/scout/open/stream.rb +146 -83
  34. data/lib/scout/open/util.rb +22 -3
  35. data/lib/scout/open.rb +5 -4
  36. data/lib/scout/path/find.rb +24 -11
  37. data/lib/scout/path/util.rb +40 -0
  38. data/lib/scout/persist/serialize.rb +19 -6
  39. data/lib/scout/persist.rb +29 -13
  40. data/lib/scout/resource/path.rb +57 -0
  41. data/lib/scout/resource/produce.rb +0 -8
  42. data/lib/scout/resource/util.rb +12 -5
  43. data/lib/scout/tmpfile.rb +7 -8
  44. data/lib/scout/tsv/attach.rb +177 -0
  45. data/lib/scout/tsv/change_id.rb +40 -0
  46. data/lib/scout/tsv/dumper.rb +74 -46
  47. data/lib/scout/tsv/index.rb +85 -87
  48. data/lib/scout/tsv/open.rb +160 -85
  49. data/lib/scout/tsv/parser.rb +142 -80
  50. data/lib/scout/tsv/path.rb +1 -2
  51. data/lib/scout/tsv/persist/adapter.rb +15 -45
  52. data/lib/scout/tsv/persist/fix_width_table.rb +3 -0
  53. data/lib/scout/tsv/persist/tokyocabinet.rb +6 -1
  54. data/lib/scout/tsv/persist.rb +4 -0
  55. data/lib/scout/tsv/stream.rb +204 -0
  56. data/lib/scout/tsv/transformer.rb +152 -0
  57. data/lib/scout/tsv/traverse.rb +96 -92
  58. data/lib/scout/tsv/util/filter.rb +9 -0
  59. data/lib/scout/tsv/util/reorder.rb +81 -0
  60. data/lib/scout/tsv/util/select.rb +78 -33
  61. data/lib/scout/tsv/util/unzip.rb +86 -0
  62. data/lib/scout/tsv/util.rb +60 -11
  63. data/lib/scout/tsv.rb +34 -4
  64. data/lib/scout/work_queue/socket.rb +6 -1
  65. data/lib/scout/work_queue/worker.rb +5 -2
  66. data/lib/scout/work_queue.rb +51 -20
  67. data/lib/scout/workflow/definition.rb +23 -3
  68. data/lib/scout/workflow/deployment/orchestrator.rb +245 -0
  69. data/lib/scout/workflow/deployment.rb +1 -0
  70. data/lib/scout/workflow/step/dependencies.rb +56 -10
  71. data/lib/scout/workflow/step/file.rb +5 -0
  72. data/lib/scout/workflow/step/info.rb +40 -7
  73. data/lib/scout/workflow/step/load.rb +1 -1
  74. data/lib/scout/workflow/step/provenance.rb +9 -7
  75. data/lib/scout/workflow/step/status.rb +43 -0
  76. data/lib/scout/workflow/step.rb +160 -49
  77. data/lib/scout/workflow/task/dependencies.rb +114 -0
  78. data/lib/scout/workflow/task/inputs.rb +40 -32
  79. data/lib/scout/workflow/task.rb +38 -102
  80. data/lib/scout/workflow/usage.rb +48 -18
  81. data/lib/scout/workflow.rb +4 -2
  82. data/lib/scout-gear.rb +2 -0
  83. data/lib/scout.rb +6 -0
  84. data/scout-gear.gemspec +52 -23
  85. data/scout_commands/doc +37 -0
  86. data/scout_commands/find +1 -0
  87. data/scout_commands/offsite +30 -0
  88. data/scout_commands/update +29 -0
  89. data/scout_commands/workflow/info +15 -3
  90. data/scout_commands/workflow/install +102 -0
  91. data/scout_commands/workflow/task +57 -9
  92. data/test/scout/offsite/test_ssh.rb +15 -0
  93. data/test/scout/offsite/test_step.rb +33 -0
  94. data/test/scout/offsite/test_sync.rb +36 -0
  95. data/test/scout/offsite/test_task.rb +0 -0
  96. data/test/scout/open/test_stream.rb +60 -58
  97. data/test/scout/path/test_find.rb +10 -1
  98. data/test/scout/resource/test_path.rb +6 -0
  99. data/test/scout/resource/test_produce.rb +15 -0
  100. data/test/scout/test_meta_extension.rb +25 -0
  101. data/test/scout/test_named_array.rb +24 -0
  102. data/test/scout/test_persist.rb +9 -2
  103. data/test/scout/test_tsv.rb +229 -2
  104. data/test/scout/test_work_queue.rb +65 -41
  105. data/test/scout/tsv/persist/test_tokyocabinet.rb +29 -1
  106. data/test/scout/tsv/test_attach.rb +227 -0
  107. data/test/scout/tsv/test_change_id.rb +98 -0
  108. data/test/scout/tsv/test_dumper.rb +1 -1
  109. data/test/scout/tsv/test_index.rb +49 -3
  110. data/test/scout/tsv/test_open.rb +160 -2
  111. data/test/scout/tsv/test_parser.rb +33 -2
  112. data/test/scout/tsv/test_persist.rb +2 -0
  113. data/test/scout/tsv/test_stream.rb +200 -0
  114. data/test/scout/tsv/test_transformer.rb +120 -0
  115. data/test/scout/tsv/test_traverse.rb +88 -3
  116. data/test/scout/tsv/test_util.rb +1 -0
  117. data/test/scout/tsv/util/test_reorder.rb +94 -0
  118. data/test/scout/tsv/util/test_select.rb +25 -11
  119. data/test/scout/tsv/util/test_unzip.rb +112 -0
  120. data/test/scout/work_queue/test_socket.rb +0 -1
  121. data/test/scout/workflow/deployment/test_orchestrator.rb +272 -0
  122. data/test/scout/workflow/step/test_dependencies.rb +68 -0
  123. data/test/scout/workflow/step/test_info.rb +18 -0
  124. data/test/scout/workflow/step/test_status.rb +30 -0
  125. data/test/scout/workflow/task/test_dependencies.rb +355 -0
  126. data/test/scout/workflow/task/test_inputs.rb +67 -14
  127. data/test/scout/workflow/test_definition.rb +18 -0
  128. data/test/scout/workflow/test_documentation.rb +24 -0
  129. data/test/scout/workflow/test_step.rb +112 -3
  130. data/test/scout/workflow/test_task.rb +0 -151
  131. data/test/scout/workflow/test_usage.rb +33 -6
  132. data/test/test_scout.rb +9 -0
  133. metadata +100 -8
  134. data/scout_commands/workflow/task_old +0 -706
@@ -0,0 +1,355 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ require 'scout/workflow'
5
+ class TestTaskDependencies < Test::Unit::TestCase
6
+ def test_task_override_dep_exec
7
+ wf = Workflow.annonymous_workflow "TaskInputs" do
8
+ input :input1, :integer
9
+ task :step1 => :integer do |i| i end
10
+
11
+ dep :step1
12
+ input :input2, :integer, "Integer", 3
13
+ task :step2 => :integer do |i| i * step(:step1).load end
14
+ end
15
+
16
+ assert_equal 6, wf.job(:step2, :input1 => 2, :input2 => 3).exec
17
+
18
+ step1_job = wf.job(:step1, :input1 => 6)
19
+ assert_equal 18, wf.job(:step2, :input1 => 2, "TaskInputs#step1" => step1_job).exec
20
+
21
+ assert_equal 18, wf.job(:step2, :input1 => 2, "TaskInputs#step1" => step1_job).exec
22
+
23
+ assert_equal 18, wf.job(:step2, "TaskInputs#step1" => step1_job).exec
24
+ end
25
+
26
+ def test_task_override_dep
27
+ wf = Workflow.annonymous_workflow "TaskInputs" do
28
+ input :input1, :integer
29
+ task :step1 => :integer do |i| i end
30
+
31
+ dep :step1
32
+ input :input2, :integer, "Integer", 3
33
+ task :step2 => :integer do |i| i * step(:step1).load end
34
+ end
35
+
36
+ assert_equal 6, wf.job(:step2, :input1 => 2, :input2 => 3).run
37
+
38
+ step1_job = wf.job(:step1, :input1 => 6)
39
+ assert_equal 18, wf.job(:step2, :input1 => 2, "TaskInputs#step1" => step1_job).run
40
+
41
+ assert_equal 18, wf.job(:step2, :input1 => 2, "TaskInputs#step1" => step1_job).run
42
+
43
+ assert_equal 18, wf.job(:step2, "TaskInputs#step1" => step1_job).run
44
+ end
45
+
46
+ def test_input_dep
47
+ wf = Workflow.annonymous_workflow "TaskInputs" do
48
+ input :v1, :integer
49
+ input :v2, :integer
50
+ task :sum => :integer do |v1,v2|
51
+ v1 + v2
52
+ end
53
+
54
+ input :input1, :integer
55
+ task :step1 => :integer do |i| i end
56
+
57
+ input :input2, :integer
58
+ task :step2 => :integer do |i| i end
59
+
60
+ dep :step1, :input1 => 2
61
+ dep :step2, :input2 => 3
62
+ dep :sum, :v1 => :step1, :v2 => :step2
63
+ task :my_sum => :integer do
64
+ dependencies.last.load
65
+ end
66
+
67
+ dep :my_sum
68
+ task :double => :integer do
69
+ step(:my_sum).load * 2
70
+ end
71
+ end
72
+
73
+ job = wf.job(:my_sum)
74
+ assert_equal 5, job.run
75
+ assert_equal Task::DEFAULT_NAME, job.name
76
+
77
+ job = wf.job(:double)
78
+ assert_equal Task::DEFAULT_NAME, job.name
79
+
80
+ step1 = wf.job(:step1, :input1 => 3)
81
+ assert_equal 3, step1.run
82
+ job = wf.job(:double, "TaskInputs#step1" => step1)
83
+ assert_equal 12, job.run
84
+ assert_not_equal Task::DEFAULT_NAME, job.name
85
+
86
+ step1 = wf.job(:step1, :input1 => 4)
87
+ assert_equal 4, step1.run
88
+ job = wf.job(:double, "TaskInputs#step1" => step1)
89
+ assert_equal 14, job.run
90
+ assert_not_equal Task::DEFAULT_NAME, job.name
91
+ end
92
+
93
+ def test_input_dep_override
94
+ wf = Workflow.annonymous_workflow "TaskInputs" do
95
+ input :v1, :integer
96
+ input :v2, :integer
97
+ task :sum => :integer do |v1,v2|
98
+ v1 + v2
99
+ end
100
+
101
+ input :input1, :integer
102
+ task :step1 => :integer do |i| i end
103
+
104
+ input :input2, :integer
105
+ task :step2 => :integer do |i| i end
106
+
107
+ dep :step1
108
+ dep :step2
109
+ task :my_sum => :integer do
110
+ dependencies.inject(0){|acc,d| acc += d.load }
111
+ end
112
+ end
113
+
114
+ step2 = wf.job(:step2, :input2 => 4)
115
+ job = wf.job(:my_sum, :input1 => 2, :input2 => 3, "TaskInputs#step2"=> step2)
116
+ assert_equal 6, job.exec
117
+
118
+ job = wf.job(:my_sum, :input1 => 2, :input2 => 3)
119
+ assert_equal 5, job.run
120
+
121
+ TmpFile.with_file(4) do |file|
122
+ job = wf.job(:my_sum, :input1 => 2, :input2 => 3, "TaskInputs#step2"=> file)
123
+ assert_equal 6, job.run
124
+ assert_not_equal Task::DEFAULT_NAME, job.name
125
+ end
126
+ end
127
+
128
+ def test_input_rename
129
+ wf = Workflow.annonymous_workflow "TaskInputs" do
130
+ input :v1, :integer
131
+ input :v2, :integer
132
+ task :sum => :integer do |v1,v2|
133
+ v1 + v2
134
+ end
135
+
136
+ input :vv1, :integer
137
+ input :vv2, :integer
138
+ dep :sum, :v1 => :vv1, :v2 => :vv2
139
+ task :my_sum => :integer do
140
+ dependencies.last.load
141
+ end
142
+ end
143
+
144
+ job = wf.job(:my_sum, :vv1 => 2, :vv2 => 3)
145
+ assert_equal 5, job.run
146
+ end
147
+
148
+ def test_defaults_in_dep_block
149
+ wf = Workflow.annonymous_workflow "TaskInputs" do
150
+ input :v1, :integer
151
+ input :v2, :integer
152
+ task :sum => :integer do |v1,v2|
153
+ v1 + v2
154
+ end
155
+
156
+ input :vv1, :integer
157
+ input :vv2, :integer, nil, 3
158
+ dep :sum, :v1 => :placeholder, :v2 => :placeholder do |jobname,options,dependencies|
159
+ raise "Non-numeric value where integer expected" unless Numeric === options[:vv1]
160
+ {inputs: {v1: options[:vv1], v2: options[:vv2]} }
161
+ end
162
+ task :my_sum => :integer do
163
+ dependencies.last.load
164
+ end
165
+ end
166
+
167
+ job = wf.job(:my_sum, :vv1 => "2")
168
+ assert_equal 5, job.run
169
+ end
170
+
171
+ def test_dependency_jobname
172
+ wf = Workflow.annonymous_workflow "TaskInputs" do
173
+ input :v1, :integer
174
+ input :v2, :integer
175
+ task :sum => :integer do |v1,v2|
176
+ v1 + v2
177
+ end
178
+
179
+ input :vv1, :integer
180
+ input :vv2, :integer
181
+ dep :sum, :v1 => :vv1, :v2 => :vv2, :jobname => "OTHER_NAME"
182
+ task :my_sum => :integer do
183
+ dependencies.last.load
184
+ end
185
+ end
186
+
187
+ job = wf.job(:my_sum, "TEST_NAME", :vv1 => 2, :vv2 => 3)
188
+ assert_equal 5, job.run
189
+ assert_equal "TEST_NAME", job.clean_name
190
+ assert_equal "OTHER_NAME", job.step(:sum).clean_name
191
+ end
192
+
193
+ def test_no_param_last_job
194
+ wf = Workflow.annonymous_workflow "TaskInputs" do
195
+ input :v1, :integer
196
+ input :v2, :integer
197
+ task :sum => :integer do |v1,v2|
198
+ v1 + v2
199
+ end
200
+
201
+ dep :sum
202
+ task :my_sum => :integer do
203
+ dependencies.last.load
204
+ end
205
+ end
206
+
207
+ job = wf.job(:my_sum, :v1 => 2, :v2 => "3")
208
+ assert_equal 5, job.run
209
+ refute_equal Task::DEFAULT_NAME, job.name
210
+ end
211
+
212
+ def test_no_param_last_job_block
213
+ wf = Workflow.annonymous_workflow "TaskInputs" do
214
+ input :v1, :integer
215
+ input :v2, :integer
216
+ task :sum => :integer do |v1,v2|
217
+ v1 + v2
218
+ end
219
+
220
+ dep :sum do |jobname,options|
221
+ {inputs: options}
222
+ end
223
+ task :my_sum => :integer do
224
+ dependencies.last.load
225
+ end
226
+ end
227
+
228
+ job = wf.job(:my_sum, :v1 => 2, :v2 => "3")
229
+ assert_equal 5, job.run
230
+ refute_equal Task::DEFAULT_NAME, job.name
231
+ end
232
+
233
+
234
+ def test_override_inputs_block
235
+ wf = Workflow.annonymous_workflow "TaskInputs" do
236
+ input :input1, :string
237
+ task :step1 => :string do |i| i end
238
+
239
+ dep :step1, :input1 => 1 do |id,options|
240
+ {:inputs => options}
241
+ end
242
+ task :step2 => :string do |i| step(:step1).load end
243
+ end
244
+
245
+ job = wf.job(:step2, :input1 => 2)
246
+ assert_equal 1, job.run
247
+ assert_equal Task::DEFAULT_NAME, job.name
248
+ assert_not_equal Task::DEFAULT_NAME, job.step(:step1).name
249
+ end
250
+
251
+ def test_default_inputs_in_block
252
+ wf = Workflow.annonymous_workflow "TaskInputs" do
253
+ input :input1, :string
254
+ task :step1 => :string do |i| i end
255
+
256
+ dep :step1 do |id,options|
257
+ {}
258
+ end
259
+ task :step2 => :string do |i| step(:step1).load end
260
+ end
261
+
262
+ job = wf.job(:step2, "SOME_NAME", :input1 => 2)
263
+ assert_equal "SOME_NAME", job.step(:step1).clean_name
264
+ assert_equal 2, job.run
265
+ end
266
+
267
+ def test_override_inputs_block_array
268
+ wf = Workflow.annonymous_workflow "TaskInputs" do
269
+ input :input1, :string
270
+ task :step1 => :string do |i| i end
271
+
272
+ dep :step1, :input1 => 1 do |id,options|
273
+ [{:inputs => options}]
274
+ end
275
+ input :input2, :string
276
+ task :step2 => :string do |i| step(:step1).load end
277
+ end
278
+
279
+ job = wf.job(:step2, :input1 => 2)
280
+ assert_equal 1, job.run
281
+ assert_equal Task::DEFAULT_NAME, job.name
282
+ assert_not_equal Task::DEFAULT_NAME, job.step(:step1).name
283
+ end
284
+
285
+ def test_override_inputs
286
+ wf = Workflow.annonymous_workflow "TaskInputs" do
287
+ input :input1, :string
288
+ task :step1 => :string do |i| i end
289
+
290
+ dep :step1, :input1 => 1
291
+ input :input2, :string
292
+ task :step2 => :string do |i| step(:step1).load end
293
+ end
294
+
295
+ job = wf.job(:step2, :input1 => 2)
296
+ assert_equal 1, job.run
297
+ assert_equal Task::DEFAULT_NAME, job.name
298
+ assert_not_equal Task::DEFAULT_NAME, job.step(:step1).name
299
+ end
300
+
301
+ def test_non_default_inputs
302
+ wf = Workflow.annonymous_workflow "TaskInputs" do
303
+ input :input1, :integer, "", 1
304
+ input :input2, :integer, "", 0
305
+ task :step1 => :string do |i1,i2| i1 + i2 end
306
+
307
+ dep :step1, :input2 => 1
308
+ task :step2 => :string do |i| step(:step1).load end
309
+
310
+ dep :step2
311
+ task :step3 => :string do |i| step(:step1).load end
312
+ end
313
+
314
+ job = wf.job(:step3, :input1 => 1)
315
+ assert_equal Task::DEFAULT_NAME, job.name
316
+ assert_not_equal Task::DEFAULT_NAME, job.step(:step1).name
317
+ assert_equal 2, job.run
318
+
319
+ job = wf.job(:step3, :input1 => 2)
320
+ assert_equal 3, job.run
321
+
322
+
323
+ job = wf.job(:step3)
324
+ assert_equal Task::DEFAULT_NAME, job.name
325
+ assert_not_equal Task::DEFAULT_NAME, job.step(:step1).name
326
+ end
327
+
328
+ def test_can_fail
329
+ wf = Workflow.annonymous_workflow "TaskInputs" do
330
+ input :input1, :integer, "", 1
331
+ task :step1 => :string do |i1|
332
+ if i1 < 0
333
+ raise ScoutException
334
+ else
335
+ i1
336
+ end
337
+ end
338
+
339
+ dep :step1, :canfail => true
340
+ task :step2 => :string do |i|
341
+ if step(:step1).error?
342
+ 0
343
+ else
344
+ step(:step1).load
345
+ end
346
+ end
347
+ end
348
+
349
+ assert_equal 1, wf.job(:step2, :input1 => 1).run
350
+ assert_equal 2, wf.job(:step2, :input1 => 2).run
351
+ assert_equal 0, wf.job(:step2, :input1 => -2).run
352
+ end
353
+
354
+ end
355
+
@@ -21,6 +21,11 @@ class TestTaskInput < Test::Unit::TestCase
21
21
  task :task => :array do
22
22
  inputs
23
23
  end
24
+
25
+ dep :task
26
+ task :task2 => :array do
27
+ inputs
28
+ end
24
29
  end
25
30
  end
26
31
 
@@ -71,8 +76,8 @@ class TestTaskInput < Test::Unit::TestCase
71
76
  task = self.example_task
72
77
 
73
78
  TmpFile.with_file("2\n3") do |integer_array_file|
74
- assert_equal task.digest_inputs(:string => "String", :integer => 2, :integer_array => %w(2 3)),
75
- task.digest_inputs(:string => "String", :integer => 2, :integer_array => integer_array_file)
79
+ assert_equal task.process_inputs(:string => "String", :integer => 2, :integer_array => %w(2 3)).last,
80
+ task.process_inputs(:string => "String", :integer => 2, :integer_array => integer_array_file).last
76
81
  end
77
82
  end
78
83
 
@@ -83,10 +88,10 @@ class TestTaskInput < Test::Unit::TestCase
83
88
 
84
89
  TmpFile.with_file("1\n2") do |integer_array_file|
85
90
  hash1 = Open.open(integer_array_file) do |f|
86
- task.digest_inputs(:string => "String", :integer => 2, :integer_array => f)
91
+ task.process_inputs(:string => "String", :integer => 2, :integer_array => f).last
87
92
  end
88
93
  hash2 = Open.open(integer_array_file) do |f|
89
- task.digest_inputs(:string => "String", :integer => 2, :integer_array => f)
94
+ task.process_inputs(:string => "String", :integer => 2, :integer_array => f).last
90
95
  end
91
96
  assert_equal hash1, hash2
92
97
  end
@@ -98,22 +103,23 @@ class TestTaskInput < Test::Unit::TestCase
98
103
  task = self.example_task
99
104
 
100
105
  TmpFile.with_file("2\n3") do |integer_array_file|
101
- assert_equal task.digest_inputs(:string => "String", :integer => 2, :integer_array => %w(2 3)),
102
- task.digest_inputs(:string => "String", :integer => 2, :integer_array => integer_array_file)
106
+ assert_equal task.process_inputs(:string => "String", :integer => 2, :integer_array => %w(2 3)).last,
107
+ task.process_inputs(:string => "String", :integer => 2, :integer_array => integer_array_file).last
103
108
  end
104
109
  end
105
110
 
106
111
  def test_save_and_load
107
112
  task = self.example_task
108
113
 
114
+ sss 0
109
115
  TmpFile.with_file("2\n3") do |integer_array_file|
110
116
  inputs = {:string => "String", :integer => 2, :integer_array => integer_array_file, :float_array => %w(1.1 2.2)}
111
- original_digest = task.digest_inputs(inputs)
117
+ original_digest = task.process_inputs(inputs).last
112
118
 
113
119
  TmpFile.with_file do |save_directory|
114
120
  task.save_inputs(save_directory, inputs)
115
121
  new_inputs = task.load_inputs(save_directory)
116
- new_digest = task.digest_inputs(new_inputs)
122
+ new_digest = task.process_inputs(new_inputs).last
117
123
  assert_equal original_digest, new_digest
118
124
  end
119
125
  end
@@ -124,13 +130,13 @@ class TestTaskInput < Test::Unit::TestCase
124
130
 
125
131
  TmpFile.with_file("TEST") do |somefile|
126
132
  inputs = {:string => "String", :integer => 2, :file => somefile, :float_array => %w(1.1 2.2)}
127
- original_digest = task.digest_inputs(inputs)
133
+ original_digest = task.process_inputs(inputs).last
128
134
 
129
135
  TmpFile.with_file do |save_directory|
130
136
  task.save_inputs(save_directory, inputs)
131
137
  Open.rm somefile
132
138
  new_inputs = task.load_inputs(save_directory)
133
- new_digest = task.digest_inputs(new_inputs)
139
+ new_digest = task.process_inputs(new_inputs).last
134
140
  assert_equal original_digest, new_digest
135
141
  end
136
142
  end
@@ -141,7 +147,7 @@ class TestTaskInput < Test::Unit::TestCase
141
147
 
142
148
  TmpFile.with_file("TEST") do |somefile|
143
149
  inputs = {:string => "String", :integer => 2, :file => somefile, :float_array => %w(1.1 2.2)}
144
- original_digest = task.digest_inputs(inputs)
150
+ original_digest = task.process_inputs(inputs).last
145
151
 
146
152
  TmpFile.with_file do |save_directory|
147
153
  task.save_inputs(save_directory, inputs)
@@ -149,7 +155,7 @@ class TestTaskInput < Test::Unit::TestCase
149
155
  Open.cp save_directory, copy_directory
150
156
  Open.rm_rf save_directory
151
157
  new_inputs = task.load_inputs(copy_directory)
152
- new_digest = task.digest_inputs(new_inputs)
158
+ new_digest = task.process_inputs(new_inputs).last
153
159
  assert_equal original_digest, new_digest
154
160
  end
155
161
  end
@@ -167,14 +173,61 @@ class TestTaskInput < Test::Unit::TestCase
167
173
  Open.write(file1, "TEST1")
168
174
  Open.write(file2, "TEST2")
169
175
  inputs = {:string => "String", :integer => 2, :file_array => [file1, file2], :float_array => %w(1.1 2.2)}
170
- original_digest = task.digest_inputs(inputs)
176
+ original_digest = task.process_inputs(inputs).last
171
177
 
172
178
  TmpFile.with_file do |save_directory|
173
179
  task.save_inputs(save_directory, inputs)
174
180
  Open.rm(file1)
175
181
  Open.rm(file2)
176
182
  new_inputs = task.load_inputs(save_directory)
177
- new_digest = task.digest_inputs(new_inputs)
183
+ new_digest = task.process_inputs(new_inputs).last
184
+ assert_equal original_digest, new_digest
185
+ end
186
+ end
187
+ end
188
+
189
+ def test_save_and_load_file_array_task2
190
+ task = self.example_workflow.tasks[:task2]
191
+
192
+ TmpFile.with_file do |dir|
193
+ file1 = File.join(dir, 'subdir1/file')
194
+ file2 = File.join(dir, 'subdir2/file')
195
+
196
+ Open.write(file1, "TEST1")
197
+ Open.write(file2, "TEST2")
198
+ inputs = {:string => "String", :integer => 2, :file_array => [file1, file2], :float_array => %w(1.1 2.2)}
199
+ original_digest = task.process_inputs(inputs).last
200
+
201
+ TmpFile.with_file do |save_directory|
202
+ task.save_inputs(save_directory, inputs)
203
+ Open.rm(file1)
204
+ Open.rm(file2)
205
+ new_inputs = task.load_inputs(save_directory)
206
+ new_digest = task.process_inputs(new_inputs).last
207
+ assert_equal original_digest, new_digest
208
+ end
209
+ end
210
+ end
211
+
212
+ def test_save_and_load_array_from_file
213
+ task = self.example_workflow.tasks[:task]
214
+
215
+ TmpFile.with_file do |dir|
216
+ array = %w(1 2 3 4 5)
217
+ file1 = File.join(dir, 'subdir1/file')
218
+ Open.write(file1, array * "\n")
219
+ inputs = {:array => file1 }
220
+ original_digest = task.process_inputs(inputs).last
221
+
222
+ TmpFile.with_file do |save_directory|
223
+ iii inputs
224
+ task.save_inputs(save_directory, inputs)
225
+ Open.rm(file1)
226
+ new_inputs = task.load_inputs(save_directory)
227
+ iii new_inputs
228
+ new_digest = task.process_inputs(new_inputs).last
229
+ iii new_digest
230
+ iii original_digest
178
231
  assert_equal original_digest, new_digest
179
232
  end
180
233
  end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ class TestClass < Test::Unit::TestCase
5
+ def test_function_task
6
+ wf = Workflow.annonymous_workflow do
7
+ self.name = "StringLength"
8
+ def self.str_length(s)
9
+ s.length
10
+ end
11
+
12
+ input :string, :string
13
+ task :str_length => :integer
14
+ end
15
+ assert_equal 5, wf.job(:str_length, :string => "12345").run
16
+ end
17
+ end
18
+
@@ -26,5 +26,29 @@ class TestWorkflowDocumentation < Test::Unit::TestCase
26
26
  assert_match 'test', UsageWorkflow.documentation[:title]
27
27
  assert_match 'presented', UsageWorkflow.documentation[:description]
28
28
  end
29
+
30
+ def test_documentation_markdown
31
+ doc =<<-EOF
32
+ summary
33
+
34
+ description
35
+
36
+ # Tasks
37
+
38
+ ## task1
39
+
40
+ task 1 summary
41
+
42
+ task 1 description
43
+
44
+ ## task2
45
+ task 2 summary
46
+
47
+ task 2 description
48
+ EOF
49
+
50
+ assert_includes Workflow.parse_workflow_doc(doc)[:tasks], 'task1'
51
+ assert_includes Workflow.parse_workflow_doc(doc)[:tasks]['task2'], 'task 2 description'
52
+ end
29
53
  end
30
54
 
@@ -47,6 +47,17 @@ class TestWorkflowStep < Test::Unit::TestCase
47
47
  end
48
48
  step1.type = :array
49
49
 
50
+ step1.clean
51
+ res = step1.run(false)
52
+ refute IO === res
53
+ step1.join
54
+
55
+ step1.clean
56
+ res = step1.run(true)
57
+ assert IO === res
58
+ step1.join
59
+ step1.clean
60
+
50
61
  step2 = Step.new tmpfile.step2 do
51
62
  step1 = dependencies.first
52
63
  stream = step1.stream
@@ -75,7 +86,7 @@ class TestWorkflowStep < Test::Unit::TestCase
75
86
  end
76
87
  assert_equal times/2, lines.length
77
88
 
78
- stream = step2.run
89
+ stream = step2.run(true)
79
90
  assert step1.streaming?
80
91
  assert step2.streaming?
81
92
 
@@ -137,7 +148,7 @@ class TestWorkflowStep < Test::Unit::TestCase
137
148
 
138
149
  step3.recursive_clean
139
150
 
140
- stream = step3.run
151
+ stream = step3.run(true)
141
152
  out = []
142
153
  while l = stream.gets
143
154
  out << l
@@ -218,7 +229,7 @@ class TestWorkflowStep < Test::Unit::TestCase
218
229
  step4.dependencies = [step2, step3]
219
230
 
220
231
  lines = []
221
- io = step4.run
232
+ io = step4.run(true)
222
233
  Log::ProgressBar.with_bar severity: 0 do |b|
223
234
  while line = io.gets
224
235
  b.tick
@@ -229,4 +240,102 @@ class TestWorkflowStep < Test::Unit::TestCase
229
240
 
230
241
  assert_equal times, lines.length
231
242
  end
243
+
244
+ def test_fork_stream_fork
245
+ tmpfile = tmpdir.test_step
246
+
247
+ times = 10_000
248
+ sleep = 0.1 / times
249
+
250
+ step1 = Step.new tmpfile.step1, [times, sleep] do |times,sleep|
251
+ sleep 1
252
+ Open.open_pipe do |sin|
253
+ times.times do |i|
254
+ sin.puts "line-#{i}"
255
+ sleep sleep
256
+ end
257
+ end
258
+ end
259
+ step1.type = :array
260
+
261
+
262
+ step2 = Step.new tmpfile.step2 do
263
+ step1 = dependencies.first
264
+ stream = step1.stream
265
+
266
+ Open.open_pipe do |sin|
267
+ while line = stream.gets
268
+ num = line.split("-").last
269
+ next if num.to_i % 2 == 1
270
+ sin.puts "S2: " + line
271
+ end
272
+ end
273
+ end
274
+ step2.type = :array
275
+ step2.dependencies = [step1]
276
+
277
+ step3 = Step.new tmpfile.step3 do
278
+ step1 = dependencies.first
279
+ stream = step1.stream
280
+
281
+ Open.open_pipe do |sin|
282
+ while line = stream.gets
283
+ num = line.split("-").last
284
+ next if num.to_i % 2 == 0
285
+ sin.puts "S3: " + line
286
+ end
287
+ end
288
+ end
289
+ step3.type = :array
290
+ step3.dependencies = [step1]
291
+
292
+
293
+ step4 = Step.new tmpfile.step4 do
294
+ step2, step3 = dependencies
295
+
296
+ mutex = Mutex.new
297
+ Open.open_pipe do |sin|
298
+ t2 = Thread.new do
299
+ stream2 = step2.stream
300
+ while line = stream2.gets
301
+ sin.puts line
302
+ end
303
+ end
304
+
305
+ t3 = Thread.new do
306
+ stream3 = step3.stream
307
+ while line = stream3.gets
308
+ sin.puts line
309
+ end
310
+ end
311
+ t2.join
312
+ t3.join
313
+ end
314
+ end
315
+ step4.type = :array
316
+ step4.dependencies = [step2, step3]
317
+
318
+ step4.recursive_clean
319
+ step4.fork
320
+ assert Array === step4.load
321
+ assert_equal times, step4.load.size
322
+ end
323
+
324
+ def test_dependency_canfail
325
+ tmpfile = tmpdir.test_step
326
+ step1 = Step.new tmpfile.step1, ["12"] do |s|
327
+ s.length
328
+ end
329
+
330
+ step2 = Step.new tmpfile.step2 do
331
+ step1 = dependencies.first
332
+ step1.inputs.first + " has " + step1.load.to_s + " characters"
333
+ end
334
+
335
+ step2.dependencies = [step1]
336
+
337
+ assert_equal "12 has 2 characters", step2.run
338
+ assert_equal "12 has 2 characters", step2.run
339
+ end
340
+
232
341
  end