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
@@ -42,6 +42,8 @@ module Task
42
42
  memory_inputs = provided_inputs
43
43
  end
44
44
 
45
+ memory_inputs = nil if Array === memory_inputs && memory_inputs.compact.empty?
46
+ memory_inputs = nil if Hash === memory_inputs && memory_inputs.empty?
45
47
  Persist.memory("Task job #{self.name}", repo: Workflow.job_cache, other: {task: self.name, id: id, provided_inputs: memory_inputs}) do
46
48
  provided_inputs, id = id, nil if (provided_inputs.nil? || provided_inputs.empty?) && (Hash === id || Array === id)
47
49
  provided_inputs = {} if provided_inputs.nil?
data/scout-gear.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: scout-gear 10.9.0 ruby lib
5
+ # stub: scout-gear 10.10.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-gear".freeze
9
- s.version = "10.9.0".freeze
9
+ s.version = "10.10.1".freeze
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
@@ -106,8 +106,17 @@ Gem::Specification.new do |s|
106
106
  "lib/scout/workflow.rb",
107
107
  "lib/scout/workflow/definition.rb",
108
108
  "lib/scout/workflow/deployment.rb",
109
- "lib/scout/workflow/deployment/orchestrator.rb",
109
+ "lib/scout/workflow/deployment/local.rb",
110
+ "lib/scout/workflow/deployment/orchestrator/batches.rb",
111
+ "lib/scout/workflow/deployment/orchestrator/chains.rb",
112
+ "lib/scout/workflow/deployment/orchestrator/rules.rb",
113
+ "lib/scout/workflow/deployment/orchestrator/workload.rb",
110
114
  "lib/scout/workflow/deployment/queue.rb",
115
+ "lib/scout/workflow/deployment/scheduler.rb",
116
+ "lib/scout/workflow/deployment/scheduler/job.rb",
117
+ "lib/scout/workflow/deployment/scheduler/lfs.rb",
118
+ "lib/scout/workflow/deployment/scheduler/pbs.rb",
119
+ "lib/scout/workflow/deployment/scheduler/slurm.rb",
111
120
  "lib/scout/workflow/deployment/trace.rb",
112
121
  "lib/scout/workflow/documentation.rb",
113
122
  "lib/scout/workflow/entity.rb",
@@ -237,13 +246,23 @@ Gem::Specification.new do |s|
237
246
  "test/scout/tsv/util/test_unzip.rb",
238
247
  "test/scout/work_queue/test_socket.rb",
239
248
  "test/scout/work_queue/test_worker.rb",
240
- "test/scout/workflow/deployment/test_orchestrator.rb",
249
+ "test/scout/workflow/deployment/orchestrator/test_batches.rb",
250
+ "test/scout/workflow/deployment/orchestrator/test_chains.rb",
251
+ "test/scout/workflow/deployment/orchestrator/test_rules.rb",
252
+ "test/scout/workflow/deployment/orchestrator/test_workload.rb",
253
+ "test/scout/workflow/deployment/scheduler/test_job.rb",
254
+ "test/scout/workflow/deployment/scheduler/test_lfs.rb",
255
+ "test/scout/workflow/deployment/scheduler/test_pbs.rb",
256
+ "test/scout/workflow/deployment/scheduler/test_slurm.rb",
257
+ "test/scout/workflow/deployment/test_local.rb",
258
+ "test/scout/workflow/deployment/test_scheduler.rb",
241
259
  "test/scout/workflow/deployment/test_trace.rb",
242
260
  "test/scout/workflow/step/test_archive.rb",
243
261
  "test/scout/workflow/step/test_children.rb",
244
262
  "test/scout/workflow/step/test_dependencies.rb",
245
263
  "test/scout/workflow/step/test_info.rb",
246
264
  "test/scout/workflow/step/test_load.rb",
265
+ "test/scout/workflow/step/test_progress.rb",
247
266
  "test/scout/workflow/step/test_provenance.rb",
248
267
  "test/scout/workflow/step/test_status.rb",
249
268
  "test/scout/workflow/task/test_dependencies.rb",
