scout-gear 10.9.0 → 10.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +25 -0
  3. data/VERSION +1 -1
  4. data/bin/scout +4 -1
  5. data/lib/scout/knowledge_base/registry.rb +2 -3
  6. data/lib/scout/workflow/definition.rb +11 -0
  7. data/lib/scout/workflow/deployment/local.rb +288 -0
  8. data/lib/scout/workflow/deployment/orchestrator/batches.rb +130 -0
  9. data/lib/scout/workflow/deployment/orchestrator/chains.rb +104 -0
  10. data/lib/scout/workflow/deployment/orchestrator/rules.rb +256 -0
  11. data/lib/scout/workflow/deployment/orchestrator/workload.rb +67 -0
  12. data/lib/scout/workflow/deployment/scheduler/job.rb +740 -0
  13. data/lib/scout/workflow/deployment/scheduler/lfs.rb +125 -0
  14. data/lib/scout/workflow/deployment/scheduler/pbs.rb +176 -0
  15. data/lib/scout/workflow/deployment/scheduler/slurm.rb +158 -0
  16. data/lib/scout/workflow/deployment/scheduler.rb +73 -0
  17. data/lib/scout/workflow/deployment.rb +10 -1
  18. data/lib/scout/workflow/exceptions.rb +2 -0
  19. data/lib/scout/workflow/step/config.rb +3 -0
  20. data/lib/scout/workflow/step/info.rb +2 -2
  21. data/lib/scout/workflow/step/progress.rb +52 -0
  22. data/lib/scout/workflow/step.rb +30 -1
  23. data/lib/scout/workflow/task.rb +2 -0
  24. data/scout-gear.gemspec +23 -4
  25. data/scout_commands/batch/list +1 -1
  26. data/scout_commands/workflow/cmd +5 -13
  27. data/scout_commands/workflow/info +1 -1
  28. data/scout_commands/workflow/task +61 -25
  29. data/test/scout/workflow/deployment/orchestrator/test_batches.rb +138 -0
  30. data/test/scout/workflow/deployment/orchestrator/test_chains.rb +171 -0
  31. data/test/scout/workflow/deployment/orchestrator/test_rules.rb +219 -0
  32. data/test/scout/workflow/deployment/orchestrator/test_workload.rb +117 -0
  33. data/test/scout/workflow/deployment/scheduler/test_job.rb +31 -0
  34. data/test/scout/workflow/deployment/scheduler/test_lfs.rb +32 -0
  35. data/test/scout/workflow/deployment/scheduler/test_pbs.rb +32 -0
  36. data/test/scout/workflow/deployment/scheduler/test_slurm.rb +32 -0
  37. data/test/scout/workflow/deployment/{test_orchestrator.rb → test_local.rb} +161 -33
  38. data/test/scout/workflow/deployment/test_scheduler.rb +75 -0
  39. data/test/scout/workflow/deployment/test_trace.rb +1 -1
  40. data/test/scout/workflow/step/test_progress.rb +27 -0
  41. data/test/scout/workflow/task/test_inputs.rb +17 -0
  42. data/test/test_helper.rb +2 -1
  43. metadata +22 -3
  44. data/lib/scout/workflow/deployment/orchestrator.rb +0 -292
@@ -1,38 +1,40 @@
1
1
  require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
2
  require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
3
 
4
- class TestOrchestrator < Test::Unit::TestCase
5
- setup do
6
- module TestWF
7
- extend Workflow
8
- self.name = "TestWF"
4
+ require 'scout/workflow/deployment/trace'
5
+ module TestWF
6
+ extend Workflow
7
+ self.name = "TestWF"
8
+
9
+ MULT = 0.1
10
+ task :a => :text do
11
+ sleep(TestWF::MULT * (rand(10) + 2))
12
+ end
9
13
 
10
- MULT = 0.1
11
- task :a => :text do
12
- sleep(TestWF::MULT * (rand(10) + 2))
13
- end
14
+ dep :a
15
+ task :b => :text do
16
+ sleep(TestWF::MULT * (rand(10) + 2))
17
+ end
14
18
 
