tengine_job 0.6.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +23 -0
  4. data/Gemfile.lock +109 -0
  5. data/README.rdoc +20 -0
  6. data/Rakefile +42 -0
  7. data/VERSION +1 -0
  8. data/examples/0004_retry_one_layer.rb +24 -0
  9. data/examples/0004_retry_one_layer.sh +38 -0
  10. data/examples/0005_retry_two_layer.rb +54 -0
  11. data/examples/0005_retry_two_layer.sh +80 -0
  12. data/examples/0006_retry_three_layer.rb +58 -0
  13. data/examples/0006_retry_three_layer.sh +74 -0
  14. data/examples/0007_simple_jobnet.rb +7 -0
  15. data/examples/0021_dynamic_env.rb +20 -0
  16. data/examples/VERSION +1 -0
  17. data/examples/tengine_job_test.sh +10 -0
  18. data/lib/tengine/job.rb +94 -0
  19. data/lib/tengine/job/category.rb +54 -0
  20. data/lib/tengine/job/connectable.rb +43 -0
  21. data/lib/tengine/job/drivers/job_control_driver.rb +82 -0
  22. data/lib/tengine/job/drivers/job_execution_driver.rb +30 -0
  23. data/lib/tengine/job/drivers/jobnet_control_driver.rb +117 -0
  24. data/lib/tengine/job/drivers/schedule_driver.rb +30 -0
  25. data/lib/tengine/job/dsl_binder.rb +12 -0
  26. data/lib/tengine/job/dsl_evaluator.rb +18 -0
  27. data/lib/tengine/job/dsl_loader.rb +180 -0
  28. data/lib/tengine/job/edge.rb +150 -0
  29. data/lib/tengine/job/element_selector_notation.rb +169 -0
  30. data/lib/tengine/job/end.rb +32 -0
  31. data/lib/tengine/job/executable.rb +74 -0
  32. data/lib/tengine/job/execution.rb +141 -0
  33. data/lib/tengine/job/expansion.rb +37 -0
  34. data/lib/tengine/job/fork.rb +6 -0
  35. data/lib/tengine/job/job.rb +23 -0
  36. data/lib/tengine/job/jobnet.rb +173 -0
  37. data/lib/tengine/job/jobnet/builder.rb +150 -0
  38. data/lib/tengine/job/jobnet/job_state_transition.rb +167 -0
  39. data/lib/tengine/job/jobnet/jobnet_state_transition.rb +110 -0
  40. data/lib/tengine/job/jobnet/state_transition.rb +37 -0
  41. data/lib/tengine/job/jobnet_actual.rb +55 -0
  42. data/lib/tengine/job/jobnet_template.rb +10 -0
  43. data/lib/tengine/job/join.rb +6 -0
  44. data/lib/tengine/job/junction.rb +29 -0
  45. data/lib/tengine/job/killing.rb +30 -0
  46. data/lib/tengine/job/mm_compatibility.rb +6 -0
  47. data/lib/tengine/job/mm_compatibility/connectable.rb +13 -0
  48. data/lib/tengine/job/name_path.rb +31 -0
  49. data/lib/tengine/job/root.rb +16 -0
  50. data/lib/tengine/job/root_jobnet_actual.rb +39 -0
  51. data/lib/tengine/job/root_jobnet_template.rb +49 -0
  52. data/lib/tengine/job/script_executable.rb +235 -0
  53. data/lib/tengine/job/signal.rb +121 -0
  54. data/lib/tengine/job/start.rb +20 -0
  55. data/lib/tengine/job/stoppable.rb +15 -0
  56. data/lib/tengine/job/vertex.rb +172 -0
  57. data/lib/tengine_job.rb +3 -0
  58. data/spec/fixtures/rjn_0001_simple_jobnet_builder.rb +42 -0
  59. data/spec/fixtures/rjn_0002_simple_parallel_jobnet_builder.rb +42 -0
  60. data/spec/fixtures/rjn_0003_fork_join_jobnet_builder.rb +61 -0
  61. data/spec/fixtures/rjn_0004_parallel_jobnet_with_finally_fixture.rb +62 -0
  62. data/spec/fixtures/rjn_0005_retry_two_layer_fixture.rb +153 -0
  63. data/spec/fixtures/rjn_0008_expansion_fixture.rb +32 -0
  64. data/spec/fixtures/rjn_0009_tree_sequential_jobnet_builder.rb +174 -0
  65. data/spec/fixtures/rjn_0010_2jobs_and_1job_parallel_jobnet_builder.rb +39 -0
  66. data/spec/fixtures/rjn_0011_nested_fork_jobnet_builder.rb +96 -0
  67. data/spec/fixtures/rjn_0012_nested_and_finally_builder.rb +157 -0
  68. data/spec/fixtures/rjn_1004_hadoop_job_in_jobnet_fixture.rb +105 -0
  69. data/spec/fixtures/rjn_means_root_jobnet +0 -0
  70. data/spec/fixtures/test_credential_fixture.rb +12 -0
  71. data/spec/fixtures/test_server_fixture.rb +28 -0
  72. data/spec/mongoid.yml +35 -0
  73. data/spec/spec_helper.rb +56 -0
  74. data/spec/sshd/.gitignore +1 -0
  75. data/spec/sshd/id_rsa +51 -0
  76. data/spec/sshd/id_rsa.pub +1 -0
  77. data/spec/sshd/ssh_host_rsa_key +51 -0
  78. data/spec/sshd/ssh_host_rsa_key.pub +1 -0
  79. data/spec/sshd/sshd_config +10 -0
  80. data/spec/sshd/sshd_config.erb +11 -0
  81. data/spec/sshd/tengine_job_test.sh +6 -0
  82. data/spec/support/jobnet_fixture_builder.rb +145 -0
  83. data/spec/support/mongo_index_key_log.rb +91 -0
  84. data/spec/tengine/job/category_spec.rb +193 -0
  85. data/spec/tengine/job/connectable_spec.rb +94 -0
  86. data/spec/tengine/job/drivers/job_controll_driver/connection_error_spec.rb +236 -0
  87. data/spec/tengine/job/drivers/job_controll_driver/duplicated_job_start_spec.rb +302 -0
  88. data/spec/tengine/job/drivers/job_controll_driver/expansion_spec.rb +120 -0
  89. data/spec/tengine/job/drivers/job_controll_driver/stop_spec.rb +159 -0
  90. data/spec/tengine/job/drivers/job_controll_driver_spec.rb +623 -0
  91. data/spec/tengine/job/drivers/job_execution_driver_spec.rb +88 -0
  92. data/spec/tengine/job/drivers/jobnet_control_driver/nested_and_finally_spec.rb +472 -0
  93. data/spec/tengine/job/drivers/jobnet_control_driver/nested_jobnet_spec.rb +231 -0
  94. data/spec/tengine/job/drivers/jobnet_control_driver/stop_jobnet_spec.rb +202 -0
  95. data/spec/tengine/job/drivers/jobnet_control_driver_spec.rb +446 -0
  96. data/spec/tengine/job/drivers/schedule_driver_spec.rb +202 -0
  97. data/spec/tengine/job/dsl_binder_spec.rb +36 -0
  98. data/spec/tengine/job/dsl_loader_spec.rb +403 -0
  99. data/spec/tengine/job/dsls/0013_hadoop_job_run.rb +29 -0
  100. data/spec/tengine/job/dsls/0014_join_and_join.rb +19 -0
  101. data/spec/tengine/job/dsls/0015_fork_and_fork.rb +18 -0
  102. data/spec/tengine/job/dsls/0016_complex_fork_and_join.rb +20 -0
  103. data/spec/tengine/job/dsls/0017_finally.rb +15 -0
  104. data/spec/tengine/job/dsls/0018_expansion.rb +23 -0
  105. data/spec/tengine/job/dsls/0019_execute_job_on_event.rb +16 -0
  106. data/spec/tengine/job/dsls/0020_duplicated_jobnet_name.rb +16 -0
  107. data/spec/tengine/job/dsls/1060_test_dir1/1060_test_dir2/0013_hadoop_job_run.rb +29 -0
  108. data/spec/tengine/job/dsls/2003_expansion/expansion_5.rb +11 -0
  109. data/spec/tengine/job/dsls/VERSION +1 -0
  110. data/spec/tengine/job/dynamic_env_spec.rb +95 -0
  111. data/spec/tengine/job/edge_spec.rb +241 -0
  112. data/spec/tengine/job/element_selector_notation_spec.rb +354 -0
  113. data/spec/tengine/job/examples_spec.rb +62 -0
  114. data/spec/tengine/job/execution_spec.rb +100 -0
  115. data/spec/tengine/job/expansion_spec.rb +116 -0
  116. data/spec/tengine/job/hadoop_job_run_spec.rb +65 -0
  117. data/spec/tengine/job/job_spec.rb +4 -0
  118. data/spec/tengine/job/jobnet/1015_complecated_jobnet_spec.rb +72 -0
  119. data/spec/tengine/job/jobnet_actual_spec.rb +175 -0
  120. data/spec/tengine/job/jobnet_spec.rb +399 -0
  121. data/spec/tengine/job/jobnet_template_spec.rb +240 -0
  122. data/spec/tengine/job/killing_spec.rb +91 -0
  123. data/spec/tengine/job/reset_spec.rb +958 -0
  124. data/spec/tengine/job/reset_spec/4056_1_dump.txt +1 -0
  125. data/spec/tengine/job/root_jobnet_actual_spec.rb +89 -0
  126. data/spec/tengine/job/root_jobnet_template_spec.rb +248 -0
  127. data/spec/tengine/job/script_executable_spec.rb +132 -0
  128. data/spec/tengine/job/stoppable_spec.rb +176 -0
  129. data/spec/tengine/job/vertex_spec.rb +25 -0
  130. data/spec/tengine_job_spec.rb +4 -0
  131. data/tengine_job.gemspec +197 -0
  132. data/tmp/log/.gitignore +1 -0
  133. metadata +296 -0