@@ -334,7 +334,7 @@ workdir.glob("**/command.batch").sort_by{|f| File.mtime(f)}.each do |fcmd|
334
334
  step_path = step_line.split(": ").last.strip
335
335
  step = Step.new step_path
336
336
  has_bar = false
337
- (step.rec_dependencies + [step]).reverse.each do |j|
337
+ (step.rec_dependencies.to_a + [step]).reverse.each do |j|
338
338
  next if j.done?
339
339
  if j.file(:progress).exists?
340
340
  bar = Log::ProgressBar.new
@@ -12,20 +12,12 @@ $ #{$0} <workflow> <command> [<subcommands>] [<options>] [<arg> ...]
12
12
 
13
13
  -h--help Print this help
14
14
  EOF
15
- if options[:help]
16
- if defined? scout_usage
17
- scout_usage
18
- else
19
- puts SOPT.doc
20
- end
21
- exit 0
22
- end
23
15
 
24
16
  workflow = ARGV.shift
25
17
 
26
18
  if workflow == '-h'
27
19
  if defined? scout_usage
28
- scout_usage
20
+ scout_usage
29
21
  else
30
22
  puts SOPT.doc
31
23
  end
@@ -99,11 +91,11 @@ puts
99
91
  puts Log.color :magenta, "## COMMANDS"
100
92
  puts
101
93
  puts Log.color :magenta, "Command:"
102
- puts
94
+ puts
103
95
  puts " scout #{$previous_commands * " "} "
104
- puts
96
+ puts
105
97
  puts Log.color :magenta, "Subcommands:"
106
- puts
98
+ puts
107
99
 
108
100
  commands(prev).each do |command|
109
101
  directory = File.directory? dir[command].find
@@ -113,4 +105,4 @@ commands(prev).each do |command|
113
105
  puts " " << command
114
106
  end
115
107
  end
116
-
108
+
@@ -31,7 +31,7 @@ if options[:inputs]
31
31
  names, values = step.info.values_at :input_names, :inputs
32
32
  names.zip(values).each do |name,value|
33
33
  puts [Log.color(:title, name), Log.fingerprint(value)] * " = "
34
- end
34
+ end if names
35
35
  elsif options[:recursive_inputs]
36
36
  step.recursive_inputs.each do |name,value|
37
37
  puts [Log.color(:title, name), Log.fingerprint(value)] * " = "
@@ -16,10 +16,13 @@ Run a workflow job
16
16
  $ #{$0} [<options>] <workflow> <task>
17
17
 
18
18
  -h--help Print this help
19
+ --workflows* Other workflows to load
19
20
  --nostream Disable job streaming
20
21
  --update Update jobs with newer dependencies
21
22
  --deploy* Deploy mode: serial, local, queue, or SLURM (default 'serial')
23
+ --deploy_rules* Deployment rules; can be files of keywords
22
24
  --fork Fork and return path
25
+ --exec Exec and return output
23
26
  --load_inputs* Directory or file with inputs files to load
24
27
  --save_inputs* Directory or tar.gz file path to store inputs
25
28
  -jn--jobname* Name to use as job identifier
@@ -33,33 +36,45 @@ EOF
33
36
 
34
37
  workflow_name, task_name = ARGV
35
38
 
39
+
40
+ help, workflows, provenance, clean, recursive_clean, clean_task, load_inputs, save_inputs, jobname, printpath, deploy, deploy_rules, override_deps, do_fork, do_exec = IndiferentHash.process_options options,
41
+ :help, :workflows, :provenance, :clean, :recursive_clean, :clean_task, :load_inputs, :save_inputs, :jobname, :printpath, :deploy, :deploy_rules, :override_deps, :fork, :exec,
42
+ :deploy => 'serial'
43
+
36
44
  raise MissingParameterException.new :workflow if workflow_name.nil?
37
45
 
38
46
  workflow = Workflow.require_workflow workflow_name
47
+
48
+ workflows = workflows.split(/,\s*/) if workflows
49
+ workflows.each{|wf| Workflow.require_workflow wf } if workflows
50
+
39
51
  task_name = task_name.to_sym if task_name