15
- dep :a
16
- task :b => :text do
17
- sleep(TestWF::MULT * (rand(10) + 2))
18
- end
19
+ dep :a
20
+ dep :b
21
+ task :c => :text do
22
+ sleep(TestWF::MULT * (rand(10) + 2))
23
+ end
19
24
 
20
- dep :a
21
- dep :b
22
- task :c => :text do
23
- sleep(TestWF::MULT * (rand(10) + 2))
24
- end
25
+ dep :c
26
+ task :d => :text do
27
+ sleep(TestWF::MULT * (rand(10) + 2))
28
+ end
25
29
 
26
- dep :c
27
- task :d => :text do
28
- sleep(TestWF::MULT * (rand(10) + 2))
29
- end
30
+ dep :c
31
+ task :e => :text do
32
+ sleep(TestWF::MULT * (rand(10) + 2))
33
+ end
34
+ end
30
35
 
31
- dep :c
32
- task :e => :text do
33
- sleep(TestWF::MULT * (rand(10) + 2))
34
- end
35
- end
36
+ class TestLocalExec < Test::Unit::TestCase
37
+ setup do
36
38
  end
37
39
 
38
40
  def test_orchestrate_resources
@@ -65,7 +67,7 @@ TestWF:
65
67
  cpus: 15
66
68
  EOF
67
69
 
68
- orchestrator = Workflow::Orchestrator.new(0.1, "cpus" => 30, "IO" => 10, "size" => 10 )
70
+ orchestrator = Workflow::LocalExecutor.new(0.01, "cpus" => 30, "IO" => 10, "size" => 10 )
69
71
  orchestrator.process(rules, jobs)
70
72
 
71
73
  data = Workflow.trace jobs, :plot_data => true
@@ -89,7 +91,50 @@ TestWF:
89
91
 
90
92
  jobs =[]
91
93
 
92
- num = 10
94
+ num = 1
95
+ num.times do |i|
96
+ jobs.concat %w(TEST1 TEST2).collect{|name| TestWF.job(:d, name + " #{i}") }
97
+ end
98
+ jobs.each do |j| j.recursive_clean end
99
+
100
+ rules = YAML.load <<-EOF
101
+ defaults:
102
+ log: 4
103
+ default_resources:
104
+ IO: 1
105
+ TestWF:
106
+ a:
107
+ erase: true
108
+ resources:
109
+ cpus: 7
110
+ b:
111
+ erase: true
112
+ resources:
113
+ cpus: 2
114
+ c:
115
+ resources:
116
+ cpus: 10
117
+ d:
118
+ resources:
119
+ cpus: 15
120
+ EOF
121
+
122
+ orchestrator = Workflow::LocalExecutor.new(TestWF::MULT, "cpus" => 30, "IO" => 4, "size" => 10 )
123
+ orchestrator.process(rules, jobs)
124
+
125
+ jobs.each do |job|
126
+ assert job.step(:c).dependencies.empty?
127
+ assert job.step(:c).info[:archived_info].keys.select{|k| k.include?("TestWF/a/")}.any?
128
+ assert job.step(:c).info[:archived_info].keys.select{|k| k.include?("TestWF/b/")}.any?
129
+ end
130
+
131
+ end
132
+
133
+ def test_orchestrate_erase_long
134
+
135
+ jobs =[]
136
+
137
+ num = 3
93
138
  num.times do |i|
94
139
  jobs.concat %w(TEST1 TEST2).collect{|name| TestWF.job(:d, name + " #{i}") }
95
140
  end
@@ -117,7 +162,7 @@ TestWF:
117
162
  cpus: 15
118
163
  EOF
119
164
 
120
- orchestrator = Workflow::Orchestrator.new(TestWF::MULT, "cpus" => 30, "IO" => 4, "size" => 10 )
165
+ orchestrator = Workflow::LocalExecutor.new(TestWF::MULT, "cpus" => 30, "IO" => 4, "size" => 10 )
121
166
  orchestrator.process(rules, jobs)
122
167
 
123
168
  jobs.each do |job|
@@ -162,7 +207,7 @@ TestWF:
162
207
  cpus: 15
163
208
  EOF
164
209
 
