Merge branch '4031-fix-graph-connections' closes #4031
[arvados.git] / apps / workbench / test / controllers / pipeline_instances_controller_test.rb
1 require 'test_helper'
2
3 class PipelineInstancesControllerTest < ActionController::TestCase
4   include PipelineInstancesHelper
5
6   test "one" do
7     r = [{started_at: 1, finished_at: 3}]
8     assert_equal 2, determine_wallclock_runtime(r)
9
10     r = [{started_at: 1, finished_at: 5}]
11     assert_equal 4, determine_wallclock_runtime(r)
12
13     r = [{started_at: 1, finished_at: 2}, {started_at: 3, finished_at: 5}]
14     assert_equal 3, determine_wallclock_runtime(r)
15
16     r = [{started_at: 3, finished_at: 5}, {started_at: 1, finished_at: 2}]
17     assert_equal 3, determine_wallclock_runtime(r)
18
19     r = [{started_at: 3, finished_at: 5}, {started_at: 1, finished_at: 2},
20          {started_at: 2, finished_at: 4}]
21     assert_equal 4, determine_wallclock_runtime(r)
22
23     r = [{started_at: 1, finished_at: 5}, {started_at: 2, finished_at: 3}]
24     assert_equal 4, determine_wallclock_runtime(r)
25
26     r = [{started_at: 3, finished_at: 5}, {started_at: 1, finished_at: 4}]
27     assert_equal 4, determine_wallclock_runtime(r)
28
29     r = [{started_at: 1, finished_at: 4}, {started_at: 3, finished_at: 5}]
30     assert_equal 4, determine_wallclock_runtime(r)
31
32     r = [{started_at: 1, finished_at: 4}, {started_at: 3, finished_at: 5},
33          {started_at: 5, finished_at: 8}]
34     assert_equal 7, determine_wallclock_runtime(r)
35
36     r = [{started_at: 1, finished_at: 4}, {started_at: 3, finished_at: 5},
37          {started_at: 6, finished_at: 8}]
38     assert_equal 6, determine_wallclock_runtime(r)
39   end
40
41   test "generate graph" do
42
43     use_token 'admin'
44
45     pipeline_for_graph = {
46       state: 'Complete',
47       uuid: 'zzzzz-d1hrv-9fm8l10i9z2kqc9',
48       components: {
49         stage1: {
50           repository: 'foo',
51           script: 'hash',
52           script_version: 'master',
53           job: {uuid: 'zzzzz-8i9sb-graphstage10000'},
54           output_uuid: 'zzzzz-4zz18-bv31uwvy3neko22'
55         },
56         stage2: {
57           repository: 'foo',
58           script: 'hash2',
59           script_version: 'master',
60           script_parameters: {
61             input: 'fa7aeb5140e2848d39b416daeef4ffc5+45'
62           },
63           job: {uuid: 'zzzzz-8i9sb-graphstage20000'},
64           output_uuid: 'zzzzz-4zz18-uukreo9rbgwsujx'
65         }
66       }
67     }
68
69     @controller.params['tab_pane'] = "Graph"
70     provenance, pips = @controller.graph([pipeline_for_graph])
71
72     graph_test_collection1 = find_fixture Collection, "graph_test_collection1"
73     stage1 = find_fixture Job, "graph_stage1"
74     stage2 = find_fixture Job, "graph_stage2"
75
76     ['component_zzzzz-d1hrv-9fm8l10i9z2kqc9_stage1',
77      'component_zzzzz-d1hrv-9fm8l10i9z2kqc9_stage2',
78      stage1.uuid,
79      stage2.uuid,
80      stage1.output,
81      stage2.output,
82      pipeline_for_graph[:components][:stage1][:output_uuid],
83      pipeline_for_graph[:components][:stage2][:output_uuid]
84     ].each do |k|
85
86       assert_not_nil provenance[k], "Expected key #{k} in provenance set"
87       assert_equal 1, pips[k], "Expected key #{k} in pips set" if !k.start_with? "component_"
88     end
89
90     prov_svg = ProvenanceHelper::create_provenance_graph provenance, "provenance_svg", {
91         :request => RequestDuck,
92         :all_script_parameters => true,
93         :combine_jobs => :script_and_version,
94         :pips => pips,
95         :only_components => true }
96
97     stage1_id = "#{stage1[:script]}_#{stage1[:script_version]}_#{Digest::MD5.hexdigest(stage1[:script_parameters].to_json)}"
98     stage2_id = "#{stage2[:script]}_#{stage2[:script_version]}_#{Digest::MD5.hexdigest(stage2[:script_parameters].to_json)}"
99
100     stage1_out = stage1[:output].gsub('+','\\\+')
101
102     assert_match /#{stage1_id}&#45;&gt;#{stage1_out}/, prov_svg
103
104     assert_match /#{stage1_out}&#45;&gt;#{stage2_id}/, prov_svg
105
106   end
107
108   test "generate graph compare" do
109
110     use_token 'admin'
111
112     pipeline_for_graph1 = {
113       state: 'Complete',
114       uuid: 'zzzzz-d1hrv-9fm8l10i9z2kqc9',
115       components: {
116         stage1: {
117           repository: 'foo',
118           script: 'hash',
119           script_version: 'master',
120           job: {uuid: 'zzzzz-8i9sb-graphstage10000'},
121           output_uuid: 'zzzzz-4zz18-bv31uwvy3neko22'
122         },
123         stage2: {
124           repository: 'foo',
125           script: 'hash2',
126           script_version: 'master',
127           script_parameters: {
128             input: 'fa7aeb5140e2848d39b416daeef4ffc5+45'
129           },
130           job: {uuid: 'zzzzz-8i9sb-graphstage20000'},
131           output_uuid: 'zzzzz-4zz18-uukreo9rbgwsujx'
132         }
133       }
134     }
135
136     pipeline_for_graph2 = {
137       state: 'Complete',
138       uuid: 'zzzzz-d1hrv-9fm8l10i9z2kqc0',
139       components: {
140         stage1: {
141           repository: 'foo',
142           script: 'hash',
143           script_version: 'master',
144           job: {uuid: 'zzzzz-8i9sb-graphstage10000'},
145           output_uuid: 'zzzzz-4zz18-bv31uwvy3neko22'
146         },
147         stage2: {
148           repository: 'foo',
149           script: 'hash2',
150           script_version: 'master',
151           script_parameters: {
152           },
153           job: {uuid: 'zzzzz-8i9sb-graphstage30000'},
154           output_uuid: 'zzzzz-4zz18-uukreo9rbgwsujj'
155         }
156       }
157     }
158
159     @controller.params['tab_pane'] = "Graph"
160     provenance, pips = @controller.graph([pipeline_for_graph1, pipeline_for_graph2])
161
162     collection1 = find_fixture Collection, "graph_test_collection1"
163
164     stage1 = find_fixture Job, "graph_stage1"
165     stage2 = find_fixture Job, "graph_stage2"
166     stage3 = find_fixture Job, "graph_stage3"
167
168     [['component_zzzzz-d1hrv-9fm8l10i9z2kqc9_stage1', nil],
169      ['component_zzzzz-d1hrv-9fm8l10i9z2kqc9_stage2', nil],
170      ['component_zzzzz-d1hrv-9fm8l10i9z2kqc0_stage1', nil],
171      ['component_zzzzz-d1hrv-9fm8l10i9z2kqc0_stage2', nil],
172      [stage1.uuid, 3],
173      [stage2.uuid, 1],
174      [stage3.uuid, 2],
175      [stage1.output, 3],
176      [stage2.output, 1],
177      [stage3.output, 2],
178      [pipeline_for_graph1[:components][:stage1][:output_uuid], 3],
179      [pipeline_for_graph1[:components][:stage2][:output_uuid], 1],
180      [pipeline_for_graph2[:components][:stage2][:output_uuid], 2]
181     ].each do |k|
182       assert_not_nil provenance[k[0]], "Expected key #{k[0]} in provenance set"
183       assert_equal k[1], pips[k[0]], "Expected key #{k} in pips" if !k[0].start_with? "component_"
184     end
185
186     prov_svg = ProvenanceHelper::create_provenance_graph provenance, "provenance_svg", {
187         :request => RequestDuck,
188         :all_script_parameters => true,
189         :combine_jobs => :script_and_version,
190         :pips => pips,
191         :only_components => true }
192
193     collection1_id = collection1.portable_data_hash.gsub('+','\\\+')
194
195     stage2_id = "#{stage2[:script]}_#{stage2[:script_version]}_#{Digest::MD5.hexdigest(stage2[:script_parameters].to_json)}"
196     stage3_id = "#{stage3[:script]}_#{stage3[:script_version]}_#{Digest::MD5.hexdigest(stage3[:script_parameters].to_json)}"
197
198     stage2_out = stage2[:output].gsub('+','\\\+')
199     stage3_out = stage3[:output].gsub('+','\\\+')
200
201     assert_match /#{collection1_id}&#45;&gt;#{stage2_id}/, prov_svg
202     assert_match /#{collection1_id}&#45;&gt;#{stage3_id}/, prov_svg
203
204     assert_match /#{stage2_id}&#45;&gt;#{stage2_out}/, prov_svg
205     assert_match /#{stage3_id}&#45;&gt;#{stage3_out}/, prov_svg
206
207   end
208
209 end