40
52
  task = workflow.tasks[task_name.to_sym] if task_name
41
53
 
42
- options[:help] = true if task.nil?
43
-
44
- help, provenance, clean, recursive_clean, clean_task, load_inputs, save_inputs, jobname, printpath, deploy, override_deps, do_fork = IndiferentHash.process_options options,
45
- :help, :provenance, :clean, :recursive_clean, :clean_task, :load_inputs, :save_inputs, :jobname, :printpath, :deploy, :override_deps, :fork,
46
- :deploy => 'serial'
54
+ help = true if task.nil?
47
55
 
48
56
  if help
49
57
  if defined? scout_usage
50
- scout_usage
58
+ scout_usage
51
59
  else
52
60
  puts SOPT.doc
53
61
  end
54
62
 
55
63
  puts workflow.usage(task) if workflow
56
- exit 0
64
+
65
+ if task_name && task.nil?
66
+ exit -1
67
+ else
68
+ exit 0
69
+ end
57
70
  end
58
71
 
72
+ task = workflow.tasks[task_name]
73
+
59
74
  job_inputs = task.get_SOPT
60
75
 
61
76
  if load_inputs
62
- job_inputs = job_inputs.merge(workflow.tasks[task_name].load_inputs(load_inputs))
77
+ job_inputs = job_inputs.merge(task.load_inputs(load_inputs))
63
78
  end
64
79
 
65
80
  if override_deps
@@ -99,10 +114,21 @@ elsif do_fork
99
114
  job.fork
100
115
  puts job.path
101
116
  exit 0
117
+ elsif do_exec
118
+ puts job.exec
119
+ exit 0
102
120
  elsif save_inputs
103
121
  puts job.save_inputs(save_inputs)
104
122
  exit 0
105
123
  else
124
+ require 'scout/workflow/deployment'
125
+
126
+ if deploy_rules.nil?
127
+ rules = Workflow::Orchestrator.load_rules_for_job(job)
128
+ else
129
+ deploy_files = deploy_rules.split(/,\s*/)
130
+ rules = Workflow::Orchestrator.load_rules deploy_files
131
+ end
106
132
 
107
133
  case deploy
108
134
  when "queue"
@@ -112,28 +138,40 @@ else
112
138
  puts save_inputs
113
139
  exit
114
140
  end
141
+ when 'dry', 'dryrun', 'debug'
142
+ batches = Workflow::Orchestrator.job_batches rules, job
143
+ batches.each do |batch|
144
+ top = batch[:top_level]
145
+ jobs = batch[:jobs]
146
+ puts Log.color :title, Log.fingerprint(top)
147
+ puts batch[:rules].to_yaml
148
+ deps = batch[:deps].collect{|dep| dep[:top_level] }
149
+ provided_inputs = jobs.inject({}){|acc,j| acc = IndiferentHash.add_defaults acc, j.provided_inputs }
150
+ provided_inputs.each do |i,v|
151
+ puts Log.color :green, "#{i}: " + Log.color(:blue, Log.fingerprint(v))
152
+ end
153
+ other = jobs - [top]
154
+ puts Log.color :subtitle, 'Other jobs: ' + Log.color(:blue, other.collect{|d| d.short_path}.uniq * ', ' ) if other.any?
155
+ puts Log.color :subtitle, 'Dependencies: ' + Log.color(:blue, deps.collect{|d| d.short_path}.uniq * ', ' ) if deps.any?
156
+ end
157
+ exit 0
115
158
  when "serial"
116
159
  job.run(true)
117
160
  when "local"