165
- orchestrator = Workflow::Orchestrator.new(TestWF::MULT, "cpus" => 30, "IO" => 4, "size" => 10 )
210
+ orchestrator = Workflow::LocalExecutor.new(TestWF::MULT, "cpus" => 30, "IO" => 4, "size" => 10 )
166
211
  orchestrator.process(rules, jobs)
167
212
 
168
213
  jobs.each do |job|
@@ -205,7 +250,7 @@ TestWF:
205
250
  cpus: 15
206
251
  EOF
207
252
 
208
- orchestrator = Workflow::Orchestrator.new(TestWF::MULT, "cpus" => 30, "IO" => 4, "size" => 10 )
253
+ orchestrator = Workflow::LocalExecutor.new(TestWF::MULT, "cpus" => 30, "IO" => 4, "size" => 10 )
209
254
  orchestrator.process(rules, jobs)
210
255
 
211
256
  jobs.each do |job|
@@ -249,7 +294,7 @@ TestWF:
249
294
  cpus: 15
250
295
  EOF
251
296
 
252
- orchestrator = Workflow::Orchestrator.new(TestWF::MULT, "cpus" => 30, "IO" => 4, "size" => 10 )
297
+ orchestrator = Workflow::LocalExecutor.new(TestWF::MULT, "cpus" => 30, "IO" => 4, "size" => 10 )
253
298
  orchestrator.process(rules, jobs)
254
299
 
255
300
  jobs.each do |job|
@@ -259,5 +304,88 @@ TestWF:
259
304
  end
260
305
 
261
306
  end
307
+
308
+ def test_orchestrate_produce
309
+
310
+ jobs =[]
311
+
312
+ num = 1
313
+ num.times do |i|
314
+ jobs.concat %w(TEST1 TEST2).collect{|name| TestWF.job(:d, name + " #{i}") }
315
+ jobs.concat %w(TEST1 TEST2).collect{|name| TestWF.job(:c, name + " #{i}") }
316
+ end
317
+ jobs.each do |j| j.recursive_clean end
318
+
319
+ rules = YAML.load <<-EOF
320
+ defaults:
321
+ erase: true
322
+ log: 4
323
+ default_resources:
324
+ IO: 1
325
+ TestWF:
326
+ a:
327
+ resources:
328
+ cpus: 7
329
+ b:
330
+ resources:
331
+ cpus: 2
332
+ c:
333
+ resources:
334
+ cpus: 10
335
+ d:
336
+ resources:
337
+ cpus: 15
338
+ EOF
339
+
340
+ Workflow::LocalExecutor.produce(jobs, rules, produce_timer: 0.1, produce_cpus: 20)
341
+
342
+ jobs.each do |job|
343
+ next unless job.task_name.to_s == 'd'
344
+ assert job.step(:c).dependencies.empty?
345
+ assert job.step(:c).info[:archived_info].keys.select{|k| k.include?("TestWF/a/")}.any?
346
+ assert job.step(:c).info[:archived_info].keys.select{|k| k.include?("TestWF/b/")}.any?
347
+ end
348
+
349
+ end
350
+
351
+ def test_orchestrate_produce_deps
352
+
353
+ jobs =[]
354
+
355
+ num = 1
356
+ num.times do |i|
357
+ jobs.concat %w(TEST1 TEST2).collect{|name| TestWF.job(:d, name + " #{i}") }
358
+ jobs.concat %w(TEST1 TEST2).collect{|name| TestWF.job(:c, name + " #{i}") }
359
+ end
360
+ jobs.each do |j| j.recursive_clean end
361
+
362
+ rules = YAML.load <<-EOF
363
+ defaults:
364
+ erase: true
365
+ log: 4
366
+ default_resources:
367
+ IO: 1
368
+ TestWF:
369
+ a:
370
+ resources:
371
+ cpus: 7
372
+ b:
373
+ resources:
374
+ cpus: 2
375
+ c:
376
+ resources:
377
+ cpus: 10
378
+ d:
379
+ resources:
380
+ cpus: 15
381
+ EOF
382
+
383
+ Workflow::LocalExecutor.produce_dependencies(jobs, [:a, :b], rules, produce_timer: 0.1)
384
+
385
+ jobs.each do |job|
386
+ assert job.step(:a).done?
387
+ refute job.done?
388
+ end
389
+ end
262
390
  end
