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
@@ -0,0 +1,219 @@
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 TestOrchestrateRules < Test::Unit::TestCase
5
+
6
+ RULES = IndiferentHash.setup(YAML.load(<<-EOF))
7
+ ---
8
+ defaults:
9
+ queue: first_queue
10
+ time: 1h
11
+ log: 2
12
+ config_keys: key1 value1 token1
13
+ chains:
14
+ chain_a:
15
+ workflow: TestWFA
16
+ tasks: a1, a2, a3
17
+ config_keys: key2 value2 token2, key3 value3 token3.1 token3.2
18
+ chain_b:
19
+ workflow: TestWFB
20
+ tasks: b1, b2
21
+ chain_b2:
22
+ comment: This chain is not valid, it is missing a2
23
+ tasks: TestWFA#a1, TestWFA#a3, TestWFB#b1, TestWFB#b2
24
+ TestWFA:
25
+ defaults:
26
+ log: 4
27
+ config_keys: key4 value4 token4
28
+ a1:
29
+ cpus: 10
30
+ config_keys: key5 value5 token5
31
+ TestWFC:
32
+ defaults:
33
+ skip: true
34
+ log: 4
35
+ EOF
36
+
37
+ def test_defaults
38
+ rules = Workflow::Orchestrator.task_specific_rules RULES, "TestWFA", :a1
39
+ assert_equal "first_queue" , rules[:queue]
40
+ end
41
+
42
+
43
+ def test_task_options
44
+ rules = Workflow::Orchestrator.task_specific_rules RULES, "TestWFA", :a1
45
+ assert_equal 10, rules[:cpus]
46
+ assert_equal 4, rules[:log]
47
+ end
48
+
49
+ def test_skip
50
+ rules = Workflow::Orchestrator.task_specific_rules RULES, "TestWFC", :c1
51
+ assert rules[:skip]
52
+ end
53
+
54
+ def test_load_rules
55
+ rules1 =<<-EOF
56
+ defaults:
57
+ name: rules1
58
+ time: 1h
59
+ cpus: 2
60
+ Workflow:
61
+ defaults:
62
+ time: 1m
63
+ cpus: 4
64
+ Workflow3:
65
+ defaults:
66
+ time: 3m
67
+ EOF
68
+
69
+ rules2 =<<-EOF
70
+ defaults:
71
+ name: rules2
72
+ time: 2h
73
+ Workflow:
74
+ defaults:
75
+ time: 2m
76
+ Workflow2:
77
+ defaults:
78
+ time: 3m
79
+ EOF
80
+
81
+ TmpFile.with_file rules1 do |file1|
82
+ TmpFile.with_file rules2 do |file2|
83
+
84
+ rules = Workflow::Orchestrator.load_rules [file2, file1]
85
+
86
+ assert_equal 'rules2', rules[:defaults][:name]
87
+
88
+ assert_equal 2, rules[:defaults][:cpus]
89
+ assert_equal '2h', rules[:defaults][:time]
90
+
91
+ assert_equal 4, rules['Workflow'][:defaults][:cpus]
92
+ assert_equal '2m', rules["Workflow"][:defaults][:time]
93
+
94
+ assert_include rules, 'Workflow2'
95
+ assert_include rules, 'Workflow3'
96
+ end
97
+ end
98
+ end
99
+
100
+ def test_load_rules_config_keys
101
+ rules1 =<<-EOF
102
+ Workflow:
103
+ defaults:
104
+ time: 1h
105
+ cpus: 2
106
+ config_keys: cpus 4 loop
107
+ EOF
108
+
109
+ rules2 =<<-EOF
110
+ Workflow:
111
+ defaults:
112
+ time: 1h
113
+ cpus: 4
114
+ config_keys: mem high database
115
+ EOF
116
+
117
+ correct = YAML.load <<-EOF
118
+ ---
119
+ Workflow:
120
+ defaults:
121
+ time: 1h
122
+ cpus: 4
123
+ config_keys: cpus 4 loop,mem high database
124
+ EOF
125
+
126
+
127
+ TmpFile.with_file rules1 do |file1|
128
+ TmpFile.with_file rules2 do |file2|
129
+
130
+ rules = Workflow::Orchestrator.load_rules [file2, file1]
131
+ assert_equal correct, rules
132
+ end
133
+ end
134
+ end
135
+
136
+
137
+ def test_load_rules_config_keys_alt
138
+ rules1 =<<-EOF
139
+ Workflow:
140
+ defaults:
141
+ name: rules1
142
+ time: 1h
143
+ cpus: 2
144
+ config_keys:
145
+ - cpus 4 loop
146
+ - level warn log
147
+ EOF
148
+
149
+ rules2 =<<-EOF
150
+ Workflow:
151
+ defaults:
152
+ name: rules2
153
+ time: 1h
154
+ cpus: 4
155
+ config_keys:
156
+ - mem high database
157
+ EOF
158
+
159
+ correct = YAML.load <<-EOF
160
+ ---
161
+ Workflow:
162
+ defaults:
163
+ name: rules2
164
+ time: 1h
165
+ cpus: 4
166
+ config_keys: cpus 4 loop,level warn log,mem high database
167
+ EOF
168
+
169
+
170
+ TmpFile.with_file rules1 do |file1|
171
+ TmpFile.with_file rules2 do |file2|
172
+
173
+ rules = Workflow::Orchestrator.load_rules [file2, file1]
174
+ assert_equal correct, rules
175
+ end
176
+ end
177
+ end
178
+
179
+
180
+ def test_load_rules_import
181
+ rules1 =<<-EOF
182
+ Workflow:
183
+ defaults:
184
+ time: 1h
185
+ cpus: 2
186
+ config_keys: cpus 4 loop
187
+ EOF
188
+
189
+ rules2 =<<-EOF
190
+ Workflow:
191
+ defaults:
192
+ time: 1h
193
+ cpus: 2
194
+ config_keys: mem high database
195
+ EOF
196
+
197
+ correct = YAML.load <<-EOF
198
+ ---
199
+ Workflow:
200
+ defaults:
201
+ time: 1h
202
+ cpus: 2
203
+ config_keys: cpus 4 loop,mem high database
204
+ EOF
205
+
206
+
207
+ TmpFile.with_file rules1 do |file1|
208
+ TmpFile.with_file rules2 do |file2|
209
+ Open.open(file2, mode: 'a') do |f|
210
+ f.puts "import: #{file1}"
211
+ end
212
+
213
+ rules = Workflow::Orchestrator.load_rules file2
214
+ assert_equal correct, rules
215
+ end
216
+ end
217
+ end
218
+ end
219
+
@@ -0,0 +1,117 @@
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
+ module TestWFA
5
+ extend Workflow
6
+
7
+ task :a1 => :string do self.task_name.to_s end
8
+
9
+ dep :a1
10
+ task :a2 => :string do self.task_name.to_s end
11
+
12
+ dep :a2
13
+ task :a3 => :string do self.task_name.to_s end
14
+ end
15
+
16
+ module TestWFB
17
+ extend Workflow
18
+
19
+ dep TestWFA, :a2
20
+ task :b1 => :string do self.task_name.to_s end
21
+
22
+ dep :b1
23
+ task :b2 => :string do self.task_name.to_s end
24
+ end
25
+
26
+ module TestWFC
27
+ extend Workflow
28
+
29
+ dep TestWFA, :a1
30
+ dep_task :c1, TestWFB, :b2
31
+
32
+ task :c2 => :string do self.task_name.to_s end
33
+
34
+ dep :c1
35
+ dep :c2
36
+ task :c3 => :string do self.task_name.to_s end
37
+
38
+ dep_task :c4, TestWFC, :c3
39
+ end
40
+
41
+ module TestWFD
42
+ extend Workflow
43
+
44
+ dep TestWFC, :c3, :jobname => "First c3"
45
+ dep TestWFC, :c3, :jobname => "Second c3"
46
+ task :d1 => :string do self.task_name.to_s end
47
+ end
48
+
49
+ module TestDeepWF
50
+ extend Workflow
51
+
52
+ dep_task :deep1, TestWFD, :d1
53
+
54
+ input :size, :integer, "Number of dependencies", 100
55
+ dep :deep1 do |jobname,options|
56
+ options[:size].to_i.times.collect{|i|
57
+ {:jobname => "step-#{i}"}
58
+ }
59
+ end
60
+ task :suite => :array do
61
+ end
62
+ end
63
+
64
+ class TestWorkload < Test::Unit::TestCase
65
+
66
+ RULES = IndiferentHash.setup(YAML.load(<<-EOF))
67
+ ---
68
+ defaults:
69
+ queue: first_queue
70
+ time: 1h
71
+ log: 2
72
+ config_keys: key1 value1 token1
73
+ chains:
74
+ chain_a_b:
75
+ tasks: TestWFB#b1, TestWFB#b2, TestWFA#a1, TestWFA#a2
76
+ config_keys: key2 value2 token2, key3 value3 token3.1 token3.2
77
+ chain_a:
78
+ workflow: TestWFA
79
+ tasks: a1, a2, a3
80
+ config_keys: key2 value2 token2, key3 value3 token3.1 token3.2
81
+ chain_b:
82
+ workflow: TestWFB
83
+ tasks: b1, b2
84
+ chain_b2:
85
+ tasks: TestWFB#b1, TestWFB#b2, TestWFA#a1
86
+ chain_d:
87
+ tasks: TestWFD#d1, TestWFC#c1, TestWFC#c2, TestWFC#c3
88
+ TestWFA:
89
+ defaults:
90
+ log: 4
91
+ config_keys: key4 value4 token4
92
+ time: 10min
93
+ a1:
94
+ cpus: 10
95
+ config_keys: key5 value5 token5
96
+ TestWFC:
97
+ defaults:
98
+ skip: true
99
+ log: 4
100
+ time: 10s
101
+ EOF
102
+
103
+ def test_workload
104
+ job = TestWFC.job(:c4, nil)
105
+ job.recursive_clean
106
+
107
+ workload = Workflow::Orchestrator.job_workload(job)
108
+ assert_equal [], workload[job.step(:c2)]
109
+ assert workload.select{|job,deps| deps.include? job }.empty?
110
+ assert_include workload[job], job.dependencies.first
111
+
112
+ workload = Workflow::Orchestrator.job_workload([job])
113
+ assert_equal [], workload[job.step(:c2)]
114
+ assert workload.select{|job,deps| deps.include? job }.empty?
115
+ assert_include workload[job], job.dependencies.first
116
+ end
117
+ end
@@ -0,0 +1,31 @@
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
+ # Define a small workflow used by tests
5
+ module TestSchedWF
6
+ extend Workflow
7
+
8
+ task :a1 => :string do self.task_name.to_s end
9
+
10
+ dep :a1
11
+ task :b1 => :string do self.task_name.to_s end
12
+ end
13
+
14
+ class TestSchedulerJob < Test::Unit::TestCase
15
+ def test_basic_template
16
+ job = TestSchedWF.job(:b1, "TEST")
17
+ TmpFile.with_file do |batch_dir|
18
+ tpl = SchedulerJob.job_template(job, :batch_dir => batch_dir, :lua_modules => 'java')
19
+ assert_include tpl, 'module load java'
20
+ assert_include tpl, '#STEP_PATH'
21
+ end
22
+ end
23
+
24
+ def test_singularity
25
+ job = TestSchedWF.job(:b1, "TEST")
26
+ TmpFile.with_file do |batch_dir|
27
+ tpl = SchedulerJob.job_template(job, :batch_dir => batch_dir, :singularity => true, :singularity_img => '/tmp/img.sif')
28
+ assert_include tpl, 'singularity exec'
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
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
+ # Define a small workflow used by tests
5
+ module TestSchedWF
6
+ extend Workflow
7
+
8
+ task :a1 => :string do self.task_name.to_s end
9
+
10
+ dep :a1
11
+ task :b1 => :string do self.task_name.to_s end
12
+ end
13
+
14
+ class TestSchedulerJobLSF < Test::Unit::TestCase
15
+ def test_basic_template
16
+ job = TestSchedWF.job(:b1, "TEST")
17
+ TmpFile.with_file do |batch_dir|
18
+ tpl = LSF.job_template(job, :batch_dir => batch_dir, :lua_modules => 'java')
19
+ assert_include tpl, 'module load java'
20
+ assert_include tpl, '#STEP_PATH'
21
+ assert_include tpl, '#BSUB'
22
+ end
23
+ end
24
+
25
+ def test_singularity
26
+ job = TestSchedWF.job(:b1, "TEST")
27
+ TmpFile.with_file do |batch_dir|
28
+ tpl = LSF.job_template(job, :batch_dir => batch_dir, :singularity => true, :singularity_img => '/tmp/img.sif')
29
+ assert_include tpl, 'singularity exec'
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
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
+ # Define a small workflow used by tests
5
+ module TestSchedWF
6
+ extend Workflow
7
+
8
+ task :a1 => :string do self.task_name.to_s end
9
+
10
+ dep :a1
11
+ task :b1 => :string do self.task_name.to_s end
12
+ end
13
+
14
+ class TestSchedulerJobPBS < Test::Unit::TestCase
15
+ def test_basic_template
16
+ job = TestSchedWF.job(:b1, "TEST")
17
+ TmpFile.with_file do |batch_dir|
18
+ tpl = PBS.job_template(job, :batch_dir => batch_dir, :lua_modules => 'java')
19
+ assert_include tpl, 'module load java'
20
+ assert_include tpl, '#STEP_PATH'
21
+ assert_include tpl, '#PBS'
22
+ end
23
+ end
24
+
25
+ def test_singularity
26
+ job = TestSchedWF.job(:b1, "TEST")
27
+ TmpFile.with_file do |batch_dir|
28
+ tpl = PBS.job_template(job, :batch_dir => batch_dir, :singularity => true, :singularity_img => '/tmp/img.sif')
29
+ assert_include tpl, 'singularity exec'
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
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
+ # Define a small workflow used by tests
5
+ module TestSchedWF
6
+ extend Workflow
7
+
8
+ task :a1 => :string do self.task_name.to_s end
9
+
10
+ dep :a1
11
+ task :b1 => :string do self.task_name.to_s end
12
+ end
13
+
14
+ class TestSchedulerJobSLURM < Test::Unit::TestCase
15
+ def test_basic_template
16
+ job = TestSchedWF.job(:b1, "TEST")
17
+ TmpFile.with_file do |batch_dir|
18
+ tpl = SLURM.job_template(job, :batch_dir => batch_dir, :lua_modules => 'java')
19
+ assert_include tpl, 'module load java'
20
+ assert_include tpl, '#STEP_PATH'
21
+ assert_include tpl, '#SBATCH'
22
+ end
23
+ end
24
+
25
+ def test_singularity
26
+ job = TestSchedWF.job(:b1, "TEST")
27
+ TmpFile.with_file do |batch_dir|
28
+ tpl = SLURM.job_template(job, :batch_dir => batch_dir, :singularity => true, :singularity_img => '/tmp/img.sif')
29
+ assert_include tpl, 'singularity exec'
30
+ end
31
+ end
32
+ end