118
- refresh = Scout::Config.get :refresh, :deploy, :local, :orchestrator, default: 0.5
119
- orchestrator = Workflow::Orchestrator.new refresh.to_f, "cpus" => Misc.processors
120
- orchestrator.process({}, job)
121
- when "slurm"
122
- require 'rbbt-scout'
123
- require_relative '../../modules/rbbt-util/lib/rbbt/hpc'
124
- slurm_options = {}
125
- HPC::BATCH_MODULE = HPC.batch_system "SLURM"
126
- HPC::BATCH_MODULE.orchestrate_job(job, slurm_options)
127
- job.grace
128
- else
129
- if deploy.end_with?('-slurm')
130
- server = deploy.sub('-slurm','')
131
- OffsiteStep.setup(job, server: server, slurm: true)
161
+ Workflow::LocalExecutor.produce job, rules
162
+ when 'batch', 'sched', 'cluster', "slurm", 'pbs', 'lsf'
163
+ Workflow::Scheduler.produce job, rules
164
+ exit 0
165
+ else
166
+ raise 'Use scout-camp instead of scout' unless defined? OffsiteStep
167
+ if deploy.end_with?('-batch')
168
+ server = deploy.sub('-batch','')
169
+ OffsiteStep.setup(job, server: server, batch: true)
132
170
  else
133
171
  OffsiteStep.setup(job, server: deploy)
134
172
  end
135
173
 
136
- job.run
174
+ job.run(true)
137
175
  end unless job.done?
138
176
 
139
177
  if printpath
@@ -147,5 +185,3 @@ else
147
185
  end
148
186
  end
149
187
  end