263
391
 
@@ -0,0 +1,75 @@
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/deployment/scheduler/slurm'
5
+
6
+ class TestScheduler < Test::Unit::TestCase
7
+ setup do
8
+ module TestWF
9
+ extend Workflow
10
+ self.name = "TestWF"
11
+
12
+ MULT ||= 0.1
13
+ task :a => :text do
14
+ sleep(TestWF::MULT * (rand(10) + 2))
15
+ end
16
+
17
+ dep :a
18
+ task :b => :text do
19
+ sleep(TestWF::MULT * (rand(10) + 2))
20
+ end
21
+
22
+ dep :a
23
+ dep :b
24
+ task :c => :text do
25
+ sleep(TestWF::MULT * (rand(10) + 2))
26
+ end
27
+
28
+ dep :c
29
+ task :d => :text do
30
+ sleep(TestWF::MULT * (rand(10) + 2))
31
+ end
32
+
33
+ dep :c
34
+ task :e => :text do
35
+ sleep(TestWF::MULT * (rand(10) + 2))
36
+ end
37
+ end
38
+ end
39
+
40
+ def test_orchestrate_process
41
+
42
+ jobs =[]
43
+
44
+ num = 1
45
+ num.times do |i|
46
+ jobs.concat %w(TEST1 TEST2).collect{|name| TestWF.job(:d, name + " #{i}") }
47
+ end
48
+ jobs.each do |j| j.recursive_clean end
49
+
50
+ rules = YAML.load <<-EOF
51
+ defaults:
52
+ log: 4
53
+ default_resources:
54
+ IO: 1
55
+ TestWF:
56
+ a:
57
+ resources:
58
+ cpus: 7
59
+ b:
60
+ resources:
61
+ cpus: 2
62
+ c:
63
+ resources:
64
+ cpus: 10
65
+ d:
66
+ resources:
67
+ cpus: 15
68
+ EOF
69
+
70
+ batches = Workflow::Orchestrator.job_batches(rules, jobs)
71
+ dirs = Workflow::Scheduler.process_batches(batches, dry_run: true)
72
+ iii dirs
73
+ end
74
+ end
75
+
@@ -4,7 +4,7 @@ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1
4
4
  require 'scout/tsv'
5
5
 
6
6
  class TestWorkflowTrace < Test::Unit::TestCase
7
- def test_true
7
+ def test_trace
8
8
  m = Module.new do
9
9
  extend Workflow
10
10
  self.name = "TestWF"
@@ -0,0 +1,27 @@
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 TestStepProgress < Test::Unit::TestCase
5
+ def test_monitor_stream
6
+
7
+ TmpFile.with_file do |tmpfile|
8
+ items = %w(foo bar baz)
9
+ lines = []
10
+ step = Step.new tmpfile, ["12"] do |s|
11
+ file = file('test')
12
+ Open.write file, items * "\n"
13
+ s = file.open
14
+ self.monitor_stream s, bar: 3 do |line|
15
+ lines << line.strip
16
+ end
17
+ end
18
+ step.type = :text
19
+
20
+ res = step.run(:stream)
21
+ res.read
22
+ res.join
23
+ assert_equal items, lines
24
+ end
25
+ end
26
+ end
27
+
@@ -18,6 +18,7 @@ class TestTaskInput < Test::Unit::TestCase
18
18
  input :boolean_array, :boolean_array, "", [true, false, true]
19
19
  input :path_array, :path_array, "", %w(dir/subdir/file1 dir/subdir/file2)
20
20
  input :file_array, :file_array
21
+ input :select, :select, '', :foo, select_options: %(foo bar)
21
22
  task :task => :array do
22
23
  inputs
23
24
  end
@@ -124,6 +125,22 @@ class TestTaskInput < Test::Unit::TestCase
124
125
  end
125
126
  end
126
127
 