@@ -0,0 +1,240 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Tengine::Job::JobnetTemplate do
5
+
6
+ describe "build_sequencial_edges" do
7
+ context "普通の場合" do
8
+ # |--- job111
9
+ # |--- jobnet11<>---|
10
+ # | |--- job112
11
+ # |
12
+ # jobnet1<>---|
13
+ # | |--- job121
14
+ # |--- jobnet12<>---|
15
+ # |--- job122
16
+ #
17
+ # 以下のように実行されるように
18
+ # jobnet1
19
+ # jobnet1/jobnet11
20
+ # jobnet1/jobnet11/job111
21
+ # jobnet1/jobnet11/job112
22
+ # jobnet1/jobnet12
23
+ # jobnet1/jobnet12/job121
24
+ # jobnet1/jobnet12/job122
25
+ it "レシーバ以下のジョブネットに対してシーケンシャルにedgesを構築する" do
26
+ jobnet1 = Tengine::Job::JobnetTemplate.new(:name => "jobnet1").with_start
27
+ jobnet1 .children << jobnet11 = Tengine::Job::JobnetTemplate.new(:name => "jobnet11").with_start
28
+ jobnet11.children << job111 = Tengine::Job::JobnetTemplate.new(:name => "job111", :script => "job111.sh")
29
+ jobnet11.children << job112 = Tengine::Job::JobnetTemplate.new(:name => "job112", :script => "job112.sh")
30
+ jobnet1 .children << jobnet12 = Tengine::Job::JobnetTemplate.new(:name => "jobnet12").with_start
31
+ jobnet12.children << job121 = Tengine::Job::JobnetTemplate.new(:name => "job121", :script => "job121.sh")
32
+ jobnet12.children << job122 = Tengine::Job::JobnetTemplate.new(:name => "job122", :script => "job122.sh")
33
+
34
+ jobnet1.prepare_end
35
+ jobnet11.prepare_end
36
+ jobnet12.prepare_end
37
+
38
+ jobnet1.build_sequencial_edges
39
+ jobnet11.build_sequencial_edges
40
+ jobnet12.build_sequencial_edges
41
+
42
+ jobnet1.save!
43
+
44
+ jobnet1.children.map(&:class).should == [
45
+ Tengine::Job::Start,
46
+ Tengine::Job::JobnetTemplate,
47
+ Tengine::Job::JobnetTemplate,
48
+ Tengine::Job::End
49
+ ]
50
+ jobnet1.edges.map{|edge| [edge.origin_id, edge.destination_id]}.should == [
51
+ [jobnet1.children.first.id, jobnet11.id],
52
+ [jobnet11.id, jobnet12.id],
53
+ [jobnet12.id, jobnet1.children.last.id],
54
+ ]
55
+ jobnet11.children.map(&:class).should == [
56
+ Tengine::Job::Start,
57
+ Tengine::Job::JobnetTemplate,
58
+ Tengine::Job::JobnetTemplate,
59
+ Tengine::Job::End
60
+ ]
61
+ jobnet11.edges.map{|edge| [edge.origin_id, edge.destination_id]}.should == [
62
+ [jobnet11.children.first.id, job111.id],
63
+ [job111.id, job112.id],
64
+ [job112.id, jobnet11.children.last.id],
65
+ ]
66
+ jobnet12.children.map(&:class).should == [
67
+ Tengine::Job::Start,
68
+ Tengine::Job::JobnetTemplate,
69
+ Tengine::Job::JobnetTemplate,
70
+ Tengine::Job::End
71
+ ]
72
+ jobnet12.edges.map{|edge| [edge.origin_id, edge.destination_id]}.should == [
73
+ [jobnet12.children.first.id, job121.id],
74
+ [job121.id, job122.id],
75
+ [job122.id, jobnet12.children.last.id],
76
+ ]
77
+ end
78
+ end
79
+
80
+ context "finally入りの場合" do
81
+ # |--- job111
82
+ # |--- jobnet11<>---|
83
+ # | |--- job112
84
+ # |
85
+ # jobnet1<>---|
86
+ # | |--- job121
87
+ # |--- finally<>---|
88
+ # |--- job122
89
+ #
90
+ # 以下のように実行されるように
91
+ # jobnet1
92
+ # jobnet1/jobnet11
93
+ # jobnet1/jobnet11/job111
94
+ # jobnet1/jobnet11/job112
95
+ # jobnet1/finally
96
+ # jobnet1/finally/job121
97
+ # jobnet1/finally/job122
98
+ it "レシーバ以下のジョブネットに対してシーケンシャルにedgesを構築する" do
99
+ jobnet1 = Tengine::Job::JobnetTemplate.new(:name => "jobnet1").with_start
100
+ jobnet1 .children << jobnet11 = Tengine::Job::JobnetTemplate.new(:name => "jobnet11").with_start
101
+ jobnet11.children << job111 = Tengine::Job::JobnetTemplate.new(:name => "job111", :script => "job111.sh")
102
+ jobnet11.children << job112 = Tengine::Job::JobnetTemplate.new(:name => "job112", :script => "job112.sh")
103
+ jobnet1 .children << finally = Tengine::Job::JobnetTemplate.new(:name => "finally", :jobnet_type_key => :finally).with_start
104
+ finally.children << job121 = Tengine::Job::JobnetTemplate.new(:name => "job121", :script => "job121.sh")
105
+ finally.children << job122 = Tengine::Job::JobnetTemplate.new(:name => "job122", :script => "job122.sh")
106
+
107
+ jobnet1.prepare_end
108
+ jobnet11.prepare_end
109
+ finally.prepare_end
110
+
111
+ jobnet1.build_sequencial_edges
112
+ jobnet11.build_sequencial_edges
113
+ finally.build_sequencial_edges
114
+
115
+ jobnet1.save!
116
+
117
+ jobnet1.children.map(&:class).should == [
118
+ Tengine::Job::Start,
119
+ Tengine::Job::JobnetTemplate,
120
+ Tengine::Job::JobnetTemplate, # :finallyはEndの前にあります。
121
+ Tengine::Job::End
122
+ ]
123
+ jobnet1.finally_jobnet.should == finally
124
+
125
+ jobnet1.edges.map{|edge| [edge.origin_id, edge.destination_id]}.should == [
126
+ [jobnet1.children.first.id, jobnet11.id],
127
+ [jobnet11.id, jobnet1.children.last.id],
128
+ ]
129
+ jobnet11.children.map(&:class).should == [
130
+ Tengine::Job::Start,
131
+ Tengine::Job::JobnetTemplate,
132
+ Tengine::Job::JobnetTemplate,
133
+ Tengine::Job::End
134
+ ]
135
+ jobnet11.edges.map{|edge| [edge.origin_id, edge.destination_id]}.should == [
136
+ [jobnet11.children.first.id, job111.id],
137
+ [job111.id, job112.id],
138
+ [job112.id, jobnet11.children.last.id],
139
+ ]
140
+ finally.children.map(&:class).should == [
141
+ Tengine::Job::Start,
142
+ Tengine::Job::JobnetTemplate,
143
+ Tengine::Job::JobnetTemplate,
144
+ Tengine::Job::End
145
+ ]
146
+ finally.edges.map{|edge| [edge.origin_id, edge.destination_id]}.should == [
147
+ [finally.children.first.id, job121.id],
148
+ [job121.id, job122.id],
149
+ [job122.id, finally.children.last.id],
150
+ ]
151
+ end
152
+ end
153
+ end
154
+
155
+ context "並列処理" do
156
+
157
+ describe :join do
158
+ # job1 ---|
159
+ # |--- job4 ---|
160
+ # job2 ---| |
161
+ # |--- job5
162
+ # job3 ----------------|
163
+ #
164
+ # とMMでは書いていたものはこんな感じになります。
165
+ #
166
+ # |--- job1 ---|
167
+ # | J--- job4 ---|
168
+ # start ---F--- job2 ---| |
169
+ # | J--- job5 --- end
170
+ # |--- job3 ----------------|
171
+ it do
172
+ jobnet1 = Tengine::Job::JobnetTemplate.new(:name => "jobnet1")
173
+ jobnet1.children << _start = Tengine::Job::Start.new
174
+ jobnet1.children << fork1 = Tengine::Job::Fork.new
175
+ jobnet1.children << job1 = Tengine::Job::JobnetTemplate.new(:name => "job1", :script => "job1.sh")
176
+ jobnet1.children << job2 = Tengine::Job::JobnetTemplate.new(:name => "job2", :script => "job2.sh")
177
+ jobnet1.children << join1 = Tengine::Job::Join.new
178
+ jobnet1.children << job3 = Tengine::Job::JobnetTemplate.new(:name => "job3", :script => "job3.sh")
179
+ jobnet1.children << job4 = Tengine::Job::JobnetTemplate.new(:name => "job4", :script => "job4.sh")
180
+ jobnet1.children << join2 = Tengine::Job::Join.new
181
+ jobnet1.children << job5 = Tengine::Job::JobnetTemplate.new(:name => "job5", :script => "job5.sh")
182
+ jobnet1.children << _end = Tengine::Job::End.new
183
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => _start.id, :destination_id => fork1.id)
184
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => fork1.id, :destination_id => job1.id)
185
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => fork1.id, :destination_id => job2.id)
186
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => fork1.id, :destination_id => job3.id)
187
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job1.id, :destination_id => join1.id)
188
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job2.id, :destination_id => join1.id)
189
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => join1.id, :destination_id => job4.id)
190
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job3.id, :destination_id => join2.id)
191
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job4.id, :destination_id => join2.id)
192
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => join2.id, :destination_id => job5.id)
193
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job5.id, :destination_id => _end.id)
194
+ jobnet1.save!
195
+ end
196
+ end
197
+
198
+ describe :fork do
199
+ # |--- job2
200
+ # job1 ---| |--- job4
201
+ # |--- job3 ---- |
202
+ # |--- job5
203
+ #
204
+ # とMMでは書いていたものはこんな感じになります。
205
+ #
206
+ # |--- job2--------------------|
207
+ # | |
208
+ # start --- job1 ---F |--- job4 --- J---end
209
+ # |--- job3 ---- F |
210
+ # |--- job5 ----|
211
+ it do
212
+ jobnet1 = Tengine::Job::JobnetTemplate.new(:name => "jobnet1")
213
+ jobnet1.children << _start = Tengine::Job::Start.new
214
+ jobnet1.children << job1 = Tengine::Job::JobnetTemplate.new(:name => "job1", :script => "job1.sh")
215
+ jobnet1.children << fork1 = Tengine::Job::Fork.new
216
+ jobnet1.children << job2 = Tengine::Job::JobnetTemplate.new(:name => "job2", :script => "job2.sh")
217
+ jobnet1.children << job3 = Tengine::Job::JobnetTemplate.new(:name => "job3", :script => "job3.sh")
218
+ jobnet1.children << fork2 = Tengine::Job::Fork.new
219
+ jobnet1.children << job4 = Tengine::Job::JobnetTemplate.new(:name => "job4", :script => "job4.sh")
220
+ jobnet1.children << job5 = Tengine::Job::JobnetTemplate.new(:name => "job5", :script => "job5.sh")
221
+ jobnet1.children << join1 = Tengine::Job::Join.new
222
+ jobnet1.children << _end = Tengine::Job::End.new
223
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => _start.id, :destination_id => job1.id)
224
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job1.id, :destination_id => fork1.id)
225
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => fork1.id, :destination_id => job2.id)
226
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => fork1.id, :destination_id => job3.id)
227
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job3.id, :destination_id => fork2.id)
228
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => fork2.id, :destination_id => job4.id)
229
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => fork2.id, :destination_id => job5.id)
230
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job2.id, :destination_id => join1.id)
231
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job4.id, :destination_id => join1.id)
232
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => job5.id, :destination_id => join1.id)
233
+ jobnet1.edges << Tengine::Job::Edge.new(:origin_id => join1.id, :destination_id => _end.id)
234
+ jobnet1.save!
235
+ end
236
+ end
237
+
238
+ end
239
+
240
+ end
@@ -0,0 +1,91 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Tengine::Job::Killing do
5
+
6
+ context "強制停止の設定" do
7
+ before do
8
+ builder = Rjn0011NestedForkJobnetBuilder.new
9
+ @ctx = builder.context
10
+ @root = builder.create_template
11
+ end
12
+
13
+ [:root, :j1100, :j1200, :j1300, :j1110, :j1120, :j1130, :j1140, :j1121, :j1131, :j1310].each do |name|
14
+ context "#{name}のデフォルト" do
15
+ subject { @ctx[name] }
16
+ its(:killing_signals){ should == nil}
17
+ its(:killing_signal_interval){ should == nil}
18
+ its(:actual_killing_signals){ should == ['KILL']}
19
+ its(:actual_killing_signal_interval){ should == Tengine::Job::Killing::DEFAULT_KILLING_SIGNAL_INTERVAL}
20
+ end
21
+ end
22
+
23
+ context "j1100に明示的に設定されている場合" do
24
+ before do
25
+ @ctx[:j1100].tap do |j|
26
+ j.killing_signals = ["INT", "HUP", "QUIT", "KILL"]
27
+ j.killing_signal_interval = 30
28
+ end
29
+ @ctx[:j1130].tap do |j|
30
+ j.killing_signals = ["HUP", "QUIT", "KILL"]
31
+ j.killing_signal_interval = 60
32
+ end
33
+ end
34
+
35
+ [:root, :j1200, :j1300, :j1310].each do |name|
36
+ context "#{name} デフォルトのまま" do
37
+ subject { @ctx[name] }
38
+ its(:killing_signals){ should == nil}
39
+ its(:killing_signal_interval){ should == nil}
40
+ its(:actual_killing_signals){ should == ['KILL']}
41
+ its(:actual_killing_signal_interval){ should == Tengine::Job::Killing::DEFAULT_KILLING_SIGNAL_INTERVAL}
42
+ end
43
+ end
44
+
45
+ [:j1100].each do |name|
46
+ context "#{name} は自身の値も変更されている" do
47
+ subject { @ctx[name] }
48
+ its(:killing_signals){ should == ['INT', 'HUP', 'QUIT', 'KILL']}
49
+ its(:killing_signal_interval){ should == 30}
50
+ its(:actual_killing_signals){ should == ['INT', 'HUP', 'QUIT', 'KILL']}
51
+ its(:actual_killing_signal_interval){ should == 30}
52
+ end
53
+ end
54
+
55
+ [:j1120, :j1140, :j1121].each do |name|
56
+ context "#{name} はj1100の設定が反映される" do
57
+ subject { @ctx[name] }
58
+ its(:killing_signals){ should == nil}
59
+ its(:killing_signal_interval){ should == nil}
60
+ its(:actual_killing_signals){ should == ['INT', 'HUP', 'QUIT', 'KILL']}
61
+ its(:actual_killing_signal_interval){ should == 30}
62
+ end
63
+ end
64
+
65
+ [:j1130].each do |name|
66
+ context "#{name} は自身の値も変更されている" do
67
+ subject { @ctx[name] }
68
+ its(:killing_signals){ should == ['HUP', 'QUIT', 'KILL']}
69
+ its(:killing_signal_interval){ should == 60}
70
+ its(:actual_killing_signals){ should == ['HUP', 'QUIT', 'KILL']}
71
+ its(:actual_killing_signal_interval){ should == 60}
72
+ end
73
+ end
74
+
75
+ [:j1131].each do |name|
76
+ context "#{name} はj1130の設定が反映される" do
77
+ subject { @ctx[name] }
78
+ its(:killing_signals){ should == nil}
79
+ its(:killing_signal_interval){ should == nil}
80
+ its(:actual_killing_signals){ should == ['HUP', 'QUIT', 'KILL']}
81
+ its(:actual_killing_signal_interval){ should == 60}
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+
89
+
90
+
91
+ end
@@ -0,0 +1,958 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe "reset" do
5
+ context "@4056" do
6
+ before do
7
+ @record = eval(File.read(File.expand_path("reset_spec/4056_1_dump.txt", File.dirname(__FILE__))))
8
+ Tengine::Job::Vertex.delete_all
9
+ Tengine::Job::Vertex.collection.insert(@record)
10
+ @root = Tengine::Job::Vertex.find(@record["_id"])
11
+ end
12
+
13
+ it "状況確認" do
14
+ @root.phase_key.should == :error
15
+ @root.element('/jn0006/jn1' ).phase_key.should == :error
16
+ @root.element('/jn0006/jn1/jn11' ).phase_key.should == :error
17
+ @root.element('/jn0006/jn1/jn11/finally' ).phase_key.should == :success
18
+ @root.element('/jn0006/jn1/jn11/finally/jn11_f').phase_key.should == :success
19
+ @root.element('/jn0006/jn1/j12' ).phase_key.should == :initialized
20
+ @root.element('/jn0006/jn1/finally' ).phase_key.should == :success
21
+ @root.element('/jn0006/jn1/finally/jn1_f' ).phase_key.should == :success
22
+ @root.element('/jn0006/jn2' ).phase_key.should == :initialized
23
+ @root.element('/jn0006/jn2/j21' ).phase_key.should == :initialized
24
+ @root.element('/jn0006/jn2/jn22' ).phase_key.should == :initialized
25
+ @root.element('/jn0006/jn2/jn22/j221' ).phase_key.should == :initialized
26
+ @root.element('/jn0006/jn2/jn22/j222' ).phase_key.should == :initialized
27
+ @root.element('/jn0006/jn2/jn22/finally' ).phase_key.should == :initialized
28
+ @root.element('/jn0006/jn2/jn22/finally/jn22_f').phase_key.should == :initialized
29
+ @root.element('/jn0006/jn2/finally' ).phase_key.should == :initialized
30
+ @root.element('/jn0006/jn2/finally/jn2_f' ).phase_key.should == :initialized
31
+ @root.element('/jn0006/finally' ).phase_key.should == :success
32
+
33
+ @root.edges.map(&:phase_key).should == [:transmitted, :closed, :closed]
34
+ @root.element('/jn0006/jn1' ).edges.map(&:phase_key).should == [:transmitted, :closed, :closed]
35
+ @root.element('/jn0006/jn1/jn11' ).edges.map(&:phase_key).should == [:transmitted, :closed, :closed]
36
+ @root.element('/jn0006/jn1/jn11/finally').edges.map(&:phase_key).should == [:transmitted, :transmitted]
37
+ @root.element('/jn0006/jn1/finally' ).edges.map(&:phase_key).should == [:transmitted, :transmitted]
38
+ @root.element('/jn0006/jn2' ).edges.map(&:phase_key).should == [:active, :active, :active]
39
+ @root.element('/jn0006/jn2/jn22' ).edges.map(&:phase_key).should == [:active, :active, :active]
40
+ @root.element('/jn0006/jn2/jn22/finally').edges.map(&:phase_key).should == [:active, :active]
41
+ @root.element('/jn0006/jn2/finally' ).edges.map(&:phase_key).should == [:active, :active]
42
+ @root.element('/jn0006/finally' ).edges.map(&:phase_key).should == [:transmitted, :transmitted]
43
+ end
44
+
45
+ it "jn11をspotで再実行" do
46
+ @now = Time.now.utc
47
+ @event = mock(:event, :occurred_at => @now)
48
+ @signal = Tengine::Job::Signal.new(@event)
49
+ @jn11 = @root.element("jn11@jn1")
50
+ @execution = Tengine::Job::Execution.create!({
51
+ :target_actual_ids => [@jn11.id.to_s],
52
+ :retry => true, :spot => true,
53
+ :root_jobnet_id => @root.id
54
+ })
55
+ @execution.phase_key.should == :initialized
56
+ @event.stub(:[]).with(:execution_id).and_return(@execution.id.to_s)
57
+ @execution.stub(:target_actuals).and_return([@jn11])
58
+
59
+ @root.update_with_lock do
60
+ @execution.transmit(@signal)
61
+ end
62
+
63
+ fire_args = @signal.reservations.first.fire_args
64
+ fire_args.first.should == :"start.jobnet.job.tengine"
65
+ hash = fire_args.last
66
+ hash.delete(:source_name).should_not be_nil
67
+ hash.should == {
68
+ :properties => {
69
+ :target_jobnet_id=>@jn11.id.to_s,
70
+ :target_jobnet_name_path=>"/jn0006/jn1/jn11",
71
+ :execution_id=>@execution.id.to_s,
72
+ :root_jobnet_id=>@root.id.to_s,
73
+ :root_jobnet_name_path=>"/jn0006"
74
+ }
75
+ }
76
+
77
+ @root.reload
78
+ @root.element('/jn0006/jn1' ).phase_key.should == :error
79
+ @root.element('/jn0006/jn1/jn11' ).phase_key.should == :ready
80
+ @root.element('/jn0006/jn1/jn11/finally' ).phase_key.should == :initialized
81
+ @root.element('/jn0006/jn1/jn11/finally/jn11_f').phase_key.should == :initialized
82
+ @root.element('/jn0006/jn1/j12' ).phase_key.should == :initialized
83
+ @root.element('/jn0006/jn1/finally' ).phase_key.should == :success
84
+ @root.element('/jn0006/jn1/finally/jn1_f' ).phase_key.should == :success
85
+ @root.element('/jn0006/jn2' ).phase_key.should == :initialized
86
+ @root.element('/jn0006/jn2/j21' ).phase_key.should == :initialized
87
+ @root.element('/jn0006/jn2/jn22' ).phase_key.should == :initialized
88
+ @root.element('/jn0006/jn2/jn22/j221' ).phase_key.should == :initialized
89
+ @root.element('/jn0006/jn2/jn22/j222' ).phase_key.should == :initialized
90
+ @root.element('/jn0006/jn2/jn22/finally' ).phase_key.should == :initialized
91
+ @root.element('/jn0006/jn2/jn22/finally/jn22_f').phase_key.should == :initialized
92
+ @root.element('/jn0006/jn2/finally' ).phase_key.should == :initialized
93
+ @root.element('/jn0006/jn2/finally/jn2_f' ).phase_key.should == :initialized
94
+ @root.element('/jn0006/finally' ).phase_key.should == :success
95
+
96
+ @root.edges.map(&:phase_key).should == [:transmitted, :closed, :closed]
97
+ @root.element('/jn0006/jn1' ).edges.map(&:phase_key).should == [:transmitted, :closed, :closed]
98
+ @root.element('/jn0006/jn1/jn11' ).edges.map(&:phase_key).should == [:active, :active, :active]
99
+ @root.element('/jn0006/jn1/jn11/finally').edges.map(&:phase_key).should == [:active, :active]
100
+ @root.element('/jn0006/jn1/finally' ).edges.map(&:phase_key).should == [:transmitted, :transmitted]
101
+ @root.element('/jn0006/jn2' ).edges.map(&:phase_key).should == [:active, :active, :active]
102
+ @root.element('/jn0006/jn2/jn22' ).edges.map(&:phase_key).should == [:active, :active, :active]
103
+ @root.element('/jn0006/jn2/jn22/finally').edges.map(&:phase_key).should == [:active, :active]
104
+ @root.element('/jn0006/jn2/finally' ).edges.map(&:phase_key).should == [:active, :active]
105
+ @root.element('/jn0006/finally' ).edges.map(&:phase_key).should == [:transmitted, :transmitted]
106
+ end
107
+
108
+ it "jn11以降を再実行" do
109
+ @now = Time.now.utc
110
+ @event = mock(:event, :occurred_at => @now)
111
+ @signal = Tengine::Job::Signal.new(@event)
112
+ @jn11 = @root.element("jn11@jn1")
113
+ @execution = Tengine::Job::Execution.create!({
114
+ :target_actual_ids => [@jn11.id.to_s],
115
+ :retry => true, :spot => false,
116
+ :root_jobnet_id => @root.id
117
+ })
118
+ @execution.phase_key.should == :initialized
119
+ @event.stub(:[]).with(:execution_id).and_return(@execution.id.to_s)
120
+ @execution.stub(:target_actuals).and_return([@jn11])
121
+
122
+ @root.update_with_lock do
123
+ @execution.transmit(@signal)
124
+ end
125
+
126
+ fire_args = @signal.reservations.first.fire_args
127
+ fire_args.first.should == :"start.jobnet.job.tengine"
128
+ hash = fire_args.last
129
+ hash.delete(:source_name).should_not be_nil
130
+ hash.should == {
131
+ :properties => {
132
+ :target_jobnet_id=>@jn11.id.to_s,
133
+ :target_jobnet_name_path=>"/jn0006/jn1/jn11",
134
+ :execution_id=>@execution.id.to_s,
135
+ :root_jobnet_id=>@root.id.to_s,
136
+ :root_jobnet_name_path=>"/jn0006"
137
+ }
138
+ }
139
+
140
+ @root.reload
141
+ @root.element('/jn0006/jn1' ).phase_key.should == :error
142
+ @root.element('/jn0006/jn1/jn11' ).phase_key.should == :ready
143
+ @root.element('/jn0006/jn1/jn11/finally' ).phase_key.should == :initialized
144
+ @root.element('/jn0006/jn1/jn11/finally/jn11_f').phase_key.should == :initialized
145
+ @root.element('/jn0006/jn1/j12' ).phase_key.should == :initialized
146
+ @root.element('/jn0006/jn1/finally' ).phase_key.should == :initialized
147
+ @root.element('/jn0006/jn1/finally/jn1_f' ).phase_key.should == :initialized
148
+ @root.element('/jn0006/jn2' ).phase_key.should == :initialized
149
+ @root.element('/jn0006/jn2/j21' ).phase_key.should == :initialized
150
+ @root.element('/jn0006/jn2/jn22' ).phase_key.should == :initialized
151
+ @root.element('/jn0006/jn2/jn22/j221' ).phase_key.should == :initialized
152
+ @root.element('/jn0006/jn2/jn22/j222' ).phase_key.should == :initialized
153
+ @root.element('/jn0006/jn2/jn22/finally' ).phase_key.should == :initialized
154
+ @root.element('/jn0006/jn2/jn22/finally/jn22_f').phase_key.should == :initialized
155
+ @root.element('/jn0006/jn2/finally' ).phase_key.should == :initialized
156
+ @root.element('/jn0006/jn2/finally/jn2_f' ).phase_key.should == :initialized
157
+ @root.element('/jn0006/finally' ).phase_key.should == :success
158
+
159
+ @root.edges.map(&:phase_key).should == [:transmitted, :closed, :closed]
160
+ @root.element('/jn0006/jn1' ).edges.map(&:phase_key).should == [:transmitted, :active, :active]
161
+ @root.element('/jn0006/jn1/jn11' ).edges.map(&:phase_key).should == [:active, :active, :active]
162
+ @root.element('/jn0006/jn1/jn11/finally').edges.map(&:phase_key).should == [:active, :active]
163
+ @root.element('/jn0006/jn1/finally' ).edges.map(&:phase_key).should == [:active, :active]
164
+ @root.element('/jn0006/jn2' ).edges.map(&:phase_key).should == [:active, :active, :active]
165
+ @root.element('/jn0006/jn2/jn22' ).edges.map(&:phase_key).should == [:active, :active, :active]
166
+ @root.element('/jn0006/jn2/jn22/finally').edges.map(&:phase_key).should == [:active, :active]
167
+ @root.element('/jn0006/jn2/finally' ).edges.map(&:phase_key).should == [:active, :active]
168
+ @root.element('/jn0006/finally' ).edges.map(&:phase_key).should == [:transmitted, :transmitted]
169
+ end
170
+ end
171
+
172
+ # in [jn0005]
173
+ # |--e3-->(j2)--e5--->|
174
+ # (S1)--e1-->(j1)--e2-->[F1] [J1]-->e7-->(j4)--e8-->(E1)
175
+ # |--e4-->[jn4]--e6-->|
176
+ #
177
+ # in [jn0005/jn4]
178
+ # |--e11-->(j42)--e13-->|
179
+ # (S2)--e9-->(j41)--e10-->[F2] [J2]--e15-->(j44)--e16-->(E2)
180
+ # |--e12-->(j43)--e14-->|
181
+ #
182
+ # in [jn0005/jn4/finally]
183
+ # (S3)--e17-->(jn4_f)--e18-->(E3)
184
+ #
185
+ # in [jn0005/finally]
186
+ # (S4)--e19-->[jn0005_fjn]--e20-->(jn0005_f)--e21-->(E4)
187
+ #
188
+ # in [jn0005/finally/jn0005_fjn]
189
+ # (S5)--e22-->(jn0005_f1)--e23-->(jn0005_f1)--e24-->(E5)
190
+ #
191
+ # in [jn0005/finally/jn0005_fjn/finally]
192
+ # (S6)--e25-->(jn0005_fif)--e26-->(E6)
193
+ {
194
+ "@4026" => true,
195
+ "@4034" => false,
196
+ }.each do |scenario_no, spot|
197
+ context "#{scenario_no} スポット実行#{spot}" do
198
+ before do
199
+ Tengine::Job::Vertex.delete_all
200
+ builder = Rjn0005RetryTwoLayerFixture.new
201
+ @root = builder.create_actual
202
+ @ctx = builder.context
203
+ end
204
+
205
+ context "/jn0005/j1が:errorになって実行が終了した後" do
206
+ before do
207
+ @ctx[:jn0005].phase_key = :error
208
+ @ctx[:j1].phase_key = :error
209
+ @ctx[:jn0005].finally_vertex do |f|
210
+ f.phase_key = :success
211
+ f.descendants.each{|d| d.phase_key = :success}
212
+ end
213
+ @ctx[:e1].phase_key = :transmitted
214
+ (2..8).each{|idx| @ctx[:"e#{idx}"].phase_key = :closed}
215
+ (19..26).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
216
+ @root.save!
217
+ end
218
+
219
+ it "/jn0005/jn4/j41を再実行できる" do
220
+ execution = Tengine::Job::Execution.create!({
221
+ :retry => true, :spot => spot,
222
+ :root_jobnet_id => @root.id,
223
+ :target_actual_ids => [@ctx[:j41].id.to_s]
224
+ })
225
+ execution.stub(:root_jobnet).and_return(@root)
226
+ t1 = Time.now
227
+ event1 = mock(:event1)
228
+ event1.stub(:occurred_at).and_return(t1)
229
+ signal1 = Tengine::Job::Signal.new(event1)
230
+ signal1.stub(:execution).and_return(execution)
231
+ @root.update_with_lock do
232
+ execution.transmit(signal1)
233
+ end
234
+ signal1.reservations.length.should == 1
235
+ signal1.reservations.first.tap do |reservation|
236
+ reservation.event_type_name.should == :"start.job.job.tengine"
237
+ end
238
+ #
239
+ t2 = Time.now
240
+ event2 = mock(:event2)
241
+ event2.stub(:occurred_at).and_return(t2)
242
+ signal2 = Tengine::Job::Signal.new(event2)
243
+ signal2.stub(:execution).and_return(execution)
244
+ @root.reload
245
+ j41 = @root.element("/jn0005/jn4/j41")
246
+ j41.phase_key.should == :ready
247
+ @root.update_with_lock do
248
+ j41.activate(signal2)
249
+ end
250
+ signal2.reservations.map(&:fire_args).should == []
251
+ signal2.reservations.length.should == 0
252
+ end
253
+
254
+ end
255
+ end
256
+ end
257
+
258
+ context "@4035" do
259
+
260
+ before do
261
+ Tengine::Job::Vertex.delete_all
262
+ builder = Rjn0005RetryTwoLayerFixture.new
263
+ @root = builder.create_actual
264
+ @ctx = builder.context
265
+ end
266
+
267
+ context "/jn0005/j1が:errorになって実行が終了した後、/jn0005/j2を再実行" do
268
+ before do
269
+ @ctx[:jn0005].phase_key = :error
270
+ @ctx[:j1].phase_key = :error
271
+ @ctx[:j2].phase_key = :success
272
+ [2,3,4,6].each{|idx| @ctx[:"e#{idx}"].phase_key = :closed}
273
+ [1].each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
274
+ [5,7,8].each{|idx| @ctx[:"e#{idx}"].phase_key = :active}
275
+ (9..26).each{|idx| @ctx[:"e#{idx}"].phase_key = :active}
276
+ @root.save!
277
+ end
278
+
279
+ it "成功しても/jn0005/j4は実行されない" do
280
+ execution = Tengine::Job::Execution.create!({
281
+ :retry => true, :spot => false,
282
+ :root_jobnet_id => @root.id,
283
+ :target_actual_ids => [@ctx[:j2].id.to_s]
284
+ })
285
+ execution.stub(:root_jobnet).and_return(@root)
286
+ t1 = Time.now
287
+ event1 = mock(:"success.job.job.tengine")
288
+ event1.stub(:occurred_at).and_return(t1)
289
+ signal1 = Tengine::Job::Signal.new(event1)
290
+ signal1.stub(:execution).and_return(execution)
291
+ next_of_j2 = @root.element("next!j2")
292
+ @root.update_with_lock do
293
+ next_of_j2.transmit(signal1)
294
+ end
295
+ signal1.reservations.map(&:fire_args).should == []
296
+ @root.reload
297
+ @root.element("j2").tap{|j| j.phase_key.should == :success }
298
+ @root.element("j4").tap{|j| j.phase_key.should == :initialized }
299
+ @root.element("next!j2").phase_key.should == :transmitted
300
+ @root.element("prev!j4").phase_key.should == :active
301
+ end
302
+ end
303
+
304
+ end
305
+
306
+ context "@4034 [bug]initializedのジョブネット内のジョブを起点として再実行すると、起点となるジョブの後続ジョブがactivateされた際に親のジョブネットにackを返してしまいTengine::Job::Executable::PhaseError" do
307
+ before do
308
+ Tengine::Job::Vertex.delete_all
309
+ builder = Rjn0005RetryTwoLayerFixture.new
310
+ @root = builder.create_actual
311
+ @ctx = builder.context
312
+ end
313
+
314
+ context "/jn0005/jn4/j41を起点として再実行" do
315
+ before do
316
+ @execution = Tengine::Job::Execution.create!({
317
+ :retry => true, :spot => false,
318
+ :root_jobnet_id => @root.id,
319
+ :target_actual_ids => [@ctx[:j41].id.to_s]
320
+ })
321
+ @execution.stub(:root_jobnet).and_return(@root)
322
+
323
+ [:root, :jn0005, :j1, :j41].each{|j| @ctx[j].phase_key = :error }
324
+ [:jn4, :j2, :j4,
325
+ :j42, :j43, :j44, :jn4f, :jn4_f].each{|j| @ctx[j].phase_key = :initialized }
326
+
327
+ [:finally, :jn0005_fjn, :jn0005_f, :jn0005_f1, :jn0005_f2,
328
+ :jn0005_fjn_f, :jn0005_fif].each{|j| @ctx[j].phase_key = :success}
329
+
330
+ @ctx[:e1].phase_key = :transmitted
331
+ (2..9).each{|idx| @ctx[:"e#{idx}"].phase_key = :closed}
332
+ (10..18).each{|idx| @ctx[:"e#{idx}"].phase_key = :active}
333
+ (19..26).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
334
+ @root.save!
335
+ end
336
+
337
+ it "j41の後続のジョブがactivateされる" do
338
+ t1 = Time.now
339
+ event1 = mock(:"success.job.job.tengine")
340
+ event1.stub(:occurred_at).and_return(t1)
341
+ signal1 = Tengine::Job::Signal.new(event1)
342
+ signal1.stub(:execution).and_return(@execution)
343
+ next_of_j41 = @root.element("next!/jn0005/jn4/j41")
344
+ @root.update_with_lock do
345
+ next_of_j41.transmit(signal1)
346
+ end
347
+ signal1.reservations.length.should == 2
348
+ signal1.reservations.map(&:event_type_name).should == [:"start.job.job.tengine", :"start.job.job.tengine"]
349
+
350
+ @root.reload
351
+ @root.element("/jn0005/jn4/j42").tap{|j| j.phase_key.should == :ready }
352
+ @root.element("/jn0005/jn4/j43").tap{|j| j.phase_key.should == :ready }
353
+ @root.element("next!/jn0005/jn4/j41").phase_key.should == :transmitted
354
+ @root.element("prev!/jn0005/jn4/j42").phase_key.should == :transmitting
355
+ @root.element("prev!/jn0005/jn4/j43").phase_key.should == :transmitting
356
+
357
+ t2 = Time.now
358
+ event2 = mock(:"start.job.job.tengine")
359
+ event2.stub(:occurred_at).and_return(t2)
360
+ signal2 = Tengine::Job::Signal.new(event2)
361
+ signal2.stub(:execution).and_return(@execution)
362
+ j42 = @root.element("/jn0005/jn4/j42")
363
+ @root.update_with_lock do
364
+ j42.activate(signal2)
365
+ end
366
+ @root.reload
367
+ @root.element("/jn0005/jn4/j42").tap{|j| j.phase_key.should == :starting }
368
+ @root.element("/jn0005/jn4" ).tap{|j| j.phase_key.should == :initialized }
369
+ end
370
+ end
371
+ end
372
+
373
+ context "ジョブネット内のジョブネットまたはジョブを起点にリセット" do
374
+ before do
375
+ Tengine::Job::Vertex.delete_all
376
+ builder = Rjn0005RetryTwoLayerFixture.new
377
+ @root = builder.create_actual
378
+ @ctx = builder.context
379
+ end
380
+
381
+ context "ルートジョブネットが正常終了した後に" do
382
+ before do
383
+ [:root, :jn0005, :j1, :jn4, :j2, :j4,
384
+ :j41, :j42, :j43, :j44, :jn4f, :jn4_f,
385
+ :finally, :jn0005_fjn, :jn0005_f, :jn0005_f1, :jn0005_f2,
386
+ :jn0005_fjn_f, :jn0005_fif].each{|j| @ctx[j].phase_key = :success}
387
+
388
+ (1..26).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
389
+ @root.save!
390
+ end
391
+
392
+ context "j41を起点に再実行すると" do
393
+ it "jn4内のVertexのみリセットされる" do
394
+ t1 = Time.now
395
+ event1 = mock(:event, :occurred_at => t1)
396
+ signal1 = Tengine::Job::Signal.new(event1)
397
+ j41 = @root.element('/jn0005/jn4/j41')
398
+ execution = Tengine::Job::Execution.create!({
399
+ :target_actual_ids => [j41.id.to_s],
400
+ :retry => true, :spot => false,
401
+ :root_jobnet_id => @root.id
402
+ })
403
+ execution.stub(:root_jobnet).and_return(@root)
404
+ event1.stub(:[]).with(:execution_id).and_return(execution.id.to_s)
405
+ @root.update_with_lock{ execution.transmit(signal1) }
406
+ @root.save!
407
+ execution.save!
408
+ execution.reload
409
+ @root.reload
410
+
411
+ (10..16).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
412
+ (17..18).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
413
+ (19..26).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
414
+ (1..9).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
415
+ @root.element('/jn0005' ).phase_key.should == :success
416
+ @root.element('/jn0005/j1' ).phase_key.should == :success
417
+ @root.element('/jn0005/j2' ).phase_key.should == :success
418
+ @root.element('/jn0005/jn4' ).phase_key.should == :success
419
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :ready
420
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :initialized
421
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :initialized
422
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :initialized
423
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :initialized
424
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :initialized
425
+ @root.element('/jn0005/j4' ).phase_key.should == :success
426
+ @root.element('/jn0005/finally' ).phase_key.should == :success
427
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :success
428
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :success
429
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :success
430
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :success
431
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :success
432
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :success
433
+ end
434
+
435
+ it "jn4内のジョブの処理が全部終わって、jn4をsucceedしてもignore" do
436
+ [:j41, :j42, :j43, :j44, :jn4f, :jn4_f].each{|j| @ctx[j].phase_key = :success}
437
+ (10..18).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
438
+ @root.save!
439
+
440
+ j41 = @root.element("j41@jn4")
441
+ execution = Tengine::Job::Execution.create!({
442
+ :target_actual_ids => [j41.id.to_s],
443
+ :retry => true, :spot => false,
444
+ :root_jobnet_id => @root.id
445
+ })
446
+
447
+ t2 = Time.now
448
+ # jn4fのジョブネット正常終了イベント
449
+ event2 = mock(:"success.jobnet.job.tengine")
450
+ event2.stub(:occurred_at).and_return(t2)
451
+ signal2 = Tengine::Job::Signal.new(event2)
452
+ signal2.stub(:execution).and_return(execution)
453
+ jn4 = @root.element('/jn0005/jn4')
454
+ jn4.phase_key.should == :success
455
+ jn4.finished_at.should be_nil
456
+ @root.update_with_lock{ jn4.succeed(signal2) }
457
+
458
+ @root.reload
459
+ @root.element('/jn0005/j1' ).phase_key.should == :success
460
+ @root.element('/jn0005/j2' ).phase_key.should == :success
461
+ @root.element('/jn0005/jn4' ).phase_key.should == :success
462
+ @root.element('/jn0005/jn4' ).finished_at.should be_nil
463
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :success
464
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :success
465
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :success
466
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :success
467
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :success
468
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :success
469
+ @root.element('/jn0005/j4' ).phase_key.should == :success
470
+ @root.element('/jn0005/finally' ).phase_key.should == :success
471
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :success
472
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :success
473
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :success
474
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :success
475
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :success
476
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :success
477
+ end
478
+ end
479
+
480
+ context "jn4を起点に再実行すると" do
481
+ it "jn0005内のjn4以降がリセットされる" do
482
+ t1 = Time.now
483
+ event1 = mock(:event, :occurred_at => t1)
484
+ signal1 = Tengine::Job::Signal.new(event1)
485
+ jn4 = @root.element('/jn0005/jn4')
486
+ execution = Tengine::Job::Execution.create!({
487
+ :target_actual_ids => [jn4.id.to_s],
488
+ :retry => true, :spot => false,
489
+ :root_jobnet_id => @root.id
490
+ })
491
+ execution.stub(:root_jobnet).and_return(@root)
492
+ event1.stub(:[]).with(:execution_id).and_return(execution.id.to_s)
493
+ @root.update_with_lock{ execution.transmit(signal1) }
494
+ @root.save!
495
+ execution.save!
496
+ execution.reload
497
+ @root.reload
498
+
499
+ (1..5).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
500
+ (6..26).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
501
+ @root.element('/jn0005' ).phase_key.should == :success
502
+ @root.element('/jn0005/j1' ).phase_key.should == :success
503
+ @root.element('/jn0005/j2' ).phase_key.should == :success
504
+ @root.element('/jn0005/jn4' ).phase_key.should == :ready
505
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :initialized
506
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :initialized
507
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :initialized
508
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :initialized
509
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :initialized
510
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :initialized
511
+ @root.element('/jn0005/j4' ).phase_key.should == :initialized
512
+ @root.element('/jn0005/finally' ).phase_key.should == :initialized
513
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :initialized
514
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :initialized
515
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :initialized
516
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :initialized
517
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :initialized
518
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :initialized
519
+ end
520
+ end
521
+
522
+ context "finally内のジョブjn0005_fifを起点に再実行すると" do
523
+ it "/jn0005/finally/jn0005_fjn/finally内のVertexのみリセットされる" do
524
+ t1 = Time.now
525
+ event1 = mock(:event, :occurred_at => t1)
526
+ signal1 = Tengine::Job::Signal.new(event1)
527
+ jn0005_fif = @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif')
528
+ execution = Tengine::Job::Execution.create!({
529
+ :target_actual_ids => [jn0005_fif.id.to_s],
530
+ :retry => true, :spot => false,
531
+ :root_jobnet_id => @root.id
532
+ })
533
+ execution.stub(:root_jobnet).and_return(@root)
534
+ event1.stub(:[]).with(:execution_id).and_return(execution.id.to_s)
535
+ @root.update_with_lock{ execution.transmit(signal1) }
536
+ @root.save!
537
+ execution.save!
538
+ execution.reload
539
+ @root.reload
540
+
541
+ @ctx[:e26].phase_key.should == :active
542
+ @ctx[:e20].phase_key.should == :transmitted
543
+ @ctx[:e21].phase_key.should == :transmitted
544
+ (22..25).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
545
+ (1..19).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
546
+ @root.element('/jn0005/j1' ).phase_key.should == :success
547
+ @root.element('/jn0005/j2' ).phase_key.should == :success
548
+ @root.element('/jn0005/jn4' ).phase_key.should == :success
549
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :success
550
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :success
551
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :success
552
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :success
553
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :success
554
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :success
555
+ @root.element('/jn0005/j4' ).phase_key.should == :success
556
+ @root.element('/jn0005/finally' ).phase_key.should == :success
557
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :success
558
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :success
559
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :success
560
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :success
561
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :success
562
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :ready
563
+ end
564
+ end
565
+
566
+ context "j1を起点に再実行すると" do
567
+ before do
568
+ j1 = @root.element('/jn0005/j1')
569
+ @execution = Tengine::Job::Execution.create!({
570
+ :target_actual_ids => [j1.id.to_s],
571
+ :retry => true, :spot => false,
572
+ :root_jobnet_id => @root.id
573
+ })
574
+ t1 = Time.now
575
+ event1 = mock(:event, :occurred_at => t1)
576
+ signal1 = Tengine::Job::Signal.new(event1)
577
+ @execution.stub(:root_jobnet).and_return(@root)
578
+ event1.stub(:[]).with(:execution_id).and_return(@execution.id.to_s)
579
+ @root.update_with_lock{ @execution.transmit(signal1) }
580
+ @root.save!
581
+ @execution.save!
582
+ @execution.reload
583
+ @root.reload
584
+ end
585
+
586
+ it "リセット後の確認" do
587
+ @execution.phase_key.should == :starting
588
+ (2..26).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
589
+ [1].each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
590
+ @root.element('/jn0005' ).phase_key.should == :success
591
+ @root.element('/jn0005/j1' ).phase_key.should == :ready
592
+ @root.element('/jn0005/j2' ).phase_key.should == :initialized
593
+ @root.element('/jn0005/jn4' ).phase_key.should == :initialized
594
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :initialized
595
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :initialized
596
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :initialized
597
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :initialized
598
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :initialized
599
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :initialized
600
+ @root.element('/jn0005/j4' ).phase_key.should == :initialized
601
+ @root.element('/jn0005/finally' ).phase_key.should == :initialized
602
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :initialized
603
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :initialized
604
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :initialized
605
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :initialized
606
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :initialized
607
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :initialized
608
+ end
609
+
610
+ it "jn4内のジョブがactivateされるとjn4にack" do
611
+ t2 = Time.now
612
+ event2 = mock(:"start.job.job.tengine") # j41のジョブ開始イベント
613
+ event2.stub(:occurred_at).and_return(t2)
614
+ signal2 = Tengine::Job::Signal.new(event2)
615
+ signal2.stub(:execution).and_return(@execution)
616
+
617
+ @root.element('/jn0005/jn4').phase_key = :starting
618
+ j41 = @root.element('/jn0005/jn4/j41')
619
+ j41.phase_key = :ready
620
+ @root.save!
621
+ @root.update_with_lock{ j41.activate(signal2) }
622
+ @root.reload
623
+ @root.element('/jn0005/jn4').phase_key.should == :running
624
+ end
625
+
626
+ it "/jn0005/jn4/finally/jn4_fがactivateされると/jn0005/jn4/finallyにack" do
627
+ t2 = Time.now
628
+ event2 = mock(:"start.job.job.tengine") # jn4fのジョブ開始イベント
629
+ event2.stub(:occurred_at).and_return(t2)
630
+ signal2 = Tengine::Job::Signal.new(event2)
631
+ signal2.stub(:execution).and_return(@execution)
632
+
633
+ @root.element('/jn0005/jn4/finally').phase_key = :starting
634
+ jn4_f = @root.element('/jn0005/jn4/finally/jn4_f')
635
+ jn4_f.phase_key = :ready
636
+ @root.save!
637
+ @root.update_with_lock{ jn4_f.activate(signal2) }
638
+ @root.reload
639
+ @root.element('/jn0005/jn4/finally').phase_key.should == :running
640
+ end
641
+
642
+ it "/jn0005/finally/jn0005_fjn/finally/jn0005_fifがactivateされると/jn0005/finally/jn0005_fjn/finallyにack" do
643
+ t2 = Time.now
644
+ event2 = mock(:"start.job.job.tengine") # jn0005_fifのジョブ開始イベント
645
+ event2.stub(:occurred_at).and_return(t2)
646
+ signal2 = Tengine::Job::Signal.new(event2)
647
+ signal2.stub(:execution).and_return(@execution)
648
+
649
+ @root.element('/jn0005/finally/jn0005_fjn/finally').phase_key = :starting
650
+ jn0005_fif = @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif')
651
+ jn0005_fif.phase_key = :ready
652
+ @root.save!
653
+ @root.update_with_lock{ jn0005_fif.activate(signal2) }
654
+ @root.reload
655
+ @root.element('/jn0005/finally/jn0005_fjn/finally').phase_key.should == :running
656
+ end
657
+ end
658
+ end
659
+
660
+ context "ジョブ/jn0005/jn4/j43が異常終了した後に" do
661
+ before do
662
+ [:root, :jn0005, :jn4, :j43].each{|j| @ctx[j].phase_key = :error}
663
+ [:j4, :j44].each{|j| @ctx[j].phase_key = :initialized}
664
+ [:j1, :j2, :j41, :j42,
665
+ :jn4f, :jn4_f,
666
+ :finally, :jn0005_fjn, :jn0005_f, :jn0005_f1, :jn0005_f2,
667
+ :jn0005_fjn_f, :jn0005_fif].each{|j| @ctx[j].phase_key = :success}
668
+
669
+ (1..5).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
670
+ (6..8).each{|idx| @ctx[:"e#{idx}"].phase_key = :closed}
671
+ (9..13).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
672
+ (14..16).each{|idx| @ctx[:"e#{idx}"].phase_key = :closed}
673
+ (17..26).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
674
+ @root.save!
675
+ end
676
+
677
+ context "j43を起点に再実行すると" do
678
+ it "jn4内のj43以降がリセットされる" do
679
+ t1 = Time.now
680
+ event1 = mock(:event, :occurred_at => t1)
681
+ signal1 = Tengine::Job::Signal.new(event1)
682
+ j43 = @root.element('/jn0005/jn4/j43')
683
+ execution = Tengine::Job::Execution.create!({
684
+ :target_actual_ids => [j43.id.to_s],
685
+ :retry => true, :spot => false,
686
+ :root_jobnet_id => @root.id
687
+ })
688
+ execution.stub(:root_jobnet).and_return(@root)
689
+ event1.stub(:[]).with(:execution_id).and_return(execution.id.to_s)
690
+ @root.update_with_lock{ execution.transmit(signal1) }
691
+ @root.save!
692
+ execution.save!
693
+ execution.reload
694
+ @root.reload
695
+
696
+ (1..5).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
697
+ (6..8).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :closed}
698
+ (9..13).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
699
+ (14..18).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
700
+ (19..26).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
701
+ @root.element('/jn0005' ).phase_key.should == :error
702
+ @root.element('/jn0005/j1' ).phase_key.should == :success
703
+ @root.element('/jn0005/j2' ).phase_key.should == :success
704
+ @root.element('/jn0005/jn4' ).phase_key.should == :error
705
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :success
706
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :success
707
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :ready
708
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :initialized
709
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :initialized
710
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :initialized
711
+ @root.element('/jn0005/j4' ).phase_key.should == :initialized
712
+ @root.element('/jn0005/finally' ).phase_key.should == :success
713
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :success
714
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :success
715
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :success
716
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :success
717
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :success
718
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :success
719
+ end
720
+ end
721
+
722
+ context "j44を起点に再実行すると" do
723
+ it "jn4内のj44の後続のみリセットされる" do
724
+ t1 = Time.now
725
+ event1 = mock(:event, :occurred_at => t1)
726
+ signal1 = Tengine::Job::Signal.new(event1)
727
+ j44 = @root.element('/jn0005/jn4/j44')
728
+ execution = Tengine::Job::Execution.create!({
729
+ :target_actual_ids => [j44.id.to_s],
730
+ :retry => true, :spot => false,
731
+ :root_jobnet_id => @root.id
732
+ })
733
+ execution.stub(:root_jobnet).and_return(@root)
734
+ event1.stub(:[]).with(:execution_id).and_return(execution.id.to_s)
735
+ @root.update_with_lock{ execution.transmit(signal1) }
736
+ @root.save!
737
+ execution.save!
738
+ execution.reload
739
+ @root.reload
740
+
741
+ (1..5).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
742
+ (6..8).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :closed}
743
+ (9..13).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
744
+ (14..15).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :closed}
745
+ (16..18).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
746
+ (19..26).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
747
+ @root.element('/jn0005' ).phase_key.should == :error
748
+ @root.element('/jn0005/j1' ).phase_key.should == :success
749
+ @root.element('/jn0005/j2' ).phase_key.should == :success
750
+ @root.element('/jn0005/jn4' ).phase_key.should == :error
751
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :success
752
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :success
753
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :error
754
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :ready
755
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :initialized
756
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :initialized
757
+ @root.element('/jn0005/j4' ).phase_key.should == :initialized
758
+ @root.element('/jn0005/finally' ).phase_key.should == :success
759
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :success
760
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :success
761
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :success
762
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :success
763
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :success
764
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :success
765
+ end
766
+ end
767
+
768
+ context "jn4を起点に再実行すると" do
769
+ it "jn0005内のjn4以降がリセットされる" do
770
+ t1 = Time.now
771
+ event1 = mock(:event, :occurred_at => t1)
772
+ signal1 = Tengine::Job::Signal.new(event1)
773
+ jn4 = @root.element('/jn0005/jn4')
774
+ execution = Tengine::Job::Execution.create!({
775
+ :target_actual_ids => [jn4.id.to_s],
776
+ :retry => true, :spot => false,
777
+ :root_jobnet_id => @root.id
778
+ })
779
+ execution.stub(:root_jobnet).and_return(@root)
780
+ event1.stub(:[]).with(:execution_id).and_return(execution.id.to_s)
781
+ @root.update_with_lock{ execution.transmit(signal1) }
782
+ @root.save!
783
+ execution.save!
784
+ execution.reload
785
+ @root.reload
786
+
787
+ (1..5).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
788
+ (6..26).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
789
+ @root.element('/jn0005' ).phase_key.should == :error
790
+ @root.element('/jn0005/j1' ).phase_key.should == :success
791
+ @root.element('/jn0005/j2' ).phase_key.should == :success
792
+ @root.element('/jn0005/jn4' ).phase_key.should == :ready
793
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :initialized
794
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :initialized
795
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :initialized
796
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :initialized
797
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :initialized
798
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :initialized
799
+ @root.element('/jn0005/j4' ).phase_key.should == :initialized
800
+ @root.element('/jn0005/finally' ).phase_key.should == :initialized
801
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :initialized
802
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :initialized
803
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :initialized
804
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :initialized
805
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :initialized
806
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :initialized
807
+ end
808
+ end
809
+ end
810
+
811
+ context "finally内のジョブ/jn0005/finally/jn0005_fjn/jn0005_f2が異常終了した後に" do
812
+ before do
813
+ [:root, :jn0005,
814
+ :finally, :jn0005_fjn, :jn0005_f2,].each{|j| @ctx[j].phase_key = :error}
815
+ [:j1, :j2, :jn4, :j4,
816
+ :j41, :j42, :j43, :j44,
817
+ :jn4f, :jn4_f, :jn0005_f1,
818
+ :jn0005_fjn_f, :jn0005_fif].each{|j| @ctx[j].phase_key = :success}
819
+ [:jn0005_f].each{|j| @ctx[j].phase_key = :initialized}
820
+
821
+ (1..19).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
822
+ (20..21).each{|idx| @ctx[:"e#{idx}"].phase_key = :closed}
823
+ (22..23).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
824
+ [24].each{|idx| @ctx[:"e#{idx}"].phase_key = :closed}
825
+ (25..26).each{|idx| @ctx[:"e#{idx}"].phase_key = :transmitted}
826
+ @root.save!
827
+ end
828
+
829
+ context "jn0005_f2を起点に再実行すると" do
830
+ it "jn0005_fjn内のjn0005_f2以降がリセットされる" do
831
+ t1 = Time.now
832
+ event1 = mock(:event, :occurred_at => t1)
833
+ signal1 = Tengine::Job::Signal.new(event1)
834
+ jn0005_f2 = @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2')
835
+ execution = Tengine::Job::Execution.create!({
836
+ :target_actual_ids => [jn0005_f2.id.to_s],
837
+ :retry => true, :spot => false,
838
+ :root_jobnet_id => @root.id
839
+ })
840
+ execution.stub(:root_jobnet).and_return(@root)
841
+ event1.stub(:[]).with(:execution_id).and_return(execution.id.to_s)
842
+ @root.update_with_lock{ execution.transmit(signal1) }
843
+ @root.save!
844
+ execution.save!
845
+ execution.reload
846
+ @root.reload
847
+
848
+ (1..19).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
849
+ (20..21).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :closed}
850
+ (22..23).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
851
+ (24..26).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
852
+ @root.element('/jn0005' ).phase_key.should == :error
853
+ @root.element('/jn0005/j1' ).phase_key.should == :success
854
+ @root.element('/jn0005/j2' ).phase_key.should == :success
855
+ @root.element('/jn0005/jn4' ).phase_key.should == :success
856
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :success
857
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :success
858
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :success
859
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :success
860
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :success
861
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :success
862
+ @root.element('/jn0005/j4' ).phase_key.should == :success
863
+ @root.element('/jn0005/finally' ).phase_key.should == :error
864
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :error
865
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :success
866
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :ready
867
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :initialized
868
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :initialized
869
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :initialized
870
+ end
871
+ end
872
+
873
+ context "jn0005_fjnを起点に再実行すると" do
874
+ it "jn0005_fjn内がリセットされる" do
875
+ t1 = Time.now
876
+ event1 = mock(:event, :occurred_at => t1)
877
+ signal1 = Tengine::Job::Signal.new(event1)
878
+ jn0005_fjn = @root.element('/jn0005/finally/jn0005_fjn')
879
+ execution = Tengine::Job::Execution.create!({
880
+ :target_actual_ids => [jn0005_fjn.id.to_s],
881
+ :retry => true, :spot => false,
882
+ :root_jobnet_id => @root.id
883
+ })
884
+ execution.stub(:root_jobnet).and_return(@root)
885
+ event1.stub(:[]).with(:execution_id).and_return(execution.id.to_s)
886
+ @root.update_with_lock{ execution.transmit(signal1) }
887
+ @root.save!
888
+ execution.save!
889
+ execution.reload
890
+ @root.reload
891
+
892
+ (1..19).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
893
+ (20..26).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
894
+ @root.element('/jn0005' ).phase_key.should == :error
895
+ @root.element('/jn0005/j1' ).phase_key.should == :success
896
+ @root.element('/jn0005/j2' ).phase_key.should == :success
897
+ @root.element('/jn0005/jn4' ).phase_key.should == :success
898
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :success
899
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :success
900
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :success
901
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :success
902
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :success
903
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :success
904
+ @root.element('/jn0005/j4' ).phase_key.should == :success
905
+ @root.element('/jn0005/finally' ).phase_key.should == :error
906
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :ready
907
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :initialized
908
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :initialized
909
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :initialized
910
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :initialized
911
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :initialized
912
+ end
913
+ end
914
+
915
+ context "jn0005/finallyを起点に再実行すると" do
916
+ it "jn0005/finally内がリセットされる" do
917
+ t1 = Time.now
918
+ event1 = mock(:event, :occurred_at => t1)
919
+ signal1 = Tengine::Job::Signal.new(event1)
920
+ finally = @root.element('/jn0005/finally')
921
+ execution = Tengine::Job::Execution.create!({
922
+ :target_actual_ids => [finally.id.to_s],
923
+ :retry => true, :spot => false,
924
+ :root_jobnet_id => @root.id
925
+ })
926
+ execution.stub(:root_jobnet).and_return(@root)
927
+ event1.stub(:[]).with(:execution_id).and_return(execution.id.to_s)
928
+ @root.update_with_lock{ execution.transmit(signal1) }
929
+ @root.save!
930
+ execution.save!
931
+ execution.reload
932
+ @root.reload
933
+
934
+ (1..18).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :transmitted}
935
+ (19..26).each{|idx| @ctx[:"e#{idx}"].phase_key.should == :active}
936
+ @root.element('/jn0005' ).phase_key.should == :error
937
+ @root.element('/jn0005/j1' ).phase_key.should == :success
938
+ @root.element('/jn0005/j2' ).phase_key.should == :success
939
+ @root.element('/jn0005/jn4' ).phase_key.should == :success
940
+ @root.element('/jn0005/jn4/j41' ).phase_key.should == :success
941
+ @root.element('/jn0005/jn4/j42' ).phase_key.should == :success
942
+ @root.element('/jn0005/jn4/j43' ).phase_key.should == :success
943
+ @root.element('/jn0005/jn4/j44' ).phase_key.should == :success
944
+ @root.element('/jn0005/jn4/finally' ).phase_key.should == :success
945
+ @root.element('/jn0005/jn4/finally/jn4_f').phase_key.should == :success
946
+ @root.element('/jn0005/j4' ).phase_key.should == :success
947
+ @root.element('/jn0005/finally' ).phase_key.should == :ready
948
+ @root.element('/jn0005/finally/jn0005_fjn' ).phase_key.should == :initialized
949
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f1' ).phase_key.should == :initialized
950
+ @root.element('/jn0005/finally/jn0005_fjn/jn0005_f2' ).phase_key.should == :initialized
951
+ @root.element('/jn0005/finally/jn0005_f' ).phase_key.should == :initialized
952
+ @root.element('/jn0005/finally/jn0005_fjn/finally' ).phase_key.should == :initialized
953
+ @root.element('/jn0005/finally/jn0005_fjn/finally/jn0005_fif').phase_key.should == :initialized
954
+ end
955
+ end
956
+ end
957
+ end
958
+ end