150
-
151
-
@@ -0,0 +1,138 @@
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
+
5
+ module TestWFA
6
+ extend Workflow
7
+
8
+ task :a1 => :string do self.task_name.to_s end
9
+
10
+ dep :a1
11
+ task :a2 => :string do self.task_name.to_s end
12
+
13
+ dep :a2
14
+ task :a3 => :string do self.task_name.to_s end
15
+ end
16
+
17
+ module TestWFB
18
+ extend Workflow
19
+
20
+ dep TestWFA, :a2
21
+ task :b1 => :string do self.task_name.to_s end
22
+
23
+ dep :b1
24
+ task :b2 => :string do self.task_name.to_s end
25
+ end
26
+
27
+ module TestWFC
28
+ extend Workflow
29
+
30
+ dep TestWFA, :a1
31
+ dep_task :c1, TestWFB, :b2
32
+
33
+ task :c2 => :string do self.task_name.to_s end
34
+
35
+ dep :c1
36
+ dep :c2
37
+ task :c3 => :string do self.task_name.to_s end
38
+
39
+ dep_task :c4, TestWFC, :c3
40
+ end
41
+
42
+ module TestWFD
43
+ extend Workflow
44
+
45
+ dep TestWFC, :c3, :jobname => "First c3"
46
+ dep TestWFC, :c3, :jobname => "Second c3"
47
+ task :d1 => :string do self.task_name.to_s end
48
+ end
49
+
50
+ module TestDeepWF
51
+ extend Workflow
52
+
53
+ dep_task :deep1, TestWFD, :d1
54
+
55
+ input :size, :integer, "Number of dependencies", 100
56
+ dep :deep1 do |jobname,options|
57
+ options[:size].to_i.times.collect{|i|
58
+ {:jobname => "step-#{i}"}
59
+ }
60
+ end
61
+ task :suite => :array do
62
+ end
63
+ end
64
+
65
+ class TestOrchestrateBatches < Test::Unit::TestCase
66
+
67
+ RULES = IndiferentHash.setup(YAML.load(<<-EOF))
68
+ ---
69
+ defaults:
70
+ queue: first_queue
71
+ time: 1h
72
+ log: 2
73
+ config_keys: key1 value1 token1
74
+ chains:
75
+ chain_a_b:
76
+ tasks: TestWFB#b1, TestWFB#b2, TestWFA#a1, TestWFA#a2
77
+ config_keys: key2 value2 token2, key3 value3 token3.1 token3.2
78
+ chain_a:
79
+ workflow: TestWFA
80
+ tasks: a1, a2, a3
81
+ config_keys: key2 value2 token2, key3 value3 token3.1 token3.2
82
+ chain_b:
83
+ workflow: TestWFB
84
+ tasks: b1, b2
85
+ chain_b2:
86
+ tasks: TestWFB#b1, TestWFB#b2, TestWFA#a1
87
+ chain_d:
88
+ tasks: TestWFD#d1, TestWFC#c1, TestWFC#c2, TestWFC#c3
89
+ TestWFA:
90
+ defaults:
91
+ log: 4
92
+ config_keys: key4 value4 token4
93
+ time: 10min
94
+ a1:
95
+ cpus: 10
96
+ config_keys: key5 value5 token5
97
+ TestWFC:
98
+ defaults:
99
+ skip: true
100
+ log: 4
101
+ time: 10s
102
+ EOF
103
+
104
+ def test_chain_batches
105
+ job = TestWFD.job(:d1, nil)
106
+ job.recursive_clean
107
+
108
+ job_chains_map = Workflow::Orchestrator.job_chains(RULES, job)
109
+ workload = Workflow::Orchestrator.job_workload(job)
110
+ batches = Workflow::Orchestrator.chain_batches(RULES, job_chains_map, workload)
111
+ assert_equal 3, batches.length
112
+ end
113
+
114
+
115
+ def test_job_batches_d
116
+ job = TestWFD.job(:d1, nil)
117
+ job.recursive_clean
118
+
119
+ batches = Workflow::Orchestrator.job_batches(RULES, [job])
120
+ assert_equal 3, batches.length
121
+ end
122
+
123
+ def test_job_batches_c4
124
+ job = TestWFC.job(:c4, nil)
125
+ job.recursive_clean
126
+
127
+ batches = Workflow::Orchestrator.job_batches(RULES, job)
128
+ assert_equal 1, batches.length
129
+ end
130
+
131
+ def test_job_batches_a2
132
+ job = TestWFA.job(:a2, nil)
133
+ job.recursive_clean
134
+
135
+ batches = Workflow::Orchestrator.job_batches({}, job)
136
+ assert_equal 2, batches.length
137
+ end
138
+ end
@@ -0,0 +1,171 @@
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
+
6
+ module TestWFA
7
+ extend Workflow
8
+
9
+ task :a1 => :string do self.task_name.to_s end
10
+
11
+ dep :a1
12
+ task :a2 => :string do self.task_name.to_s end
13
+
14
+ dep :a2
15
+ task :a3 => :string do self.task_name.to_s end
16
+ end
17
+
18
+ module TestWFB
19
+ extend Workflow
20
+
21
+ dep TestWFA, :a2
22
+ task :b1 => :string do self.task_name.to_s end
23
+
24
+ dep :b1
25
+ task :b2 => :string do self.task_name.to_s end
26
+ end
27
+
28
+ module TestWFC
29
+ extend Workflow
30
+
31
+ dep TestWFA, :a1
32
+ dep_task :c1, TestWFB, :b2
33
+
34
+ task :c2 => :string do self.task_name.to_s end
35
+
36
+ dep :c1
37
+ dep :c2
38
+ task :c3 => :string do self.task_name.to_s end
39
+
40
+ dep_task :c4, TestWFC, :c3
41
+ end
42
+
43
+ module TestWFD
44
+ extend Workflow
45
+
46
+ dep TestWFC, :c3, :jobname => "First c3"
47
+ dep TestWFC, :c3, :jobname => "Second c3"
48
+ task :d1 => :string do self.task_name.to_s end
49
+ end
50
+
51
+ module TestDeepWF
52
+ extend Workflow
53
+
54
+ dep_task :deep1, TestWFD, :d1
55
+
56
+ input :size, :integer, "Number of dependencies", 100
57
+ dep :deep1 do |jobname,options|
58
+ options[:size].to_i.times.collect{|i|
59
+ {:jobname => "step-#{i}"}
60
+ }
61
+ end
62
+ task :suite => :array do
63
+ end
64
+ end
65
+
66
+ class TestOrchestrateChains < Test::Unit::TestCase
67
+
68
+ RULES = IndiferentHash.setup(YAML.load(<<-EOF))
69
+ ---
70
+ defaults:
71
+ queue: first_queue
72
+ time: 1h
73
+ log: 2
74
+ config_keys: key1 value1 token1
75
+ chains:
76
+ chain_a_b:
77
+ tasks: TestWFB#b1, TestWFB#b2, TestWFA#a1, TestWFA#a2
78
+ comment: Should not include TestWFA#a1
79
+ chain_a:
80
+ workflow: TestWFA
81
+ tasks: a1, a2, a3
82
+ config_keys: key2 value2 token2, key3 value3 token3.1 token3.2
83
+ chain_b:
84
+ workflow: TestWFB
85
+ tasks: b1, b2
86
+ chain_b2:
87
+ tasks: TestWFB#b1, TestWFB#b2, TestWFA#a1
88
+ chain_d:
89
+ tasks: TestWFD#d1, TestWFC#c1, TestWFC#c2, TestWFC#c3
90
+ TestWFA:
91
+ defaults:
92
+ log: 4
93
+ config_keys: key4 value4 token4
94
+ a1:
95
+ cpus: 10
96
+ config_keys: key5 value5 token5
97
+ TestWFC:
98
+ defaults:
99
+ skip: true
100
+ log: 4
101
+ EOF
102
+
103
+ def test_parse_chains
104
+ chains = Workflow::Orchestrator.parse_chains RULES
105
+ assert chains[:chain_a][:tasks]["TestWFA"].include?("a1")
106
+ end
107
+
108
+ def test_job_chain_a
109
+ job = TestWFA.job(:a3, nil)
110
+ job.recursive_clean
111
+
112
+ job_chains = Workflow::Orchestrator.job_chains(RULES, job)
113
+ job_chains = NamedArray.setup(job_chains, job_chains.collect{|n,i| n })
114
+
115
+ assert_equal %w(chain_a_b chain_a), job_chains.fields
116
+ assert_equal 3, job_chains["chain_a"].last[:jobs].length
117
+ assert_equal job, job_chains["chain_a"].last[:top_level]
118
+ end
119
+
120
+ def test_job_chain_b
121
+ job = TestWFB.job(:b2, nil)
122
+ job.recursive_clean
123
+
124
+ job_chains = Workflow::Orchestrator.job_chains(RULES, job)
125
+ job_chains = NamedArray.setup(job_chains, job_chains.collect{|n,i| n })
126
+
127
+ assert_equal %w(chain_a chain_b chain_b2 chain_a_b).sort, job_chains.fields.sort
128
+
129
+ assert_equal 2, job_chains["chain_a"].last[:jobs].length
130
+ assert_equal job.step("a2"), job_chains["chain_a"].last[:top_level]
131
+
132
+ assert_equal 2, job_chains["chain_b"].last[:jobs].length
133
+ assert_equal job, job_chains["chain_b"].last[:top_level]
134
+
135
+ assert_equal 2, job_chains["chain_b2"].last[:jobs].length
136
+ assert_equal job, job_chains["chain_b2"].last[:top_level]
137
+
138
+ assert_equal 4, job_chains["chain_a_b"].last[:jobs].length
139
+ assert_equal job, job_chains["chain_a_b"].last[:top_level]
140
+ end
141
+
142
+ def test_job_chains_double
143
+ job = TestWFD.job(:d1, nil)
144
+ job.recursive_clean
145
+
146
+ job_chains = Workflow::Orchestrator.job_chains(RULES, job)
147
+ job_chains = NamedArray.setup(job_chains, job_chains.collect{|n,i| n })
148
+
149
+ assert_equal 2, job_chains.select{|n,i| n == 'chain_a' }.length
150
+ assert_equal ["First c3", "Second c3"].sort, job_chains.
151
+ select{|n,i| n == 'chain_a' }.
152
+ collect{|n,i| i[:top_level].name }.sort
153
+
154
+ assert_equal 1, job_chains.select{|n,i| n == 'chain_d' }.length
155
+ end
156
+
157
+ def __test_benchmark
158
+
159
+ job = TestDeepWF.job(:suite, :size => 100)
160
+ job.recursive_clean
161
+
162
+ Misc.benchmark(10) do
163
+ Workflow::Orchestrator.job_chains(RULES, job)
164
+ end
165
+
166
+ end
167
+
168
+
169
+
170
+ end
171
+