128
+ def test_save_and_load_select
129
+ task = self.example_task
130
+
131
+ TmpFile.with_file("2\n3") do |integer_array_file|
132
+ inputs = {:select => 'bar'}
133
+ original_digest = task.process_inputs(inputs).last
134
+
135
+ TmpFile.with_path do |save_directory|
136
+ task.save_inputs(save_directory, inputs)
137
+ new_inputs = task.load_inputs(save_directory)
138
+ new_digest = task.process_inputs(new_inputs).last
139
+ assert_equal original_digest, new_digest
140
+ end
141
+ end
142
+ end
143
+
127
144
  def test_save_and_load_file
128
145
  task = self.example_task
129
146
 
data/test/test_helper.rb CHANGED
@@ -51,11 +51,12 @@ class Test::Unit::TestCase
51
51
  Workflow.directory = tmpdir.var.jobs
52
52
  Workflow.workflows.each{|wf| wf.directory = Workflow.directory[wf.name] }
53
53
  Entity.entity_property_cache = tmpdir.entity_properties if defined?(Entity)
54
+ Workflow.job_cache.clear
55
+ SchedulerJob.batch_base_dir = tmpdir.batch
54
56
  end
55
57
 
56
58
  teardown do
57
59
  Open.rm_rf tmpdir
58
- Workflow.job_cache.clear
59
60
  end
60
61
 
61
62
  def self.datadir_test
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout-gear
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.9.0
4
+ version: 10.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
@@ -189,8 +189,17 @@ files:
189
189
  - lib/scout/workflow.rb
190
190
  - lib/scout/workflow/definition.rb
191
191
  - lib/scout/workflow/deployment.rb
192
- - lib/scout/workflow/deployment/orchestrator.rb
192
+ - lib/scout/workflow/deployment/local.rb
193
+ - lib/scout/workflow/deployment/orchestrator/batches.rb
194
+ - lib/scout/workflow/deployment/orchestrator/chains.rb
195
+ - lib/scout/workflow/deployment/orchestrator/rules.rb
196
+ - lib/scout/workflow/deployment/orchestrator/workload.rb
193
197
  - lib/scout/workflow/deployment/queue.rb
198
+ - lib/scout/workflow/deployment/scheduler.rb
199
+ - lib/scout/workflow/deployment/scheduler/job.rb
200
+ - lib/scout/workflow/deployment/scheduler/lfs.rb
201
+ - lib/scout/workflow/deployment/scheduler/pbs.rb
202
+ - lib/scout/workflow/deployment/scheduler/slurm.rb
194
203
  - lib/scout/workflow/deployment/trace.rb
195
204
  - lib/scout/workflow/documentation.rb
196
205
  - lib/scout/workflow/entity.rb
@@ -320,13 +329,23 @@ files:
320
329
  - test/scout/tsv/util/test_unzip.rb
321
330
  - test/scout/work_queue/test_socket.rb
322
331
  - test/scout/work_queue/test_worker.rb
323
- - test/scout/workflow/deployment/test_orchestrator.rb
332
+ - test/scout/workflow/deployment/orchestrator/test_batches.rb
333
+ - test/scout/workflow/deployment/orchestrator/test_chains.rb
334
+ - test/scout/workflow/deployment/orchestrator/test_rules.rb
335
+ - test/scout/workflow/deployment/orchestrator/test_workload.rb
336
+ - test/scout/workflow/deployment/scheduler/test_job.rb
337
+ - test/scout/workflow/deployment/scheduler/test_lfs.rb
338
+ - test/scout/workflow/deployment/scheduler/test_pbs.rb
339
+ - test/scout/workflow/deployment/scheduler/test_slurm.rb
340
+ - test/scout/workflow/deployment/test_local.rb
341
+ - test/scout/workflow/deployment/test_scheduler.rb
324
342
  - test/scout/workflow/deployment/test_trace.rb
325
343
  - test/scout/workflow/step/test_archive.rb
326
344
  - test/scout/workflow/step/test_children.rb
327
345
  - test/scout/workflow/step/test_dependencies.rb
328
346
  - test/scout/workflow/step/test_info.rb
329
347
  - test/scout/workflow/step/test_load.rb
348
+ - test/scout/workflow/step/test_progress.rb
330
349
  - test/scout/workflow/step/test_provenance.rb
331
350
  - test/scout/workflow/step/test_status.rb
332
351
  - test/scout/workflow/task/test_dependencies.rb