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,116 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Tengine::Job::Expansion do
5
+
6
+ context "rjn0008" do
7
+ before do
8
+ Tengine::Job::Vertex.delete_all
9
+ Rjn0001SimpleJobnetBuilder.new.create_template
10
+ Rjn0002SimpleParallelJobnetBuilder.new.create_template
11
+ builder = Rjn0008ExpansionFixture.new
12
+ @template = builder.create_template
13
+ @ctx = builder.context
14
+ end
15
+
16
+ it "生成されたActualはrjn0001とrjn0002を含む" do
17
+ actual = @template.generate
18
+ actual.should be_a(Tengine::Job::RootJobnetActual)
19
+ actual.name_path.should == "/rjn0008"
20
+ actual.name_path_until_expansion.should == "/rjn0008"
21
+ actual.actual_server_name.should == nil
22
+ actual.actual_server.should == nil
23
+ actual.children.length.should == 4
24
+ actual.children[0].tap{|j| j.should be_a(Tengine::Job::Start)}
25
+ actual.children[1].tap do |rjn0001|
26
+ rjn0001.should be_a(Tengine::Job::JobnetActual)
27
+ rjn0001.name.should == "rjn0001"
28
+ rjn0001.name_path.should == "/rjn0008/rjn0001"
29
+ rjn0001.name_path_until_expansion.should == "/rjn0001"
30
+ rjn0001.actual_server_name.should == "test_server1"
31
+ rjn0001.actual_server.should_not == nil
32
+ rjn0001.actual_credential_name.should == "test_credential1"
33
+ rjn0001.actual_credential.should_not == nil
34
+ rjn0001.was_expansion.should == true
35
+ rjn0001.ancestors.should == [actual]
36
+ rjn0001.ancestors_until_expansion.should == []
37
+ rjn0001.children.length.should == 4
38
+ rjn0001.children[0].tap{|j| j.should be_a(Tengine::Job::Start)}
39
+ rjn0001.children[1].tap do |j11|
40
+ j11.name.should == "j11"
41
+ j11.name_path.should == "/rjn0008/rjn0001/j11"
42
+ j11.name_path_until_expansion.should == "/rjn0001/j11"
43
+ j11.should be_a(Tengine::Job::JobnetActual)
44
+ j11.ancestors.should == [actual, rjn0001]
45
+ j11.ancestors_until_expansion.should == [rjn0001]
46
+ j11.actual_server_name.should == "test_server1"
47
+ j11.actual_server.should_not == nil
48
+ j11.actual_credential_name.should == "test_credential1"
49
+ j11.actual_credential.should_not == nil
50
+ end
51
+ rjn0001.children[2].tap do |j12|
52
+ j12.name.should == "j12"
53
+ j12.name_path.should == "/rjn0008/rjn0001/j12"
54
+ j12.name_path_until_expansion.should == "/rjn0001/j12"
55
+ j12.should be_a(Tengine::Job::JobnetActual)
56
+ j12.ancestors.should == [actual, rjn0001]
57
+ j12.ancestors_until_expansion.should == [rjn0001]
58
+ end
59
+ rjn0001.children[3].tap{|j| j.should be_a(Tengine::Job::End)}
60
+ rjn0001.edges.length.should == 3
61
+ end
62
+ actual.children[2].tap do |rjn0002|
63
+ rjn0002.should be_a(Tengine::Job::JobnetActual)
64
+ rjn0002.name.should == "rjn0002"
65
+ rjn0002.name_path.should == "/rjn0008/rjn0002"
66
+ rjn0002.name_path_until_expansion.should == "/rjn0002"
67
+ rjn0002.was_expansion.should == true
68
+ rjn0002.ancestors.should == [actual]
69
+ rjn0002.ancestors_until_expansion.should == []
70
+ rjn0002.children.length.should == 6
71
+ rjn0002.children[0].tap{|j| j.should be_a(Tengine::Job::Start)}
72
+ rjn0002.children[1].tap{|j| j.should be_a(Tengine::Job::Fork)}
73
+ rjn0002.children[2].tap do |j11|
74
+ j11.name.should == "j11"
75
+ j11.name_path.should == "/rjn0008/rjn0002/j11"
76
+ j11.name_path_until_expansion.should == "/rjn0002/j11"
77
+ j11.should be_a(Tengine::Job::JobnetActual)
78
+ j11.ancestors.should == [actual, rjn0002]
79
+ j11.ancestors_until_expansion.should == [rjn0002]
80
+ end
81
+ rjn0002.children[3].tap do |j12|
82
+ j12.name.should == "j12"
83
+ j12.name_path.should == "/rjn0008/rjn0002/j12"
84
+ j12.name_path_until_expansion.should == "/rjn0002/j12"
85
+ j12.should be_a(Tengine::Job::JobnetActual)
86
+ j12.ancestors.should == [actual, rjn0002]
87
+ j12.ancestors_until_expansion.should == [rjn0002]
88
+ end
89
+ rjn0002.children[4].tap{|j| j.should be_a(Tengine::Job::Join)}
90
+ rjn0002.children[5].tap{|j| j.should be_a(Tengine::Job::End)}
91
+ rjn0002.edges.length.should == 6
92
+ end
93
+ actual.children[3].tap{|j| j.should be_a(Tengine::Job::End)}
94
+ end
95
+
96
+ end
97
+
98
+ context "複数のバージョンが混在する場合" do
99
+ before do
100
+ Tengine::Job::Vertex.delete_all
101
+ @jobnet1_ver1 = Rjn0001SimpleJobnetBuilder.new.create_template(:dsl_version => 1)
102
+ @jobnet2_ver1 = Rjn0002SimpleParallelJobnetBuilder.new.create_template(:dsl_version => 1)
103
+ @jobnet1_ver2 = Rjn0001SimpleJobnetBuilder.new.create_template(:dsl_version => 2)
104
+ @jobnet2_ver2 = Rjn0002SimpleParallelJobnetBuilder.new.create_template(:dsl_version => 2)
105
+ @jobnet1_ver3 = Rjn0001SimpleJobnetBuilder.new.create_template(:dsl_version => 3)
106
+ @jobnet2_ver3 = Rjn0002SimpleParallelJobnetBuilder.new.create_template(:dsl_version => 3)
107
+ builder = Rjn0008ExpansionFixture.new
108
+ @template = builder.create_template(:dsl_version => 2)
109
+ @ctx = builder.context
110
+ end
111
+
112
+ it { @template.child_by_name("rjn0001").root_jobnet_template.id.should == @jobnet1_ver2.id }
113
+ it { @template.child_by_name("rjn0002").root_jobnet_template.id.should == @jobnet2_ver2.id }
114
+ end
115
+
116
+ end
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe 'hadoop_job_run' do
5
+
6
+ context "rjn1004" do
7
+ before(:all) do
8
+ Tengine::Job::Vertex.delete_all
9
+ builder = Rjn1004HadoopJobInJobnetFixture.new
10
+ @root = builder.create_actual
11
+ @ctx = builder.context
12
+ @execution = Tengine::Job::Execution.create!({
13
+ :root_jobnet_id => @root.id,
14
+ })
15
+ end
16
+
17
+ Tengine::Job::JobnetActual.phase_keys.each do |phase_key|
18
+ context "hadoop_job_run1のphase_keyを#{phase_key}に設定する" do
19
+ before(:all) do
20
+ @ctx[:hadoop_job_run1].phase_key = phase_key
21
+ @root.save!
22
+ end
23
+
24
+ %w[
25
+ /rjn1004/hadoop_job_run1/hadoop_job1
26
+ /rjn1004/hadoop_job_run1/hadoop_job1/Map
27
+ /rjn1004/hadoop_job_run1/hadoop_job1/Reduce
28
+ /rjn1004/hadoop_job_run1/hadoop_job2
29
+ /rjn1004/hadoop_job_run1/hadoop_job2/Map
30
+ /rjn1004/hadoop_job_run1/hadoop_job2/Reduce
31
+ ].each do |name_path|
32
+ it "その子どものhadoop_job, Map, Reduceのphase_keyも#{phase_key}になる" do
33
+ @root.vertex_by_name_path(name_path).phase_key.should == phase_key
34
+ end
35
+ end
36
+ end
37
+
38
+ context "https://www.pivotaltracker.com/story/show/23329935" do
39
+ before(:all) do
40
+ @ctx[:hadoop_job_run1].stopped_at = Time.at(0)
41
+ @ctx[:hadoop_job_run1].stop_reason = "test test"
42
+ @root.save!
43
+ end
44
+
45
+ %w[
46
+ /rjn1004/hadoop_job_run1/hadoop_job1
47
+ /rjn1004/hadoop_job_run1/hadoop_job1/Map
48
+ /rjn1004/hadoop_job_run1/hadoop_job1/Reduce
49
+ /rjn1004/hadoop_job_run1/hadoop_job2
50
+ /rjn1004/hadoop_job_run1/hadoop_job2/Map
51
+ /rjn1004/hadoop_job_run1/hadoop_job2/Reduce
52
+ ].each do |name_path|
53
+ it "その子どものhadoop_job, Map, Reduceのstop_reasonもtest testになる" do
54
+ @root.vertex_by_name_path(name_path).stop_reason.should == "test test"
55
+ end
56
+ it "その子どものhadoop_job, Map, Reduceのstopped_atも0になる" do
57
+ @root.vertex_by_name_path(name_path).stopped_at.to_f.should == 0.0
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tengine::Job::Job do
4
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'tengine/rspec'
3
+
4
+ describe Tengine::Job::JobnetActual do
5
+
6
+ include Tengine::RSpec::Extension
7
+
8
+ target_dsl File.expand_path("../../../../lib/tengine/job/drivers/job_control_driver.rb", File.dirname(__FILE__))
9
+ driver :job_control_driver
10
+
11
+ before do
12
+ actual_document = {"_id"=>BSON::ObjectId('4ece649e39efe202d00001cb'), "created_at"=>"2011-11-24 14:04:01 UTC", "updated_at"=>"2011-11-24 14:04:01 UTC", "server_name"=>"test_server1", "credential_name"=>"test_credential1", "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"complicated_jobnet", "script"=>nil, "description"=>"complerated jobnet", "jobnet_type_cd"=>1, "category_id"=>BSON::ObjectId('4ea7eafd39efe2347400002e'), "version"=>33, "dsl_filepath"=>"1015_complicated_jobnet_1.rb", "dsl_lineno"=>7, "dsl_version"=>"20111124230401", "_type"=>"Tengine::Job::RootJobnetActual", "phase_cd"=>60, "template_id"=>BSON::ObjectId('4ece4ed139efe2160a000001'), "children"=>[{"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001cc'), "_type"=>"Tengine::Job::Start"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>"test_server1", "credential_name"=>"test_credential1", "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet1-1", "script"=>nil, "description"=>"i_jobnet1-1", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001cd'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "children"=>[{"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001ce'), "_type"=>"Tengine::Job::Start"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet1-1", "script"=>"$HOME/tengine_job_test.sh 5 jobnet1-1", "description"=>"i_jobnet1-1", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001cf'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "started_at"=>"2011-11-24 15:37:03 UTC", "executing_pid"=>"15836", "exit_status"=>"0", "finished_at"=>"2011-11-24 15:37:11 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001d0'), "_type"=>"Tengine::Job::End"}], "edges"=>[{"_id"=>BSON::ObjectId('4ece649e39efe202d00001d1'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001ce'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001cf')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001d2'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001cf'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001d0')}], "started_at"=>"2011-11-24 15:37:03 UTC", "finished_at"=>"2011-11-24 15:37:17 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>"test_server1", "credential_name"=>"test_credential1", "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet1-2", "script"=>nil, "description"=>"i_jobnet1-2", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001d3'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "children"=>[{"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001d4'), "_type"=>"Tengine::Job::Start"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet1-2", "script"=>"$HOME/tengine_job_test.sh 10 jobnet1-2", "description"=>"i_jobnet1-2", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001d5'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "started_at"=>"2011-11-24 15:37:03 UTC", "executing_pid"=>"16006", "exit_status"=>"0", "finished_at"=>"2011-11-24 15:37:18 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001d6'), "_type"=>"Tengine::Job::End"}], "edges"=>[{"_id"=>BSON::ObjectId('4ece649e39efe202d00001d7'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001d4'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001d5')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001d8'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001d5'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001d6')}], "started_at"=>"2011-11-24 15:37:03 UTC", "finished_at"=>"2011-11-24 15:37:19 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>"test_server1", "credential_name"=>"test_credential1", "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet1-3", "script"=>nil, "description"=>"i_jobnet1-3", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001d9'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>80, "children"=>[{"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001da'), "_type"=>"Tengine::Job::Start"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_job1-1", "script"=>"$HOME/tengine_job_test.sh 1 job1-1", "description"=>"i_job1-1", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001db'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "started_at"=>"2011-11-24 15:37:03 UTC", "executing_pid"=>"16170", "exit_status"=>"0", "finished_at"=>"2011-11-24 15:37:10 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_job1-2", "script"=>"$HOME/tengine_job_test.sh 1 job1-2", "description"=>"i_job1-2", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001dc'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "started_at"=>"2011-11-24 15:37:03 UTC", "executing_pid"=>"16334", "exit_status"=>"0", "finished_at"=>"2011-11-24 15:37:11 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_job1-3", "script"=>"$HOME/tengine_job_test.sh 1 job1-3", "description"=>"i_job1-3", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001dd'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "started_at"=>"2011-11-24 15:37:03 UTC", "executing_pid"=>"16499", "exit_status"=>"0", "finished_at"=>"2011-11-24 15:37:13 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_job2-1", "script"=>"$HOME/tengine_job_failure_test.sh 1 job2-1", "description"=>"i_job2-1", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001de'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>80, "started_at"=>"2011-11-24 15:37:03 UTC", "executing_pid"=>"16665", "exit_status"=>"1", "finished_at"=>"2011-11-24 15:37:14 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_job2-2", "script"=>"$HOME/tengine_job_test.sh 1 job2-2", "description"=>"i_job2-2", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001df'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "started_at"=>"2011-11-24 15:37:03 UTC", "executing_pid"=>"16830", "exit_status"=>"0", "finished_at"=>"2011-11-24 15:37:16 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_job2-0", "script"=>"$HOME/tengine_job_test.sh 1 job2-0", "description"=>"i_job2-0", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001e0'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>20}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_job3", "script"=>"$HOME/tengine_job_test.sh 1 job3", "description"=>"i_job3", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001e1'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>20}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001e2'), "_type"=>"Tengine::Job::Fork"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001e3'), "_type"=>"Tengine::Job::Join"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001e4'), "_type"=>"Tengine::Job::Join"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001e5'), "_type"=>"Tengine::Job::End"}], "edges"=>[{"_id"=>BSON::ObjectId('4ece649e39efe202d00001e6'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001da'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e2')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001e7'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001e2'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001db')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001e8'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001e2'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001dc')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001e9'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001e2'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001dd')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001ea'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001e2'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001de')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001eb'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001e2'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001df')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001ec'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001db'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e3')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001ed'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001dc'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e3')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001ee'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001dd'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e3')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001ef'), "phase_cd"=>50, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001e0'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e3')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001f0'), "phase_cd"=>50, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001e3'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e1')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001f1'), "phase_cd"=>50, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001de'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e4')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001f2'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001df'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e4')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001f3'), "phase_cd"=>50, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001e4'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e0')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001f4'), "phase_cd"=>50, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001e1'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001e5')}], "started_at"=>"2011-11-24 15:37:03 UTC", "finished_at"=>"2011-11-24 15:37:18 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>"test_server1", "credential_name"=>"test_credential1", "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet2-1", "script"=>nil, "description"=>"i_jobnet2-1", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001f5'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "children"=>[{"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001f6'), "_type"=>"Tengine::Job::Start"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet2-1", "script"=>"$HOME/tengine_job_test.sh 1 jobnet2-1", "description"=>"i_jobnet2-1", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001f7'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>40, "started_at"=>"2011-11-24 15:37:03 UTC", "executing_pid"=>"16995", "exit_status"=>"0", "finished_at"=>"2011-11-24 15:37:18 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001f8'), "_type"=>"Tengine::Job::End"}], "edges"=>[{"_id"=>BSON::ObjectId('4ece649e39efe202d00001f9'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001f6'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001f7')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d00001fa'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001f7'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001f8')}], "started_at"=>"2011-11-24 15:37:03 UTC", "finished_at"=>"2011-11-24 15:37:18 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>"test_server1", "credential_name"=>"test_credential1", "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet2-2", "script"=>nil, "description"=>"i_jobnet2-2", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001fb'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>60, "children"=>[{"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001fc'), "_type"=>"Tengine::Job::Start"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet2-2", "script"=>"$HOME/tengine_job_test.sh 1 jobnet2-2", "description"=>"i_jobnet2-2", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d00001fd'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>60, "started_at"=>"2011-11-24 15:37:04 UTC", "executing_pid"=>"17160"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d00001fe'), "_type"=>"Tengine::Job::End"}], "edges"=>[{"_id"=>BSON::ObjectId('4ece649e39efe202d00001ff'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001fc'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001fd')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000200'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001fd'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001fe')}], "started_at"=>"2011-11-24 15:37:03 UTC"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>"test_server1", "credential_name"=>"test_credential1", "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet2-0", "script"=>nil, "description"=>"i_jobnet2-0", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d0000201'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>20, "children"=>[{"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d0000202'), "_type"=>"Tengine::Job::Start"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet2-0", "script"=>"$HOME/tengine_job_test.sh 1 jobnet2-0", "description"=>"i_jobnet2-0", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d0000203'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>20}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d0000204'), "_type"=>"Tengine::Job::End"}], "edges"=>[{"_id"=>BSON::ObjectId('4ece649e39efe202d0000205'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d0000202'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d0000203')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000206'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d0000203'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d0000204')}]}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>"test_server1", "credential_name"=>"test_credential1", "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet3", "script"=>nil, "description"=>"i_jobnet3", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d0000207'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>20, "children"=>[{"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d0000208'), "_type"=>"Tengine::Job::Start"}, {"created_at"=>nil, "updated_at"=>nil, "server_name"=>nil, "credential_name"=>nil, "killing_signals"=>nil, "killing_signal_interval"=>nil, "name"=>"i_jobnet3", "script"=>"$HOME/tengine_job_test.sh 1 jobnet3", "description"=>"i_jobnet3", "jobnet_type_cd"=>1, "_id"=>BSON::ObjectId('4ece649e39efe202d0000209'), "_type"=>"Tengine::Job::JobnetActual", "phase_cd"=>20}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d000020a'), "_type"=>"Tengine::Job::End"}], "edges"=>[{"_id"=>BSON::ObjectId('4ece649e39efe202d000020b'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d0000208'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d0000209')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d000020c'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d0000209'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d000020a')}]}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d000020d'), "_type"=>"Tengine::Job::Fork"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d000020e'), "_type"=>"Tengine::Job::Join"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d000020f'), "_type"=>"Tengine::Job::Join"}, {"created_at"=>nil, "updated_at"=>nil, "_id"=>BSON::ObjectId('4ece649e39efe202d0000210'), "_type"=>"Tengine::Job::End"}], "edges"=>[{"_id"=>BSON::ObjectId('4ece649e39efe202d0000211'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001cc'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d000020d')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000212'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d000020d'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001cd')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000213'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d000020d'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001d3')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000214'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d000020d'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001d9')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000215'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d000020d'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001f5')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000216'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d000020d'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d00001fb')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000217'), "phase_cd"=>20, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001cd'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d000020e')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000218'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001d3'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d000020e')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d0000219'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001d9'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d000020e')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d000021a'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d0000201'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d000020e')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d000021b'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d000020e'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d0000207')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d000021c'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001f5'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d000020f')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d000021d'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d00001fb'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d000020f')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d000021e'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d000020f'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d0000201')}, {"_id"=>BSON::ObjectId('4ece649e39efe202d000021f'), "phase_cd"=>0, "origin_id"=>BSON::ObjectId('4ece649e39efe202d0000207'), "destination_id"=>BSON::ObjectId('4ece649e39efe202d0000210')}], "started_at"=>"2011-11-24 15:37:03 UTC"}
13
+
14
+ Tengine::Job::Vertex.delete_all
15
+ Tengine::Job::Vertex.collection.insert(actual_document)
16
+ @root = Tengine::Job::Vertex.first
17
+ @parent = @root.vertex_by_name_path("/complicated_jobnet/i_jobnet1-3")
18
+ @failure_job = @root.vertex_by_name_path("/complicated_jobnet/i_jobnet1-3/i_job2-1")
19
+ @execution = Tengine::Job::Execution.create!({
20
+ :root_jobnet_id => @root.id,
21
+ })
22
+ end
23
+
24
+ it do
25
+ @root.phase_key.should == :running
26
+ @root.element("i_jobnet1-1").phase_key.should == :success ; @root.element("next!i_jobnet2-1").phase_key.should == :active
27
+ @root.element("i_jobnet1-2").phase_key.should == :success ; @root.element("next!i_jobnet2-1").phase_key.should == :active
28
+ @parent.phase_key.should == :error
29
+ @parent.element("i_job1-1").phase_key.should == :success ; @parent.element("next!i_job1-1").phase_key.should == :transmitted
30
+ @parent.element("i_job1-2").phase_key.should == :success ; @parent.element("next!i_job1-2").phase_key.should == :transmitted
31
+ @parent.element("i_job1-3").phase_key.should == :success ; @parent.element("next!i_job1-3").phase_key.should == :transmitted
32
+ @parent.element("i_job2-1").phase_key.should == :error ; @parent.element("next!i_job2-1").phase_key.should == :closed
33
+ @parent.element("i_job2-2").phase_key.should == :success ; @parent.element("next!i_job2-2").phase_key.should == :transmitted
34
+ @parent.element("i_job2-0").phase_key.should == :initialized ; @parent.element("next!i_job2-0").phase_key.should == :closed
35
+ @parent.element("i_job3").phase_key.should == :initialized ; @parent.element("next!i_job3").phase_key.should == :closed
36
+ @root.element("i_jobnet2-1").phase_key.should == :success ; @root.element("next!i_jobnet2-1").phase_key.should == :active
37
+ @root.element("i_jobnet2-2").phase_key.should == :running ; @root.element("next!i_jobnet2-2").phase_key.should == :active
38
+ @root.element("i_jobnet2-0").phase_key.should == :initialized; @root.element("next!i_jobnet2-0").phase_key.should == :active
39
+ @root.element("i_jobnet3").phase_key.should == :initialized ; @root.element("next!i_jobnet3").phase_key.should == :active
40
+
41
+ tengine.should_not_fire
42
+
43
+ # D, [2011-11-25T00:37:19.301707 #15640] DEBUG -- : received an event #<Tengine::Event:0x000001019e5618
44
+ # @properties={"target_jobnet_id"=>"4ece649e39efe202d00001d9", "execution_id"=>"4ece649e39efe202d0000220", "root_jobnet_id"=>"4ece649e39efe202d00001cb"},
45
+ # @event_type_name="error.jobnet.job.tengine", @key="1e2aec50-f8e0-012e-4a45-482a140dece2",
46
+ # @source_name="job:cloud-dev-6.local/15640/4ece649e39efe202d00001cb/4ece649e39efe202d00001d9",
47
+ # @sender_name="cloud-dev-6.local/15640", @level=2, @occurred_at=2011-11-24 15:37:19 UTC>
48
+ tengine.receive("error.jobnet.job.tengine", :properties => {
49
+ :execution_id => @execution.id.to_s,
50
+ :root_jobnet_id => @root.id.to_s,
51
+ :target_jobnet_id => @parent.id.to_s,
52
+ })
53
+
54
+ @root.reload
55
+ @root.phase_key.should == :running
56
+ @root.element("i_jobnet1-1").phase_key.should == :success ; @root.element("next!i_jobnet2-1").phase_key.should == :active
57
+ @root.element("i_jobnet1-2").phase_key.should == :success ; @root.element("next!i_jobnet2-1").phase_key.should == :active
58
+ @parent.phase_key.should == :error
59
+ @parent.element("i_job1-1").phase_key.should == :success ; @parent.element("next!i_job1-1").phase_key.should == :transmitted
60
+ @parent.element("i_job1-2").phase_key.should == :success ; @parent.element("next!i_job1-2").phase_key.should == :transmitted
61
+ @parent.element("i_job1-3").phase_key.should == :success ; @parent.element("next!i_job1-3").phase_key.should == :transmitted
62
+ @parent.element("i_job2-1").phase_key.should == :error ; @parent.element("next!i_job2-1").phase_key.should == :closed
63
+ @parent.element("i_job2-2").phase_key.should == :success ; @parent.element("next!i_job2-2").phase_key.should == :transmitted
64
+ @parent.element("i_job2-0").phase_key.should == :initialized ; @parent.element("next!i_job2-0").phase_key.should == :closed
65
+ @parent.element("i_job3").phase_key.should == :initialized ; @parent.element("next!i_job3").phase_key.should == :closed
66
+ @root.element("i_jobnet2-1").phase_key.should == :success ; @root.element("next!i_jobnet2-1").phase_key.should == :active
67
+ @root.element("i_jobnet2-2").phase_key.should == :running ; @root.element("next!i_jobnet2-2").phase_key.should == :active
68
+ @root.element("i_jobnet2-0").phase_key.should == :initialized; @root.element("next!i_jobnet2-0").phase_key.should == :active
69
+ @root.element("i_jobnet3").phase_key.should == :initialized ; @root.element("next!i_jobnet3").phase_key.should == :closing
70
+ end
71
+
72
+ end
@@ -0,0 +1,175 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Tengine::Job::JobnetActual do
5
+
6
+ describe :human_phase_key do
7
+ human_phase_name_hash = {
8
+ :initialized=>"初期化済",
9
+ :ready=>"準備中",
10
+ :starting=>"開始中",
11
+ :running=>"実行中",
12
+ :dying=>"強制停止中",
13
+ :success=>"正常終了",
14
+ :error=>"エラー終了",
15
+ :stuck=>"状態不明",
16
+ :stopping_by_user => "強制停止中",
17
+ :stopped_by_user => "強制停止済",
18
+ :stopping_by_timeout => "タイムアウト強制停止中",
19
+ :stopped_by_timeout => "タイムアウト強制停止済",
20
+ }.freeze
21
+
22
+ before(:all) do
23
+ I18n.backend ||= I18n::Backend::Simple.new
24
+ @i18_locale_backup = I18n.locale
25
+ I18n.locale = :ja
26
+ I18n.backend.store_translations('ja',
27
+ 'selectable_attrs' => {'tengine/job/jobnet_actual' => {'human_phase_name' => human_phase_name_hash } })
28
+ end
29
+
30
+ after(:all) do
31
+ I18n.locale = @i18_locale_backup
32
+ end
33
+
34
+ (Tengine::Job::JobnetActual.phase_keys - [:dying, :error]).each do |phase_key|
35
+ context "#{phase_key.inspect}の場合" do
36
+ subject{ Tengine::Job::JobnetActual.new(:phase_key => phase_key) }
37
+ its(:human_phase_key){ should == phase_key } # 変わらない
38
+ its(:human_phase_name){ should == human_phase_name_hash[phase_key] }
39
+ end
40
+ end
41
+
42
+ context "phase_keyが:dyingの場合" do
43
+ subject{ Tengine::Job::JobnetActual.new(:phase_key => :dying) }
44
+ its(:human_phase_key){ should == :dying }
45
+ its(:human_phase_name){ should == human_phase_name_hash[:dying] }
46
+ context "stop_reasonがuser_stopならば" do
47
+ before{ subject.stop_reason = "user_stop" }
48
+ its(:human_phase_key){ should == :stopping_by_user }
49
+ its(:human_phase_name){ should == human_phase_name_hash[:stopping_by_user] }
50
+ end
51
+ context "stop_reasonがtimeoutならば" do
52
+ before{ subject.stop_reason = "timeout" }
53
+ its(:human_phase_key){ should == :stopping_by_timeout }
54
+ its(:human_phase_name){ should == human_phase_name_hash[:stopping_by_timeout] }
55
+ end
56
+ end
57
+
58
+ context "phase_keyが:errorの場合" do
59
+ subject{ Tengine::Job::JobnetActual.new(:phase_key => :error) }
60
+ its(:human_phase_key){ should == :error }
61
+ its(:human_phase_name){ should == human_phase_name_hash[:error] }
62
+ context "stop_reasonがuser_stopならば" do
63
+ before{ subject.stop_reason = "user_stop" }
64
+ its(:human_phase_key){ should == :stopped_by_user }
65
+ its(:human_phase_name){ should == human_phase_name_hash[:stopped_by_user] }
66
+ end
67
+ context "stop_reasonがtimeoutならば" do
68
+ before{ subject.stop_reason = "timeout" }
69
+ its(:human_phase_key){ should == :stopped_by_timeout }
70
+ its(:human_phase_name){ should == human_phase_name_hash[:stopped_by_timeout] }
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "reset rjn0010" do
76
+ # in [rjn0010]
77
+ # |-----e2----->(j11)-----e4----->|
78
+ # [S1]--e1-->[F1] [J1]--e7-->[E1]
79
+ # |--e3-->(j12)--e5-->(j13)--e6-->|
80
+ before do
81
+ Tengine::Job::Vertex.delete_all
82
+ builder = Rjn00102jobsAnd1jobParallelJobnetBuilder.new
83
+ @root = builder.create_actual
84
+ @ctx = builder.context
85
+ @execution = Tengine::Job::Execution.create!({
86
+ :root_jobnet_id => @root.id,
87
+ })
88
+ @base_props = {
89
+ :execution_id => @execution.id.to_s,
90
+ :root_jobnet_id => @root.id.to_s,
91
+ :target_jobnet_id => @root.id.to_s,
92
+ }
93
+ mock_event = mock(:event)
94
+ mock_event.stub(:[]).with(:execution_id).and_return(@execution.id.to_s)
95
+ @signal = Tengine::Job::Signal.new(mock_event)
96
+ end
97
+
98
+ shared_examples_for "全て再実行するためにrootをリセット" do
99
+ it "全てのedgeとvetexは初期化される" do
100
+ @root.reset(@signal)
101
+ @root.save!
102
+ @root.reload
103
+ [:root, :j11, :j12, :j13].each{|j| [j, @ctx[j].phase_key].should == [j, :initialized]}
104
+ @root.edges.each{|edge| edge.phase_key.should == :active }
105
+ end
106
+ end
107
+
108
+ context "全て正常終了した後に" do
109
+ before do
110
+ [:root, :j11, :j12, :j13].each{|j| @ctx[j].phase_key = :success}
111
+ @root.edges.each{|edge| edge.phase_key = :transmitted }
112
+ @root.save!
113
+ end
114
+
115
+ it_should_behave_like "全て再実行するためにrootをリセット"
116
+
117
+ it "一部再実行の為にreset" do
118
+ @ctx[:j12].reset(@signal)
119
+ @root.save!
120
+ @root.reload
121
+ [:root, :j11].each{|j| @ctx[j].phase_key.should == :success}
122
+ [:j12, :j13].each{|j| @ctx[j].phase_key.should == :initialized}
123
+ [:e1, :e2, :e3, :e4].each{|n| @ctx[n].phase_key.should == :transmitted }
124
+ [:e5, :e6, :e7].each{|n| @ctx[n].phase_key.should == :active }
125
+ end
126
+ end
127
+
128
+ context "異常終了した後に" do
129
+ before do
130
+ [:root, :j12].each{|j| @ctx[j].phase_key = :error}
131
+ [:j11].each{|j| @ctx[j].phase_key = :success}
132
+ [:j13].each{|j| @ctx[j].phase_key = :initialized}
133
+ [:e1, :e2, :e3, :e4].each{|n| @ctx[n].phase_key = :transmitted }
134
+ [:e5, :e6, :e7].each{|n| @ctx[n].phase_key = :active }
135
+ @root.save!
136
+ end
137
+
138
+ it_should_behave_like "全て再実行するためにrootをリセット"
139
+
140
+ it "j11をreset" do
141
+ @ctx[:j11].reset(@signal)
142
+ @root.save!
143
+ @root.reload
144
+ [:root, :j12].each{|j| [j, @ctx[j].phase_key].should == [j, :error]}
145
+ [:j11, :j13].each{|j| @ctx[j].phase_key.should == :initialized}
146
+ [:e1, :e2, :e3].each{|n| @ctx[n].phase_key.should == :transmitted }
147
+ [:e4, :e5, :e6, :e7].each{|n| @ctx[n].phase_key.should == :active }
148
+ end
149
+
150
+ it "j12をreset" do
151
+ @ctx[:j12].reset(@signal)
152
+ @root.save!
153
+ @root.reload
154
+ [:root, ].each{|j| [j, @ctx[j].phase_key].should == [j, :error]}
155
+ [:j11, ].each{|j| @ctx[j].phase_key.should == :success}
156
+ [:j12, :j13].each{|j| @ctx[j].phase_key.should == :initialized}
157
+ [:e1, :e2, :e3, :e4].each{|n| @ctx[n].phase_key.should == :transmitted }
158
+ [:e5, :e6, :e7].each{|n| @ctx[n].phase_key.should == :active }
159
+ end
160
+
161
+ it "j13をreset" do
162
+ @ctx[:j13].reset(@signal)
163
+ @root.save!
164
+ @root.reload
165
+ [:root, :j12, ].each{|j| [j, @ctx[j].phase_key].should == [j, :error]}
166
+ [:j11, ].each{|j| @ctx[j].phase_key.should == :success}
167
+ [:j13].each{|j| @ctx[j].phase_key.should == :initialized}
168
+ [:e1, :e2, :e3, :e4].each{|n| @ctx[n].phase_key.should == :transmitted }
169
+ [:e5, :e6, :e7].each{|n| @ctx[n].phase_key.should == :active }
170
+ end
171
+ end
172
+
173
+
174
+ end
175
+ end
@@ -0,0 +1,399 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Tengine::Job::Jobnet do
5
+
6
+ context "基本機能" do
7
+ before do
8
+ @j1000 = Tengine::Job::JobnetTemplate.new(:name => "j1000").with_start
9
+ @j1000.children << @j1100 = Tengine::Job::JobnetTemplate.new(:name => "j1100").with_start
10
+ @j1100.children << @j1110 = Tengine::Job::JobnetTemplate.new(:name => "j1110", :script => "j1110.sh")
11
+ @j1100.children << @j1120 = Tengine::Job::JobnetTemplate.new(:name => "j1120", :script => "j1120.sh")
12
+ @j1000.children << @j1200 = Tengine::Job::JobnetTemplate.new(:name => "j1200").with_start
13
+ @j1200.children << @j1210 = Tengine::Job::JobnetTemplate.new(:name => "j1210").with_start
14
+ @j1210.children << @j1211 = Tengine::Job::JobnetTemplate.new(:name => "j1211", :script => "j1211.sh")
15
+ @j1210.children << @j1212 = Tengine::Job::JobnetTemplate.new(:name => "j1212", :script => "j1212.sh")
16
+ @j1200.children << @j1220 = Tengine::Job::JobnetTemplate.new(:name => "j1220").with_start
17
+ @j1220.children << @j1221 = Tengine::Job::JobnetTemplate.new(:name => "j1221", :script => "j1221.sh")
18
+ @j1220.children << @j1222 = Tengine::Job::JobnetTemplate.new(:name => "j1222", :script => "j1222.sh")
19
+ @j1000.prepare_end
20
+ @j1100.prepare_end
21
+ @j1200.prepare_end
22
+ @j1210.prepare_end
23
+ @j1220.prepare_end
24
+ @j1000.build_sequencial_edges
25
+ @j1100.build_sequencial_edges
26
+ @j1200.build_sequencial_edges
27
+ @j1210.build_sequencial_edges
28
+ @j1220.build_sequencial_edges
29
+ @j1000.save!
30
+ end
31
+
32
+ name_to_name_path = {
33
+ 'j1000' => '/j1000',
34
+ 'j1100' => '/j1000/j1100',
35
+ 'j1110' => '/j1000/j1100/j1110',
36
+ 'j1120' => '/j1000/j1100/j1120',
37
+ 'j1200' => '/j1000/j1200',
38
+ 'j1210' => '/j1000/j1200/j1210',
39
+ 'j1211' => '/j1000/j1200/j1210/j1211',
40
+ 'j1212' => '/j1000/j1200/j1210/j1212',
41
+ 'j1220' => '/j1000/j1200/j1220',
42
+ 'j1221' => '/j1000/j1200/j1220/j1221',
43
+ 'j1222' => '/j1000/j1200/j1220/j1222',
44
+ }
45
+
46
+ describe :name_path do
47
+ name_to_name_path.each do |node_name, name_path|
48
+ context "#{node_name}'s name_path" do
49
+ subject{ instance_variable_get(:"@#{node_name}") }
50
+ its(:name_path){ should == name_path}
51
+ end
52
+ end
53
+ end
54
+
55
+ describe 'find_descendant系' do
56
+ all_node_names = %w[j1000 j1100 j1110 j1120 j1200 j1210 j1211 j1212 j1220 j1221 j1222]
57
+
58
+ context "find_descendant*メソッドではルートはルート自身を見つけることができない" do
59
+ it :find_desendant do
60
+ root = @j1000
61
+ root.find_descendant(root.id).should be_nil
62
+ end
63
+
64
+ it :find_desendant_by_name_path do
65
+ root = @j1000
66
+ root.find_descendant_by_name_path('/j1000').should be_nil
67
+ end
68
+ end
69
+
70
+ context "vertex*メソッドではルートはルート自身を見つけることができる" do
71
+ it :vertex do
72
+ root = @j1000
73
+ root.vertex(root.id).should == root
74
+ end
75
+
76
+ it :vertex_by_name_path do
77
+ root = @j1000
78
+ root.vertex_by_name_path('/j1000').should == root
79
+ end
80
+ end
81
+
82
+ [:find_descendant, :vertex].each do |method_name|
83
+ by_name_path_method_name = :"#{method_name}_by_name_path"
84
+
85
+ (all_node_names -%w[j1000]).each do |node_name|
86
+ context "ルートから#{node_name}を見つけることができる" do
87
+ context method_name do
88
+ it "BSON::ObjectId" do
89
+ root = @j1000
90
+ node = instance_variable_get(:"@#{node_name}")
91
+ actual = root.send(method_name, node.id)
92
+ actual.id.should == node.id
93
+ actual.name.should == node.name
94
+ end
95
+
96
+ it "String" do
97
+ root = @j1000
98
+ node = instance_variable_get(:"@#{node_name}")
99
+ actual = root.send(method_name, node.id.to_s)
100
+ actual.id.should == node.id
101
+ actual.name.should == node.name
102
+ end
103
+ end
104
+
105
+ it by_name_path_method_name do
106
+ root = @j1000
107
+ node = instance_variable_get(:"@#{node_name}")
108
+ actual = root.send(by_name_path_method_name, name_to_name_path[node_name])
109
+ actual.id.should == node.id
110
+ actual.name.should == node.name
111
+ end
112
+ end
113
+ end
114
+
115
+ (all_node_names -%w[j1000 j1100 j1110 j1120 j1200]).each do |node_name|
116
+ context "j1200から#{node_name}を見つけることができる" do
117
+ it :find_descendant do
118
+ base = @j1200
119
+ node = instance_variable_get(:"@#{node_name}")
120
+ actual = base.send(method_name, node.id)
121
+ actual.id.should == node.id
122
+ actual.name.should == node.name
123
+ end
124
+
125
+ it :find_descendant_by_name_path do
126
+ base = @j1200
127
+ node = instance_variable_get(:"@#{node_name}")
128
+ actual = base.send(by_name_path_method_name, name_to_name_path[node_name])
129
+ actual.id.should == node.id
130
+ actual.name.should == node.name
131
+ end
132
+
133
+ end
134
+ end
135
+
136
+ %w[j1000 j1100 j1110 j1120].each do |node_name|
137
+ context "j1200から#{node_name}をidで見つけることはできない" do
138
+ it :find_descendant do
139
+ base = @j1200
140
+ node = instance_variable_get(:"@#{node_name}")
141
+ base.send(method_name, node.id).should == nil
142
+ end
143
+ end
144
+
145
+ context "j1200から#{node_name}を#{name_to_name_path[node_name].inspect}で見つけることができる" do
146
+ it :find_descendant_by_name_path do
147
+ base = @j1200
148
+ node = instance_variable_get(:"@#{node_name}")
149
+ base.send(by_name_path_method_name, name_to_name_path[node_name]).id.should == node.id
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ context "j1200からj1200を見つけることはできない" do
156
+ it :find_descendant do
157
+ @j1200.find_descendant(@j1200.id).should == nil
158
+ end
159
+
160
+ it :find_descendant_by_name_path do
161
+ @j1200.find_descendant_by_name_path(@j1200.name_path).should == nil
162
+ end
163
+
164
+ it :vertex do
165
+ @j1200.vertex(@j1200.id).should == @j1200
166
+ end
167
+
168
+ it :vertex_by_name_path do
169
+ @j1200.vertex_by_name_path(@j1200.name_path).should == @j1200
170
+ end
171
+ end
172
+ end
173
+
174
+ describe :find_descendant_edge do
175
+ before do
176
+ @j1000_start = @j1000.edges[0] # to j1100
177
+ @j1100_next = @j1000.edges[1] # to j1200
178
+ @j1200_next = @j1000.edges[2] # to j1000's end
179
+
180
+ @j1100_start = @j1100.edges[0] # to j1110
181
+ @j1110_next = @j1100.edges[1] # to j1120
182
+ @j1120_next = @j1100.edges[2] # to j1100's end
183
+
184
+ @j1200_start = @j1200.edges[0] # to j1210
185
+ @j1210_next = @j1200.edges[1] # to j1220
186
+ @j1220_next = @j1200.edges[2] # to j1200's end
187
+
188
+ @j1210_start = @j1210.edges[0] # to j1211
189
+ @j1211_next = @j1210.edges[1] # to j1212
190
+ @j1212_next = @j1210.edges[2] # to j1210's end
191
+
192
+ @j1220_start = @j1220.edges[0] # to j1221
193
+ @j1221_next = @j1220.edges[1] # to j1222
194
+ @j1222_next = @j1220.edges[2] # to j1220's end
195
+ end
196
+
197
+ edge_names = %w[
198
+ j1000_start j1100_next j1200_next
199
+ j1100_start j1110_next j1120_next
200
+ j1200_start j1210_next j1220_next
201
+ j1210_start j1211_next j1212_next
202
+ j1220_start j1221_next j1222_next
203
+ ]
204
+
205
+ edge_names.each do |edge_name|
206
+ context "edge_name check" do
207
+ case edge_name
208
+ when /_start$/ then
209
+
210
+ it "should be the edge from start to other" do
211
+ owner_name = edge_name.sub(/_start$/, '')
212
+ owner = instance_variable_get(:"@#{owner_name}")
213
+ start = owner.children.first
214
+ edge = instance_variable_get(:"@#{edge_name}")
215
+ edge.origin_id.should == start.id
216
+ end
217
+
218
+ when /_next$/ then
219
+
220
+ it "should be the edge from vertex to other" do
221
+ origin_name = edge_name.sub(/_next$/, '')
222
+ origin = instance_variable_get(:"@#{origin_name}")
223
+ edge = instance_variable_get(:"@#{edge_name}")
224
+ edge.origin_id.should == origin.id
225
+ owner = origin.parent
226
+ edge.owner.id.should == owner.id
227
+ end
228
+
229
+ end
230
+ end
231
+ end
232
+
233
+ edge_names.each do |edge_name|
234
+ it "ルートからエッジ#{edge_name}を参照できます" do
235
+ edge = instance_variable_get(:"@#{edge_name}")
236
+ found = @j1000.find_descendant_edge(edge.id)
237
+ found.id.should == edge.id
238
+ end
239
+ end
240
+
241
+ end
242
+
243
+ describe "vertex_by_name_path" do
244
+ {
245
+ :@j1000 => {
246
+ :@j1000 => ['/j1000', '.'],
247
+ :@j1100 => ['/j1000', '..'],
248
+ :@j1110 => ['/j1000', '../..'],
249
+ :@j1200 => ['/j1000', '..'],
250
+ },
251
+ :@j1100 => {
252
+ :@j1000 => ['/j1000/j1100', 'j1100'],
253
+ :@j1100 => ['/j1000/j1100', '.'],
254
+ :@j1110 => ['/j1000/j1100', '..'],
255
+ :@j1200 => ['/j1000/j1100', '../j1100'],
256
+ :@j1210 => ['/j1000/j1100', '../../j1100'],
257
+ },
258
+ :@j1110 => {
259
+ :@j1000 => ['/j1000/j1100/j1110', 'j1100/j1110'],
260
+ :@j1100 => ['/j1000/j1100/j1110', 'j1110'],
261
+ :@j1110 => ['/j1000/j1100/j1110', '.'],
262
+ :@j1200 => ['/j1000/j1100/j1110', '../j1100/j1110'],
263
+ :@j1210 => ['/j1000/j1100/j1110', '../../j1100/j1110'],
264
+ },
265
+ }.each do |target, hash|
266
+ hash.each do |origin, name_paths|
267
+ name_paths.each do |name_path|
268
+ it "#{target.inspect}を#{origin.inspect}から#{name_path}として参照する" do
269
+ job = instance_variable_get(origin)
270
+ job.vertex_by_name_path(name_path).should == instance_variable_get(target)
271
+ end
272
+ end
273
+ end
274
+ end
275
+ end
276
+
277
+ context "vertex_by_name_path for finally" do
278
+ before do
279
+ Tengine::Job::Vertex.delete_all
280
+ builder = Rjn0012NestedAndFinallyBuilder.new
281
+ @root = builder.create_template
282
+ @ctx = builder.context
283
+ end
284
+
285
+ it "finallyも検索可能" do
286
+ @root.vertex_by_name_path("/rjn0012/j1000/finally").should == @ctx[:j1f00]
287
+ @root.vertex_by_name_path("/rjn0012/j1000/finally/finally").should == @ctx[:j1ff0]
288
+ @root.vertex_by_name_path("/rjn0012/finally").should == @ctx[:jf000]
289
+ @root.vertex_by_name_path("/rjn0012/j1000/finally/start").should == @ctx[:S5]
290
+ @root.vertex_by_name_path("/rjn0012/j1000/finally/finally/start").should == @ctx[:S7]
291
+ @root.vertex_by_name_path("/rjn0012/finally/start").should == @ctx[:S9]
292
+ end
293
+
294
+ [
295
+ "/rjn0012/j1000/finally",
296
+ "/rjn0012/j1000/finally/finally",
297
+ "/rjn0012/finally",
298
+ "/rjn0012/j1000/finally/start",
299
+ "/rjn0012/j1000/finally/finally/start",
300
+ "/rjn0012/finally/start",
301
+ ].each do |name_path|
302
+ it name_path do
303
+ @root.vertex_by_name_path(name_path).name_path.should == name_path
304
+ end
305
+ end
306
+
307
+ it "endをchild_by_nameで参照できる" do
308
+ @root.child_by_name('end').tap do |_end1|
309
+ _end1.should_not == nil
310
+ _end1.should == @root.end_vertex
311
+ end
312
+ end
313
+ end
314
+
315
+
316
+ context "child_by_name" do
317
+ before do
318
+ Tengine::Job::Vertex.delete_all
319
+ builder = Rjn0009TreeSequentialJobnetBuilder.new
320
+ @root = builder.create_template
321
+ @ctx = builder.context
322
+ end
323
+
324
+ it "endを検索できる" do
325
+ @root.child_by_name("end").should == @ctx[:E1]
326
+ @root.vertex_by_name_path("end").should == @ctx[:E1]
327
+ @root.vertex_by_name_path("/rjn0009/end").should == @ctx[:E1]
328
+ end
329
+ end
330
+ end
331
+
332
+
333
+ context "バリデーションエラーでraiseされる例外から原因を判断できるように" do
334
+ before do
335
+ @j1000 = Tengine::Job::JobnetTemplate.new(:name => "j1000").with_start
336
+ @j1000.children << @j1100 = Tengine::Job::JobnetTemplate.new(:name => "j1100").with_start
337
+ @j1100.children << @j1110 = Tengine::Job::JobnetTemplate.new(:name => "j1110", :script => "j1110.sh")
338
+ @j1100.children << @j1120 = Tengine::Job::JobnetTemplate.new(:name => "j1120", :script => "j1120.sh")
339
+ @j1000.prepare_end
340
+ @j1100.prepare_end
341
+ @j1000.build_sequencial_edges
342
+ # @j1100.build_sequencial_edges
343
+ @j1000.edges << @e1 = Tengine::Job::Edge.new(:origin_id => @j1000.start_vertex.id, :destination_id => @j1100.id)
344
+ @j1000.edges << @e2 = Tengine::Job::Edge.new(:origin_id => @j1110.id, :destination_id => @j1000.end_vertex.id)
345
+ @j1100.edges << @e3 = Tengine::Job::Edge.new(:origin_id => @j1100.start_vertex.id, :destination_id => @j1110.id)
346
+ @j1100.edges << @e4 = Tengine::Job::Edge.new(:origin_id => @j1110.id, :destination_id => @j1120.id)
347
+ @j1100.edges << @e5 = Tengine::Job::Edge.new(:origin_id => @j1120.id, :destination_id => @j1100.end_vertex.id)
348
+ end
349
+
350
+ it "save!" do
351
+ @e3.origin_id = nil # バリデーションエラーにする
352
+ begin
353
+ @j1000.save!
354
+ fail
355
+ rescue Mongoid::Errors::Validations => e
356
+ msg = "Origin can't be blank"
357
+ e.message.should =~ %r<edge\([0-9a-f]+\) from no origin to /j1000/j1100/j1110 #{msg}>
358
+ end
359
+ end
360
+
361
+ it "update_attributes!" do
362
+ @j1000.save!
363
+ begin
364
+ @e3.origin_id = nil # バリデーションエラーにする
365
+ @j1000.update_attributes!(:description => "test description")
366
+ fail
367
+ rescue Mongoid::Errors::Validations => e
368
+ msg = "Origin can't be blank"
369
+ e.message.should =~ %r<edge\([0-9a-f]+\) from no origin to /j1000/j1100/j1110 #{msg}>
370
+ end
371
+ end
372
+
373
+ it "create!" do
374
+ begin
375
+ Tengine::Job::RootJobnetTemplate.create!(:name => nil)
376
+ fail
377
+ rescue Mongoid::Errors::Validations => e
378
+ msg = "Name can't be blank"
379
+ e.message.should =~ %r</ #{msg}>
380
+ end
381
+ end
382
+
383
+ end
384
+
385
+ describe :error_messages do
386
+ context "デフォルト" do
387
+ subject{ Tengine::Job::JobnetActual.new }
388
+ its(:error_messages){ should == nil }
389
+ its(:error_messages_text){ should == "" }
390
+ end
391
+
392
+ context "複数音メッセージ" do
393
+ subject{ Tengine::Job::JobnetActual.new(:error_messages => ["foo", "bar"]) }
394
+ its(:error_messages){ should == ["foo", "bar"] }
395
+ its(:error_messages_text){ should == "foo\nbar" }
396
+ end
397
+ end
398
+
399
+ end