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,202 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'tengine/rspec'
4
+
5
+ describe 'schedule_driver' do
6
+ include Tengine::RSpec::Extension
7
+
8
+ target_dsl File.expand_path("../../../../lib/tengine/job/drivers/schedule_driver.rb", File.dirname(__FILE__))
9
+ driver :schedule_driver
10
+
11
+ context "rjn0001" do
12
+ before do
13
+ Tengine::Core::Schedule.delete_all
14
+ Tengine::Job::Vertex.delete_all
15
+ builder = Rjn0001SimpleJobnetBuilder.new
16
+ @root = builder.create_actual
17
+ @ctx = builder.context
18
+ @execution = Tengine::Job::Execution.create!({
19
+ :root_jobnet_id => @root.id,
20
+ })
21
+ end
22
+
23
+ context "start" do
24
+ before do
25
+ # start.execution.job.tengineをreceiveすると
26
+ # job_execution_driverも受け取ってしまって、それが
27
+ # start.jobnet.job.tengineをfireしようとして、
28
+ # MQに接続しようとするので、適当にstubする必要がある
29
+ kern = ObjectSpace.each_object(Tengine::Core::Kernel) {|i| break i }
30
+ send = mock(:sender)
31
+ kern.stub(:sender).and_return(send)
32
+ send.stub(:fire)
33
+ end
34
+
35
+ it "タイムアウトが設定されていない場合はなにもしない" do
36
+ @execution.phase_key = :initialized
37
+ @execution.unset :actual_base_timeout_alert
38
+ @execution.unset :actual_base_timeout_termination
39
+ @execution.save!
40
+ @root.phase_key = :initialized
41
+ @root.save!
42
+ EM.run_block do
43
+ tengine.receive("start.execution.job.tengine", :properties => {
44
+ :execution_id => @execution.id.to_s,
45
+ :root_jobnet_id => @root.id.to_s,
46
+ :target_jobnet_id => @root.id.to_s,
47
+ })
48
+ end
49
+ Tengine::Core::Schedule.where(:status => Tengine::Core::Schedule::SCHEDULED).should be_empty
50
+ end
51
+
52
+ it "タイムアウトが0で設定されていた場合はなにもしない" do
53
+ @execution.phase_key = :initialized
54
+ @execution.actual_base_timeout_alert = 0
55
+ @execution.actual_base_timeout_termination = 0
56
+ @execution.save!
57
+ @root.phase_key = :initialized
58
+ @root.save!
59
+ EM.run_block do
60
+ tengine.receive("start.execution.job.tengine", :properties => {
61
+ :execution_id => @execution.id.to_s,
62
+ :root_jobnet_id => @root.id.to_s,
63
+ :target_jobnet_id => @root.id.to_s,
64
+ })
65
+ end
66
+ Tengine::Core::Schedule.where(:status => Tengine::Core::Schedule::SCHEDULED).should be_empty
67
+ end
68
+
69
+ it "タイムアウトが設定されていればスケジュールストアに保存" do
70
+ @execution.phase_key = :initialized
71
+ @execution.actual_base_timeout_alert = 32768
72
+ @execution.actual_base_timeout_termination = 65536
73
+ @execution.save!
74
+ @root.phase_key = :initialized
75
+ @root.save!
76
+ EM.run_block do
77
+ tengine.receive("start.execution.job.tengine", :properties => {
78
+ :execution_id => @execution.id.to_s,
79
+ :root_jobnet_id => @root.id.to_s,
80
+ :target_jobnet_id => @root.id.to_s,
81
+ })
82
+ end
83
+ Tengine::Core::Schedule.count(:conditions => {:status => Tengine::Core::Schedule::SCHEDULED}).should == 2
84
+ s1 = Tengine::Core::Schedule.first(:conditions => {:event_type_name => "alert.execution.job.tengine"})
85
+ s2 = Tengine::Core::Schedule.first(:conditions => {:event_type_name => "stop.execution.job.tengine"})
86
+ [s1, s2].each do |i|
87
+ i.source_name.should == @execution.name_as_resource
88
+ i.scheduled_at.should >= Time.now
89
+ end
90
+ s1.properties.should == {
91
+ 'execution_id' => @execution.id.to_s,
92
+ 'root_jobnet_id' => @root.id.to_s,
93
+ 'target_jobnet_id' => @root.id.to_s,
94
+ }
95
+ s2.properties.should == {
96
+ 'execution_id' => @execution.id.to_s,
97
+ 'root_jobnet_id' => @root.id.to_s,
98
+ 'target_jobnet_id' => @root.id.to_s,
99
+ 'stop_reason'=>'timeout'
100
+ }
101
+ end
102
+ end
103
+
104
+ shared_examples "terminated" do
105
+ it "タイムアウトが設定されていない場合はなにもしない #1" do
106
+ Tengine::Core::Schedule.delete_all
107
+ EM.run_block do
108
+ tengine.receive(event, :properties => {
109
+ :execution_id => @execution.id.to_s,
110
+ :root_jobnet_id => @root.id.to_s,
111
+ :target_jobnet_id => @root.id.to_s,
112
+ })
113
+ end
114
+ Tengine::Core::Schedule.should be_empty
115
+ end
116
+
117
+ it "タイムアウトが設定されていない場合はなにもしない #2" do
118
+ s0 = Tengine::Core::Schedule.new
119
+ s0.status = Tengine::Core::Schedule::SCHEDULED
120
+ s0.scheduled_at = Time.at 0
121
+ s0.save
122
+ s1 = Tengine::Core::Schedule.new
123
+ s1.status = Tengine::Core::Schedule::INVALID
124
+ s1.scheduled_at = Time.at 0
125
+ s1.source_name = @execution.name_as_resource
126
+ s1.save
127
+ EM.run_block do
128
+ tengine.receive(event, :properties => {
129
+ :execution_id => @execution.id.to_s,
130
+ :root_jobnet_id => @root.id.to_s,
131
+ :target_jobnet_id => @root.id.to_s,
132
+ })
133
+ end
134
+ s0.reload
135
+ s0.status.should == Tengine::Core::Schedule::SCHEDULED
136
+ s1.reload
137
+ s1.status.should == Tengine::Core::Schedule::INVALID
138
+ end
139
+
140
+ it "タイムアウトが設定されているが既に終了してしまっている場合も何もしない" do
141
+ s0 = Tengine::Core::Schedule.new
142
+ s0.status = Tengine::Core::Schedule::FIRED
143
+ s0.scheduled_at = Time.at 0
144
+ s0.source_name = @execution.name_as_resource
145
+ s0.save
146
+ EM.run_block do
147
+ tengine.receive(event, :properties => {
148
+ :execution_id => @execution.id.to_s,
149
+ :root_jobnet_id => @root.id.to_s,
150
+ :target_jobnet_id => @root.id.to_s,
151
+ })
152
+ end
153
+ s0.reload
154
+ s0.status.should == Tengine::Core::Schedule::FIRED
155
+ end
156
+
157
+ it "タイムアウトが設定されていてかつまだ終了していない場合はinvalidateする #1" do
158
+ s0 = Tengine::Core::Schedule.new
159
+ s0.status = Tengine::Core::Schedule::SCHEDULED
160
+ s0.scheduled_at = Time.at 0
161
+ s0.source_name = @execution.name_as_resource
162
+ s0.save
163
+ EM.run_block do
164
+ tengine.receive(event, :properties => {
165
+ :execution_id => @execution.id.to_s,
166
+ :root_jobnet_id => @root.id.to_s,
167
+ :target_jobnet_id => @root.id.to_s,
168
+ })
169
+ end
170
+ s0.reload
171
+ s0.status.should == Tengine::Core::Schedule::INVALID
172
+ end
173
+
174
+ it "タイムアウトが設定されていてかつまだ終了していない場合はinvalidateする #2" do
175
+ s0 = Tengine::Core::Schedule.new
176
+ s0.status = Tengine::Core::Schedule::SCHEDULED
177
+ s0.scheduled_at = Time.now + 32768
178
+ s0.source_name = @execution.name_as_resource
179
+ s0.save
180
+ EM.run_block do
181
+ tengine.receive(event, :properties => {
182
+ :execution_id => @execution.id.to_s,
183
+ :root_jobnet_id => @root.id.to_s,
184
+ :target_jobnet_id => @root.id.to_s,
185
+ })
186
+ end
187
+ s0.reload
188
+ s0.status.should == Tengine::Core::Schedule::INVALID
189
+ end
190
+ end
191
+
192
+ context "success" do
193
+ let(:event) { "success.execution.job.tengine" }
194
+ it_should_behave_like "terminated"
195
+ end
196
+
197
+ context "error" do
198
+ let(:event) { "error.execution.job.tengine" }
199
+ it_should_behave_like "terminated"
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'tengine/rspec'
4
+
5
+ describe Tengine::Job::DslLoader do
6
+ before(:all) do
7
+ Tengine.plugins.add(Tengine::Job)
8
+ Tengine::Job::Vertex.delete_all
9
+ end
10
+
11
+ include Tengine::RSpec::Extension
12
+
13
+ target_dsl File.expand_path("dsls/0019_execute_job_on_event.rb", File.dirname(__FILE__))
14
+ driver :job_control_driver
15
+
16
+
17
+ describe "実行時にジョブを起動するイベントドライバ" do
18
+ context "0019_execute_job_on_event.rb" do
19
+
20
+ it do
21
+ mock_execution = mock(:execution, :id => "mock_execution_id")
22
+ Tengine::Job::Execution.should_receive(:create!).and_return(mock_execution)
23
+ tengine.should_fire(:"start.execution.job.tengine", {
24
+ :properties=>{
25
+ :execution_id => mock_execution.id.to_s,
26
+ :root_jobnet_id => an_instance_of(BSON::ObjectId),
27
+ :target_jobnet_id => an_instance_of(BSON::ObjectId),
28
+ }
29
+ })
30
+ tengine.receive("foo")
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,403 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Tengine::Job::DslLoader do
5
+ before(:all) do
6
+ Tengine.plugins.add(Tengine::Job::DslLoader)
7
+ end
8
+
9
+ def load_dsl(filename)
10
+ config = {
11
+ :action => "load",
12
+ :tengined => { :load_path => File.expand_path("dsls/#{filename}", File.dirname(__FILE__)) },
13
+ }
14
+ @version = File.read(File.expand_path("dsls/VERSION", File.dirname(__FILE__))).strip
15
+ @bootstrap = Tengine::Core::Bootstrap.new(config)
16
+ @bootstrap.boot
17
+ end
18
+
19
+ describe "基本的なジョブDSL" do
20
+ context "0013_hadoop_job_run.rb" do
21
+ before{
22
+ Tengine::Job::JobnetTemplate.delete_all
23
+ load_dsl("0013_hadoop_job_run.rb")
24
+ }
25
+
26
+ it do
27
+ root_jobnet = Tengine::Job::JobnetTemplate.by_name("jobnet0013")
28
+ root_jobnet.should be_a(Tengine::Job::RootJobnetTemplate)
29
+ root_jobnet.tap do |j|
30
+ j.version.should == 0
31
+ j.dsl_version.should == @version
32
+ j.dsl_filepath.should == "0013_hadoop_job_run.rb"
33
+ j.dsl_lineno.should == 21
34
+ j.name.should == "jobnet0013"
35
+ j.description.should == "ジョブネット0013"
36
+ j.server_name.should == "i-11111111"
37
+ j.credential_name.should == "goku-ssh-pk1"
38
+ end
39
+ root_jobnet.children.map(&:class).should == [
40
+ Tengine::Job::Start,
41
+ Tengine::Job::JobnetTemplate,
42
+ Tengine::Job::JobnetTemplate,
43
+ Tengine::Job::JobnetTemplate,
44
+ Tengine::Job::End,
45
+ ]
46
+ root_jobnet.children[1].tap{|j| j.name.should == "job1"; j.description.should == "ジョブ1"; j.script.should == "import_hdfs.sh"}
47
+ hadoop_job_run = root_jobnet.children[2]
48
+ root_jobnet.children[3].tap{|j| j.name.should == "job2"; j.description.should == "ジョブ2"; j.script.should == "export_hdfs.sh"}
49
+ root_jobnet.edges.map{|edge| [edge.origin, edge.destination]}.should == [
50
+ [root_jobnet.children[0], root_jobnet.children[1]],
51
+ [root_jobnet.children[1], root_jobnet.children[2]],
52
+ [root_jobnet.children[2], root_jobnet.children[3]],
53
+ [root_jobnet.children[3], root_jobnet.children[4]],
54
+ ]
55
+ hadoop_job_run.tap{|j| j.name.should == "hadoop_job_run1"; j.description.should == "Hadoopジョブ1"; j.script.should == "hadoop_job_run.sh"}
56
+ hadoop_job_run.children.map(&:class).should == [
57
+ Tengine::Job::Start,
58
+ Tengine::Job::JobnetTemplate,
59
+ Tengine::Job::JobnetTemplate,
60
+ Tengine::Job::End,
61
+ ]
62
+ hadoop_job_run.edges.map{|edge| [edge.origin, edge.destination]}.should == [
63
+ [hadoop_job_run.children[0], hadoop_job_run.children[1]],
64
+ [hadoop_job_run.children[1], hadoop_job_run.children[2]],
65
+ [hadoop_job_run.children[2], hadoop_job_run.children[3]],
66
+ ]
67
+ hadoop_job1 = hadoop_job_run.children[1]
68
+ hadoop_job1.tap{|j| j.name.should == "hadoop_job1"}
69
+ hadoop_job1.children.map(&:class).should == [
70
+ Tengine::Job::Start,
71
+ Tengine::Job::Fork,
72
+ Tengine::Job::JobnetTemplate,
73
+ Tengine::Job::JobnetTemplate,
74
+ Tengine::Job::Join,
75
+ Tengine::Job::End,
76
+ ]
77
+
78
+ hadoop_job1.edges.map{|edge| [edge.origin, edge.destination]}.should == [
79
+ [hadoop_job1.children[0], hadoop_job1.children[1]],
80
+ [hadoop_job1.children[1], hadoop_job1.children[2]],
81
+ [hadoop_job1.children[1], hadoop_job1.children[3]],
82
+ [hadoop_job1.children[2], hadoop_job1.children[4]],
83
+ [hadoop_job1.children[3], hadoop_job1.children[4]],
84
+ [hadoop_job1.children[4], hadoop_job1.children[5]],
85
+ ]
86
+
87
+ hadoop_job1.edges.map{|edge| [edge.origin.class, edge.destination.class]}.should == [
88
+ [Tengine::Job::Start , Tengine::Job::Fork ],
89
+ [Tengine::Job::Fork , Tengine::Job::JobnetTemplate],
90
+ [Tengine::Job::Fork , Tengine::Job::JobnetTemplate],
91
+ [Tengine::Job::JobnetTemplate, Tengine::Job::Join ],
92
+ [Tengine::Job::JobnetTemplate, Tengine::Job::Join ],
93
+ [Tengine::Job::Join , Tengine::Job::End ],
94
+ ]
95
+ hadoop_job2 = hadoop_job_run.children[2]
96
+ hadoop_job2.tap{|j| j.name.should == "hadoop_job2"}
97
+ hadoop_job2.children.map(&:class).should == [
98
+ Tengine::Job::Start,
99
+ Tengine::Job::Fork,
100
+ Tengine::Job::JobnetTemplate,
101
+ Tengine::Job::JobnetTemplate,
102
+ Tengine::Job::Join,
103
+ Tengine::Job::End,
104
+ ]
105
+ end
106
+ end
107
+
108
+ context "0014_join_and_join.rb" do
109
+ before{
110
+ Tengine::Job::JobnetTemplate.delete_all
111
+ load_dsl("0014_join_and_join.rb")
112
+ }
113
+
114
+ it do
115
+ root_jobnet = Tengine::Job::JobnetTemplate.by_name("jobnet0014")
116
+ root_jobnet.should be_a(Tengine::Job::RootJobnetTemplate)
117
+ root_jobnet.tap do |j|
118
+ j.version.should == 0
119
+ j.dsl_version.should == @version
120
+ j.dsl_filepath.should == "0014_join_and_join.rb"
121
+ j.dsl_lineno.should == 12
122
+ j.name.should == "jobnet0014"
123
+ j.description.should == "jobnet0014"
124
+ j.server_name.should == "i-11111111"
125
+ j.credential_name.should == "goku-ssh-pk1"
126
+ end
127
+ root_jobnet.children.map(&:class).should == [
128
+ Tengine::Job::Start , # 0
129
+ Tengine::Job::JobnetTemplate, # 1
130
+ Tengine::Job::JobnetTemplate, # 2
131
+ Tengine::Job::JobnetTemplate, # 3
132
+ Tengine::Job::JobnetTemplate, # 4
133
+ Tengine::Job::JobnetTemplate, # 5
134
+ Tengine::Job::Fork , # 6
135
+ Tengine::Job::Join , # 7
136
+ Tengine::Job::Join , # 8
137
+ Tengine::Job::End , # 9
138
+ ]
139
+ root_jobnet.children[1].tap{|j| j.name.should == "job1"; j.description.should == "job1"; j.script.should == "echo 'job1'"}
140
+ root_jobnet.children[2].tap{|j| j.name.should == "job2"; j.description.should == "job2"; j.script.should == "echo 'job2'"}
141
+ root_jobnet.children[3].tap{|j| j.name.should == "job3"; j.description.should == "job3"; j.script.should == "echo 'job3'"}
142
+ root_jobnet.children[4].tap{|j| j.name.should == "job4"; j.description.should == "job4"; j.script.should == "echo 'job4'"}
143
+ root_jobnet.children[5].tap{|j| j.name.should == "job5"; j.description.should == "job5"; j.script.should == "echo 'job5'"}
144
+
145
+ root_jobnet.edges.map{|edge| [edge.origin, edge.destination]}.should == [
146
+ [root_jobnet.children[0], root_jobnet.children[6]],
147
+ [root_jobnet.children[6], root_jobnet.children[1]],
148
+ [root_jobnet.children[6], root_jobnet.children[2]],
149
+ [root_jobnet.children[6], root_jobnet.children[3]],
150
+ [root_jobnet.children[1], root_jobnet.children[7]],
151
+ [root_jobnet.children[2], root_jobnet.children[7]],
152
+ [root_jobnet.children[7], root_jobnet.children[4]],
153
+ [root_jobnet.children[3], root_jobnet.children[8]],
154
+ [root_jobnet.children[4], root_jobnet.children[8]],
155
+ [root_jobnet.children[8], root_jobnet.children[5]],
156
+ [root_jobnet.children[5], root_jobnet.children[9]],
157
+ ]
158
+ end
159
+ end
160
+
161
+ context "0015_fork_and_fork.rb" do
162
+ before{
163
+ Tengine::Job::JobnetTemplate.delete_all
164
+ load_dsl("0015_fork_and_fork.rb")
165
+ }
166
+
167
+ it do
168
+ root_jobnet = Tengine::Job::JobnetTemplate.by_name("jobnet0015")
169
+ root_jobnet.should be_a(Tengine::Job::RootJobnetTemplate)
170
+ root_jobnet.tap do |j|
171
+ j.version.should == 0
172
+ j.dsl_version.should == @version
173
+ j.dsl_filepath.should == "0015_fork_and_fork.rb"
174
+ j.dsl_lineno.should == 11
175
+ j.name.should == "jobnet0015"
176
+ j.description.should == "jobnet0015"
177
+ j.server_name.should == "i-11111111"
178
+ j.credential_name.should == "goku-ssh-pk1"
179
+ end
180
+ root_jobnet.children.map(&:class).should == [
181
+ Tengine::Job::Start , # 0
182
+ Tengine::Job::JobnetTemplate, # 1
183
+ Tengine::Job::JobnetTemplate, # 2
184
+ Tengine::Job::JobnetTemplate, # 3
185
+ Tengine::Job::JobnetTemplate, # 4
186
+ Tengine::Job::JobnetTemplate, # 5
187
+ Tengine::Job::Fork , # 6
188
+ Tengine::Job::Fork , # 7
189
+ Tengine::Job::Join , # 8
190
+ Tengine::Job::End , # 9
191
+ ]
192
+ root_jobnet.children[1].tap{|j| j.name.should == "job1"; j.description.should == "job1"; j.script.should == "echo 'job1'"}
193
+ root_jobnet.children[2].tap{|j| j.name.should == "job2"; j.description.should == "job2"; j.script.should == "echo 'job2'"}
194
+ root_jobnet.children[3].tap{|j| j.name.should == "job3"; j.description.should == "job3"; j.script.should == "echo 'job3'"}
195
+ root_jobnet.children[4].tap{|j| j.name.should == "job4"; j.description.should == "job4"; j.script.should == "echo 'job4'"}
196
+ root_jobnet.children[5].tap{|j| j.name.should == "job5"; j.description.should == "job5"; j.script.should == "echo 'job5'"}
197
+
198
+ root_jobnet.edges.map{|edge| [edge.origin, edge.destination]}.should == [
199
+ [root_jobnet.children[0], root_jobnet.children[1]],
200
+ [root_jobnet.children[1], root_jobnet.children[6]],
201
+ [root_jobnet.children[6], root_jobnet.children[2]],
202
+ [root_jobnet.children[6], root_jobnet.children[3]],
203
+ [root_jobnet.children[3], root_jobnet.children[7]],
204
+ [root_jobnet.children[7], root_jobnet.children[4]],
205
+ [root_jobnet.children[7], root_jobnet.children[5]],
206
+ [root_jobnet.children[2], root_jobnet.children[8]],
207
+ [root_jobnet.children[4], root_jobnet.children[8]],
208
+ [root_jobnet.children[5], root_jobnet.children[8]],
209
+ [root_jobnet.children[8], root_jobnet.children[9]],
210
+ ]
211
+ end
212
+ end
213
+
214
+ context "0016_complex_fork_and_join.rb" do
215
+ before{
216
+ Tengine::Job::JobnetTemplate.delete_all
217
+ load_dsl("0016_complex_fork_and_join.rb")
218
+ }
219
+
220
+ it do
221
+ root_jobnet = Tengine::Job::JobnetTemplate.by_name("jobnet0016")
222
+ root_jobnet.should be_a(Tengine::Job::RootJobnetTemplate)
223
+ root_jobnet.tap do |j|
224
+ j.version.should == 0
225
+ j.dsl_version.should == @version
226
+ j.dsl_filepath.should == "0016_complex_fork_and_join.rb"
227
+ j.dsl_lineno.should == 11
228
+ j.name.should == "jobnet0016"
229
+ j.description.should == "jobnet0016"
230
+ j.server_name.should == "i-11111111"
231
+ j.credential_name.should == "goku-ssh-pk1"
232
+ end
233
+ root_jobnet.children.map(&:class).should == [
234
+ Tengine::Job::Start , # 0
235
+ Tengine::Job::JobnetTemplate, # 1
236
+ Tengine::Job::JobnetTemplate, # 2
237
+ Tengine::Job::JobnetTemplate, # 3
238
+ Tengine::Job::JobnetTemplate, # 4
239
+ Tengine::Job::JobnetTemplate, # 5
240
+ Tengine::Job::JobnetTemplate, # 6
241
+ Tengine::Job::JobnetTemplate, # 7
242
+ Tengine::Job::Fork , # 8
243
+ Tengine::Job::Fork , # 9
244
+ Tengine::Job::Fork , # 10
245
+ Tengine::Job::Join , # 11
246
+ Tengine::Job::Join , # 12
247
+ Tengine::Job::End , # 13
248
+ ]
249
+ (1..7).each do |idx|
250
+ root_jobnet.children[idx].tap{|j|
251
+ j.name.should == "job#{idx}"
252
+ j.description.should == "job#{idx}"
253
+ j.script.should == "echo 'job#{idx}'"
254
+ }
255
+ end
256
+
257
+ root_jobnet.edges.map{|edge| [edge.origin, edge.destination]}.should == [
258
+ [root_jobnet.children[ 0], root_jobnet.children[ 8]],
259
+ [root_jobnet.children[ 8], root_jobnet.children[ 1]],
260
+ [root_jobnet.children[ 8], root_jobnet.children[ 2]],
261
+
262
+ [root_jobnet.children[ 2], root_jobnet.children[ 9]],
263
+ [root_jobnet.children[ 9], root_jobnet.children[ 7]],
264
+
265
+
266
+ [root_jobnet.children[ 3], root_jobnet.children[10]],
267
+ [root_jobnet.children[10], root_jobnet.children[ 4]],
268
+ [root_jobnet.children[11], root_jobnet.children[ 6]],
269
+ [root_jobnet.children[ 9], root_jobnet.children[11]],
270
+ [root_jobnet.children[10], root_jobnet.children[11]],
271
+ [root_jobnet.children[ 1], root_jobnet.children[ 3]],
272
+ [root_jobnet.children[ 4], root_jobnet.children[ 5]],
273
+ [root_jobnet.children[ 6], root_jobnet.children[12]],
274
+ [root_jobnet.children[ 7], root_jobnet.children[12]],
275
+ [root_jobnet.children[ 5], root_jobnet.children[12]],
276
+ [root_jobnet.children[12], root_jobnet.children[13]],
277
+ ]
278
+ end
279
+ end
280
+
281
+ context "0017_finally.rb" do
282
+ before{
283
+ Tengine::Job::JobnetTemplate.delete_all
284
+ load_dsl("0017_finally.rb")
285
+ }
286
+
287
+ it do
288
+ root_jobnet = Tengine::Job::JobnetTemplate.by_name("jobnet0017")
289
+ root_jobnet.should be_a(Tengine::Job::RootJobnetTemplate)
290
+ root_jobnet.tap do |j|
291
+ j.version.should == 0
292
+ j.dsl_version.should == @version
293
+ j.dsl_filepath.should == "0017_finally.rb"
294
+ j.dsl_lineno.should == 5
295
+ j.name.should == "jobnet0017"
296
+ j.description.should == "ジョブネット0017"
297
+ j.server_name.should == "i-11111111"
298
+ j.credential_name.should == "goku-ssh-pk1"
299
+ end
300
+ root_jobnet.children.map(&:class).should == [
301
+ Tengine::Job::Start , # 0
302
+ Tengine::Job::JobnetTemplate, # 1
303
+ Tengine::Job::JobnetTemplate, # 2
304
+ Tengine::Job::JobnetTemplate, # 3
305
+ Tengine::Job::JobnetTemplate, # 4
306
+ Tengine::Job::End , # 5
307
+ ]
308
+ root_jobnet.children[1].tap{|j| j.name.should == "job1"; j.description.should == "ジョブ1"; j.script.should == "job1.sh"}
309
+ root_jobnet.children[2].tap{|j| j.name.should == "job2"; j.description.should == "ジョブ2"; j.script.should == "job2.sh"}
310
+ root_jobnet.children[3].tap{|j| j.name.should == "job3"; j.description.should == "ジョブ3"; j.script.should == "job3.sh"}
311
+ root_jobnet.children[4].tap{|j|
312
+ j.name.should == "finally"
313
+ j.description.should == "finally"
314
+ j.jobnet_type_key.should == :finally
315
+ }
316
+
317
+ root_jobnet.edges.map{|edge| [edge.origin, edge.destination]}.should == [
318
+ [root_jobnet.children[0], root_jobnet.children[1]],
319
+ [root_jobnet.children[1], root_jobnet.children[2]],
320
+ [root_jobnet.children[2], root_jobnet.children[3]],
321
+ [root_jobnet.children[3], root_jobnet.children[5]],
322
+ ]
323
+
324
+ finally_jobnet = root_jobnet.children[4]
325
+ finally_jobnet.children.map(&:class).should == [
326
+ Tengine::Job::Start , # 0
327
+ Tengine::Job::JobnetTemplate, # 1
328
+ Tengine::Job::JobnetTemplate, # 2
329
+ Tengine::Job::End , # 3
330
+ ]
331
+ finally_jobnet.edges.map{|edge| [edge.origin, edge.destination]}.should == [
332
+ [finally_jobnet.children[0], finally_jobnet.children[1]],
333
+ [finally_jobnet.children[1], finally_jobnet.children[2]],
334
+ [finally_jobnet.children[2], finally_jobnet.children[3]],
335
+ ]
336
+ end
337
+ end
338
+
339
+ context "0018_expansion.rb" do
340
+ before{
341
+ Tengine::Job::JobnetTemplate.delete_all
342
+ load_dsl("0018_expansion.rb")
343
+ }
344
+
345
+ it do
346
+ root_jobnet = Tengine::Job::JobnetTemplate.by_name("jobnet0018")
347
+ root_jobnet.should be_a(Tengine::Job::RootJobnetTemplate)
348
+ root_jobnet.tap do |j|
349
+ j.version.should == 0
350
+ j.dsl_version.should == @version
351
+ j.dsl_filepath.should == "0018_expansion.rb"
352
+ j.dsl_lineno.should == 19
353
+ j.name.should == "jobnet0018"
354
+ j.description.should == "jobnet0018"
355
+ j.server_name.should == nil
356
+ j.credential_name.should == nil
357
+ end
358
+ root_jobnet.children.map(&:class).should == [
359
+ Tengine::Job::Start , # 0
360
+ Tengine::Job::Expansion, # 1
361
+ Tengine::Job::Expansion, # 2
362
+ Tengine::Job::End , # 3
363
+ ]
364
+ root_jobnet.children[1].tap{|j| j.name.should == "jobnet0018_01" }
365
+ root_jobnet.children[2].tap{|j| j.name.should == "jobnet0018_02" }
366
+
367
+ root_jobnet.edges.map{|edge| [edge.origin, edge.destination]}.should == [
368
+ [root_jobnet.children[0], root_jobnet.children[1]],
369
+ [root_jobnet.children[1], root_jobnet.children[2]],
370
+ [root_jobnet.children[2], root_jobnet.children[3]],
371
+ ]
372
+ # expansion実行スケジュール登録時に参照するルートジョブネットをコピーするので
373
+ # テンプレートでは子要素を持ちません。
374
+ root_jobnet.children[1].children.should be_empty
375
+ root_jobnet.children[2].children.should be_empty
376
+ end
377
+ end
378
+
379
+ end
380
+
381
+ context "<バグ>同じDSLバージョンで同一のルートジョブネット名が定義できてしまう" do
382
+ it do
383
+ Tengine::Job::JobnetTemplate.delete_all
384
+ expect{
385
+ load_dsl("0020_duplicated_jobnet_name.rb")
386
+ }.to raise_error(Tengine::Job::DslError, "2 jobnet named \"jobnet0020\" found at 0020_duplicated_jobnet_name.rb:6 and 0020_duplicated_jobnet_name.rb:12")
387
+ end
388
+ end
389
+
390
+ context "https://www.pivotaltracker.com/story/show/22350445" do
391
+ context "2003_expansion" do
392
+ before { Tengine::Job::JobnetTemplate.delete_all }
393
+
394
+ context "expansion_5" do
395
+ it do
396
+ expect do
397
+ load_dsl "2003_expansion/expansion_5.rb"
398
+ end.should raise_error(Tengine::Job::DslError)
399
+ end
400
+ end
401
+ end
402
+ end
403
+ end