tengine_core 0.5.39 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. data/Gemfile +1 -37
  2. data/Gemfile.lock +59 -61
  3. data/README.md +8 -6
  4. data/bin/create_indexes_for_tengine_core +18 -0
  5. data/bin/tengined +3 -3
  6. data/examples/list.txt +36 -0
  7. data/examples/uc08_if_both_a_and_b_occurs.rb +7 -1
  8. data/examples/uc20_fire_with_properties.rb +19 -0
  9. data/examples/uc21_fire_with_same_key.rb +23 -0
  10. data/examples/uc22_fire_with_source_name.rb +17 -0
  11. data/examples/uc23_fire_with_level.rb +19 -0
  12. data/examples/uc24_fire_with_level_key.rb +19 -0
  13. data/examples/uc30_local_variables.rb +28 -0
  14. data/examples/uc31_instance_variables.rb +35 -0
  15. data/examples/uc32_class_variables.rb +20 -0
  16. data/examples/uc33_statics.rb +20 -0
  17. data/examples2/uc30_local_variables.rb +55 -0
  18. data/examples2/uc31_instance_variables.rb +46 -0
  19. data/examples2/uc32_class_variables.rb +22 -0
  20. data/examples2/uc33_statics.rb +23 -0
  21. data/lib/tengine/core/bootstrap.rb +1 -1
  22. data/lib/tengine/core/config/atd.rb +0 -3
  23. data/lib/tengine/core/config/core.rb +21 -20
  24. data/lib/tengine/core/config/heartbeat_watcher.rb +0 -3
  25. data/lib/tengine/core/driveable.rb +34 -12
  26. data/lib/tengine/core/driver.rb +22 -9
  27. data/lib/tengine/core/dsl_evaluator.rb +2 -15
  28. data/lib/tengine/core/dsl_filter_def.rb +40 -0
  29. data/lib/tengine/core/dsl_loader.rb +1 -1
  30. data/lib/tengine/core/event.rb +44 -29
  31. data/lib/tengine/core/event/finder.rb +1 -1
  32. data/lib/tengine/core/event_exception_reportable.rb +7 -10
  33. data/lib/tengine/core/event_wrapper.rb +1 -1
  34. data/lib/tengine/core/find_by_name.rb +1 -1
  35. data/lib/tengine/core/handler.rb +14 -4
  36. data/lib/tengine/core/handler_path.rb +1 -1
  37. data/lib/tengine/core/heartbeat_watcher.rb +3 -2
  38. data/lib/tengine/core/kernel.rb +22 -6
  39. data/lib/tengine/core/mongoid_fix.rb +2 -1
  40. data/lib/tengine/core/mutex.rb +22 -8
  41. data/lib/tengine/core/optimistic_lock.rb +6 -6
  42. data/lib/tengine/core/safe_updatable.rb +24 -26
  43. data/lib/tengine/core/schedule.rb +2 -2
  44. data/lib/tengine/core/scheduler.rb +5 -4
  45. data/lib/tengine/core/session.rb +14 -0
  46. data/lib/tengine/core/session_wrapper.rb +20 -4
  47. data/lib/tengine/core/setting.rb +3 -3
  48. data/lib/tengine/rspec/extension.rb +6 -8
  49. metadata +156 -171
  50. data/.document +0 -5
  51. data/.rspec +0 -1
  52. data/Rakefile +0 -44
  53. data/VERSION +0 -1
  54. data/lib/tengine/core/connection_test/.gitignore +0 -1
  55. data/spec/factories/tengine_core_drivers.rb +0 -10
  56. data/spec/factories/tengine_core_events.rb +0 -14
  57. data/spec/factories/tengine_core_handler_paths.rb +0 -9
  58. data/spec/factories/tengine_core_handlers.rb +0 -9
  59. data/spec/factories/tengine_core_sessions.rb +0 -9
  60. data/spec/mongoid.yml +0 -35
  61. data/spec/spec_helper.rb +0 -48
  62. data/spec/support/mongo_index_key_log.rb +0 -91
  63. data/spec/tengine/core/bootstrap_spec.rb +0 -278
  64. data/spec/tengine/core/bugfix/bind_dsl_file_in_multi_byte_dir_spec.rb +0 -21
  65. data/spec/tengine/core/bugfix/enabled_on_activation_spec.rb +0 -112
  66. data/spec/tengine/core/bugfix/receive_event_spec.rb +0 -133
  67. data/spec/tengine/core/bugfix/use_dsl_version_method.rb +0 -12
  68. data/spec/tengine/core/bugfix/use_dsl_version_method_spec.rb +0 -28
  69. data/spec/tengine/core/bugfix/use_event_in_handler_dsl.rb +0 -11
  70. data/spec/tengine/core/bugfix//351/235/236ACSII/343/201/256/343/203/206/343/202/231/343/202/243/343/203/254/343/202/257/343/203/210/343/203/252/345/220/215/source_location_encoding.rb +0 -35
  71. data/spec/tengine/core/bugfix//351/235/236ACSII/343/201/256/343/203/206/343/202/231/343/202/243/343/203/254/343/202/257/343/203/210/343/203/252/345/220/215//351/235/236ASCII/343/201/256/343/203/225/343/202/241/343/202/244/343/203/253/345/220/215_dsl.rb +0 -38
  72. data/spec/tengine/core/bugfix//351/235/236ACSII/343/201/256/343/203/207/343/202/243/343/203/254/343/202/257/343/203/210/343/203/252/345/220/215/source_location_encoding.rb +0 -35
  73. data/spec/tengine/core/bugfix//351/235/236ACSII/343/201/256/343/203/207/343/202/243/343/203/254/343/202/257/343/203/210/343/203/252/345/220/215//351/235/236ASCII/343/201/256/343/203/225/343/202/241/343/202/244/343/203/253/345/220/215_dsl.rb +0 -38
  74. data/spec/tengine/core/config/atd_spec.rb +0 -62
  75. data/spec/tengine/core/config/core_spec.rb +0 -479
  76. data/spec/tengine/core/config/heartbeat_watcher_spec.rb +0 -62
  77. data/spec/tengine/core/config/syntax_error_in_erb.yml.erb +0 -13
  78. data/spec/tengine/core/config/wrong_category_name.yml.erb +0 -13
  79. data/spec/tengine/core/config/wrong_field_name.yml.erb +0 -12
  80. data/spec/tengine/core/config/wrong_yaml.yml.erb +0 -13
  81. data/spec/tengine/core/config_spec/another_port.yml +0 -54
  82. data/spec/tengine/core/config_spec/config_with_dir_absolute_load_path.yml +0 -16
  83. data/spec/tengine/core/config_spec/config_with_dir_relative_load_path.yml +0 -16
  84. data/spec/tengine/core/config_spec/config_with_file_absolute_load_path.yml +0 -16
  85. data/spec/tengine/core/config_spec/config_with_file_relative_load_path.yml +0 -16
  86. data/spec/tengine/core/config_spec/log_config_spec.rb +0 -245
  87. data/spec/tengine/core/driveable_spec.rb +0 -240
  88. data/spec/tengine/core/driver_spec.rb +0 -159
  89. data/spec/tengine/core/dsl_loader_spec.rb +0 -172
  90. data/spec/tengine/core/dsls/uc08_if_both_a_and_b_occurs_spec.rb +0 -35
  91. data/spec/tengine/core/dsls/uc10_if_the_event_occurs_at_the_server_spec.rb +0 -58
  92. data/spec/tengine/core/dsls/uc50_commit_event_at_first_spec.rb +0 -29
  93. data/spec/tengine/core/dsls/uc52_commit_event_after_all_handler_submit_spec.rb +0 -33
  94. data/spec/tengine/core/dsls/uc52_never_commit_event_unless_all_handler_submit_spec.rb +0 -38
  95. data/spec/tengine/core/dsls/uc53_submit_outside_of_handler_spec.rb +0 -37
  96. data/spec/tengine/core/dsls/uc60_event_in_handler_spec.rb +0 -31
  97. data/spec/tengine/core/dsls/uc61_event_outside_of_handler_spec.rb +0 -37
  98. data/spec/tengine/core/dsls/uc62_session_in_driver_spec.rb +0 -36
  99. data/spec/tengine/core/dsls/uc63_session_outside_of_driver_spec.rb +0 -35
  100. data/spec/tengine/core/dsls/uc64_safety_countup_spec.rb +0 -134
  101. data/spec/tengine/core/dsls/uc70_driver_enabled_on_activation_spec.rb +0 -39
  102. data/spec/tengine/core/dsls/uc71_driver_disabled_on_activation_spec.rb +0 -36
  103. data/spec/tengine/core/dsls/uc72_setup_eventmachine_spec.rb +0 -39
  104. data/spec/tengine/core/dsls/uc80_raise_io_error_spec.rb +0 -53
  105. data/spec/tengine/core/dsls/uc81_raise_runtime_error_spec.rb +0 -49
  106. data/spec/tengine/core/event/finder_spec.rb +0 -136
  107. data/spec/tengine/core/event_exception_reportable_spec.rb +0 -33
  108. data/spec/tengine/core/event_spec.rb +0 -161
  109. data/spec/tengine/core/event_wrapper_spec.rb +0 -35
  110. data/spec/tengine/core/handler_path_spec.rb +0 -87
  111. data/spec/tengine/core/handler_spec.rb +0 -190
  112. data/spec/tengine/core/heartbeat_watcher_spec.rb +0 -131
  113. data/spec/tengine/core/io_to_logger_spec.rb +0 -30
  114. data/spec/tengine/core/kernel_spec.rb +0 -902
  115. data/spec/tengine/core/mongodb_spec.rb +0 -12
  116. data/spec/tengine/core/mongoid_fix_spec.rb +0 -52
  117. data/spec/tengine/core/mutex_spec.rb +0 -201
  118. data/spec/tengine/core/optimistic_lock_spec.rb +0 -55
  119. data/spec/tengine/core/scheculer_spec.rb +0 -121
  120. data/spec/tengine/core/selectable_attr_spec.rb +0 -30
  121. data/spec/tengine/core/session_spec.rb +0 -104
  122. data/spec/tengine/core/setting_spec.rb +0 -79
  123. data/spec/tengine/core_spec.rb +0 -13
  124. data/spec/tengine_spec.rb +0 -14
  125. data/tengine_core.gemspec +0 -251
  126. data/tmp/log/.gitignore +0 -1
  127. data/tmp/tengined_status/.gitignore +0 -1
@@ -1,902 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require 'spec_helper'
3
- require 'amqp'
4
- require 'eventmachine'
5
-
6
- # ログを黙らせたり喋らせたりする
7
- require 'amq/client'
8
- require 'mongoid'
9
- if $DEBUG
10
- require 'logger'
11
- AMQP::Session.logger = Tengine.logger = Mongoid.logger = Logger.new(STDERR)
12
- else
13
- AMQP::Session.logger = Tengine.logger = Mongoid.logger = Tengine::NullLogger.new
14
- end
15
-
16
- describe Tengine::Core::Kernel do
17
- before do
18
- Tengine::Core::Driver.delete_all
19
- Tengine::Core::HandlerPath.delete_all
20
- Tengine::Core::Event.delete_all
21
- end
22
-
23
- describe :start do
24
- # describe :bind, "handlerのblockをメモリ上で保持" do
25
- # before do
26
- # config = Tengine::Core::Config::Core.new({
27
- # :tengined => {
28
- # :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
29
- # },
30
- # })
31
- # @kernel = Tengine::Core::Kernel.new(config)
32
- # @driver = Tengine::Core::Driver.new(:name => "driver01", :version => config.dsl_version, :enabled => true)
33
- # @handler1 = @driver.handlers.new(:filepath => "uc01_execute_processing_for_event.rb", :lineno => 7, :event_type_names => ["event01"])
34
- # @driver.save!
35
- # end
36
-
37
- # it "event_type_nameからblockを検索することができる" do
38
- # @kernel.bind
39
- # @kernel.context.__block_for__(@handler1).should_not be_nil
40
- # end
41
-
42
- # context "拡張モジュールあり" do
43
- # before(:all) do
44
- # @ext_mod1 = Module.new{}
45
- # @ext_mod1.instance_eval do
46
- # def dsl_binder; self; end
47
- # end
48
- # Tengine.plugins.add(@ext_mod1)
49
- # end
50
-
51
- # it "Kernel#contextに拡張モジュールがextendされる" do
52
- # @kernel.bind
53
- # @kernel.context.__block_for__(@handler1).should_not be_nil
54
- # @kernel.context.should be_a(Tengine::Core::DslBinder)
55
- # @kernel.context.should be_a(@ext_mod1)
56
- # end
57
- # end
58
-
59
- # end
60
-
61
- describe :wait_for_activation, "activate待ち" do
62
- before do
63
- config = Tengine::Core::Config::Core.new({
64
- :tengined => {
65
- :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
66
- :wait_activation => true,
67
- :activation_timeout => 3,
68
- :activation_dir => File.expand_path('.', File.dirname(__FILE__)),
69
- },
70
- })
71
- @kernel = Tengine::Core::Kernel.new(config)
72
- @driver = Tengine::Core::Driver.new(:name => "driver01", :version => config.dsl_version, :enabled => true)
73
- @handler1 = @driver.handlers.new(:filepath => "uc01_execute_processing_for_event.rb", :lineno => 7, :event_type_names => ["event01"])
74
- @driver.save!
75
- @activation_file_path = "#{@kernel.config[:tengined][:activation_dir]}\/tengined_#{Process.pid}.activation"
76
- end
77
-
78
- after do
79
- FileUtils.rm_f(@activation_file_path)
80
- end
81
-
82
- it "activationファイルが生成されたらactivateされる" do
83
- @kernel.should_receive(:activate)
84
- t1 = Thread.new {
85
- @kernel.start
86
- }
87
- t2 = Thread.new {
88
- FileUtils.touch(@activation_file_path)
89
- }
90
- t1.join
91
- t2.join
92
- end
93
-
94
- it "activationファイルが生成されないままならタイムアウトになる" do
95
- lambda {
96
- @kernel.should_not_receive(:activate)
97
- @kernel.start
98
- }.should raise_error(Tengine::Core::ActivationTimeoutError, "activation file found timeout error.")
99
- end
100
- end
101
-
102
- describe :activate, "メッセージの受信を開始" do
103
- before do
104
- @header = AMQP::Header.new(@mock_channel, nil, {
105
- :routing_key => "",
106
- :content_type => "application/octet-stream",
107
- :priority => 0,
108
- :headers => { },
109
- :timestamp => Time.now,
110
- :type => "",
111
- :delivery_tag => 1,
112
- :redelivered => false,
113
- :exchange => "tengine_event_exchange",
114
- })
115
-
116
- config = Tengine::Core::Config::Core.new({
117
- :tengined => {
118
- :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
119
- :wait_activation => false,
120
- :confirmation_threshold => 'info'
121
- },
122
- :heartbeat => {
123
- :core => {
124
- :interval => 1024,
125
- :expire => 32768,
126
- },
127
- },
128
- })
129
- @kernel = Tengine::Core::Kernel.new(config)
130
- @driver = Tengine::Core::Driver.new(
131
- :name => "driver01", :version => config.dsl_version, :enabled => true)
132
- @handler1 = @driver.handlers.new(
133
- :filepath => "uc01_execute_processing_for_event.rb", :lineno => 7, :event_type_names => ["event01"])
134
- @driver.save!
135
- @event1 = Tengine::Core::Event.new(:event_type_name => :event01, :key => "uuid1", :sender_name => "localhost")
136
- @event1.save!
137
- end
138
-
139
- context "イベントの受信待ち状態になる" do
140
- before do
141
- # eventmachine と mq の mock を生成
142
- mock_mq = mock("mq")
143
- mock_sender = mock("sender")
144
- @kernel.stub(:mq).and_return(mock_mq)
145
- @kernel.stub(:sender).and_return(mock_sender)
146
- mock_sender.stub(:fire)
147
- mock_mq.stub(:initiate_termination).and_yield
148
- mock_mq.stub(:unsubscribe).and_yield
149
- mock_mq.stub(:stop).and_yield
150
- mock_mq.stub(:add_hook)
151
- mock_mq.stub(:subscribe).with(nil).with(:ack => true, :nowait => false, :confirm => an_instance_of(Proc)) do |h, b|
152
- h[:confirm].yield(mock("confirm-ok"))
153
- #b.yield(@header, :message)
154
- end
155
- # subscribe されていることを検証
156
- mock_mq.should_receive(:subscribe).with(:ack => true, :nowait => false, :confirm => an_instance_of(Proc))
157
- end
158
-
159
- it "heartbeatは有効にならない" do
160
- @kernel.config[:heartbeat][:core][:interval] = -1
161
- @kernel.should_receive(:setup_mq_connection)
162
- sender = mock(:sender)
163
- @kernel.stub(:sender).and_return(sender)
164
- sender.stub(:fire).with("finished.process.core.tengine", an_instance_of(Hash)).and_yield
165
- @kernel.start
166
- end
167
-
168
- it "heartbeatは有効になる" do
169
- @kernel.config[:heartbeat][:core][:interval] = 65535
170
- EM.should_receive(:add_periodic_timer).with(65535).and_yield
171
- sender = mock(:sender)
172
- @kernel.stub(:sender).and_return(sender)
173
- sender.stub(:fire).with("finished.process.core.tengine", an_instance_of(Hash)).and_yield
174
- sender.stub(:fire).with("core.heartbeat.tengine", an_instance_of(Hash))
175
- @kernel.start do
176
- @kernel.stop
177
- end
178
- end
179
-
180
- it "heartbeatが送られる" do
181
- @kernel.should_receive(:setup_mq_connection)
182
- EM.should_receive(:add_periodic_timer).with(1024).and_yield
183
- mock_sender = mock(:sender)
184
- @kernel.stub(:sender).and_return(mock_sender)
185
- mock_sender.stub(:fire).with("finished.process.core.tengine", an_instance_of(Hash)).and_yield
186
- mock_sender.stub(:fire).with("core.heartbeat.tengine", an_instance_of(Hash))
187
- @kernel.start
188
- end
189
- end
190
-
191
- context "発火されたイベントを登録できる" do
192
- before do
193
- # eventmachine と mq の mock を生成
194
- mock_mq = mock("mq")
195
- mock_sender = mock("sender")
196
- @kernel.stub(:mq).and_return(mock_mq)
197
- @kernel.stub(:sender).and_return(mock_sender)
198
- mock_sender.stub(:fire)
199
- mock_mq.stub(:initiate_termination).and_yield
200
- mock_mq.stub(:unsubscribe).and_yield
201
- mock_mq.stub(:stop).and_yield
202
- mock_mq.stub(:add_hook)
203
- mock_mq.stub(:subscribe).with(nil).with(:ack => true, :nowait => false, :confirm => an_instance_of(Proc)) do |h, b|
204
- h[:confirm].yield(mock("confirm-ok"))
205
- b.yield(@header, :message)
206
- end
207
-
208
- # subscribe してみる
209
- @mock_raw_event = mock(:row_event)
210
- Tengine::Event.should_receive(:parse).with(:message).and_return(@mock_raw_event)
211
-
212
- @header.should_receive(:ack)
213
- end
214
-
215
- it "confirmation_threshold以下なら登録されたイベントはconfirmedがtrue" do
216
- @mock_raw_event.stub!(:key).and_return("uniq_key")
217
- @mock_raw_event.stub!(:sender_name).and_return("localhost")
218
- @mock_raw_event.stub!(:attributes).and_return(:event_type_name => :foo, :key => "uniq_key", :level => Tengine::Event::LEVELS_INV[:info])
219
- @mock_raw_event.stub!(:level).and_return(Tengine::Event::LEVELS_INV[:info])
220
- @mock_raw_event.stub!(:event_type_name).and_return("foo")
221
- count = lambda{ Tengine::Core::Event.where(:event_type_name => :foo, :confirmed => true).count }
222
- expect{ @kernel.start { @kernel.stop } }.should change(count, :call).by(1) # イベントが登録されていることを検証
223
- end
224
-
225
- it "confirmation_threshold以下なら登録されたイベントはconfirmedがfalse" do
226
- @mock_raw_event.stub!(:key).and_return("uniq_key")
227
- @mock_raw_event.stub!(:sender_name).and_return("localhost")
228
- @mock_raw_event.stub!(:attributes).and_return(:event_type_name => :foo, :key => "uniq_key", :level => Tengine::Event::LEVELS_INV[:warn])
229
- @mock_raw_event.stub!(:level).and_return(Tengine::Event::LEVELS_INV[:warn])
230
- @mock_raw_event.stub!(:event_type_name).and_return("foo")
231
- count = lambda{ Tengine::Core::Event.where(:event_type_name => :foo, :confirmed => false).count }
232
- @kernel.should_receive(:setup_mq_connection)
233
- expect{ @kernel.start }.should change(count, :call).by(1) # イベントが登録されていることを検証
234
- end
235
- end
236
-
237
- context "イベントストアへの登録有無" do
238
- it "不正なフォーマットのメッセージの場合、イベントストアへ登録を行わずACKを返却" do
239
- @header.should_receive(:ack)
240
- @kernel.process_message(@header, "invalid format message").should_not be_true
241
- end
242
-
243
- it "https://www.pivotaltracker.com/story/show/22698533" do
244
- ev = Tengine::Event.new :key => "2498e870-11cd-012f-f8c0-48bcc89f84e1", :source_name => "localhost/8110", :sender_name => "localhost/8110", :level => 2, :occurred_at => Time.now, :properties => {}, :event_type_name => ""
245
- @header.should_receive(:reject)
246
- @kernel.process_message(@header, ev.to_json).should_not be_true
247
- end
248
-
249
- it "keyがnilのイベント場合、イベントストアへ登録を行わずACKを返却" do
250
- raw_event = Tengine::Event.new(:key => "", :sender_name => "another_host", :event_type_name => "event1")
251
- @header.should_receive(:ack)
252
- @kernel.process_message(@header, raw_event.to_json).should_not be_true
253
- end
254
-
255
- it "keyが同じ、sender_nameが異なる場合は、イベントストアへ登録を行わずREJECTを返却" do
256
- @header.should_receive(:reject)
257
- raw_event = Tengine::Event.new(:key => "uuid1", :sender_name => "another_host", :event_type_name => "event1")
258
- lambda {
259
- Tengine::Core::Event.create!(raw_event.attributes.update(:confirmed => (raw_event.level <= @kernel.config.confirmation_threshold)))
260
- }.should raise_error(Mongo::OperationFailure)
261
- @kernel.process_message(@header, raw_event.to_json).should_not be_true
262
- end
263
-
264
- it "keyが異なる場合は、イベントストアへ登録を行い、ACKを返却" do
265
- @header.should_receive(:ack)
266
- raw_event = Tengine::Event.new(:key => "uuid99", :sender_name => "another_host", :event_type_name => "event1")
267
- Tengine::Core::Event.should_receive(:create!).and_return(Tengine::Core::Event.new(raw_event.attributes))
268
- @kernel.process_message(@header, raw_event.to_json).should be_true
269
- end
270
- end
271
-
272
- context "イベント処理失敗イベントの発火" do
273
- before do
274
- # eventmachine と mq の mock を生成
275
- mock_mq = mock("mq")
276
- @kernel.stub(:mq).and_return(mock_mq)
277
- mock_mq.stub(:initiate_termination).and_yield
278
- mock_mq.stub(:unsubscribe).and_yield
279
- mock_mq.stub(:stop).and_yield
280
- mock_mq.stub(:add_hook)
281
- mock_mq.stub(:subscribe).with(nil).with(:ack => true, :nowait => false, :confirm => an_instance_of(Proc)) do |h, b|
282
- h[:confirm].yield(mock("confirm-ok"))
283
- b.yield(@header, :message)
284
- end
285
-
286
- # subscribe してみる
287
- @raw_event = Tengine::Event.new(:key => "uuid1", :sender_name => "localhost", :event_type_name => "event1")
288
- Tengine::Event.should_receive(:parse).with(:message).and_return(@raw_event)
289
- @header.should_receive(:ack)
290
- end
291
-
292
- it "既に登録されているイベントとkey, sender_nameが一致するイベントを受信した場合、発火" do
293
- mock_sender = mock(:sender)
294
- Tengine::Event::Sender.should_receive(:new).with(@kernel.mq).and_return(mock_sender)
295
- mock_sender.should_receive(:default_keep_connection=).with(true)
296
- mock_sender.should_receive(:fire).with("#{@raw_event.event_type_name}.failed.tengined",
297
- {
298
- :level => Tengine::Event::LEVELS_INV[:error],
299
- :properties => { :original_event => @raw_event }
300
- })
301
- mock_sender.stub(:fire).with("finished.process.core.tengine", an_instance_of(Hash)).and_yield
302
- @kernel.start { @kernel.stop }
303
- events = Tengine::Core::Event.where(:key => @raw_event.key, :sender_name => @raw_event.sender_name)
304
- events.count.should == 1
305
- end
306
- end
307
-
308
- it "イベント種別に対応したハンドラの処理を実行することができる" do
309
- # eventmachine と mq の mock を生成
310
- mock_mq = mock("mq")
311
- mock_sender = mock("sender")
312
- @kernel.stub(:mq).and_return(mock_mq)
313
- @kernel.stub(:sender).and_return(mock_sender)
314
- mock_sender.stub(:fire)
315
- mock_mq.stub(:initiate_termination).and_yield
316
- mock_mq.stub(:unsubscribe).and_yield
317
- mock_mq.stub(:stop).and_yield
318
- mock_mq.stub(:add_hook)
319
- mock_mq.stub(:subscribe).with(nil).with(:ack => true, :nowait => false, :confirm => an_instance_of(Proc)) do |h, b|
320
- h[:confirm].yield(mock("confirm-ok"))
321
- b.yield(@header, :message)
322
- end
323
-
324
- # subscribe してみる
325
- mock_raw_event = mock(:row_event)
326
- mock_raw_event.stub!(:key).and_return("uuid")
327
- mock_raw_event.stub!(:sender_name).and_return("localhost")
328
- mock_raw_event.should_receive(:attributes).and_return(:event_type_name => :event01, :key => "uuid")
329
- mock_raw_event.stub!(:level).and_return(Tengine::Event::LEVELS_INV[:info])
330
- mock_raw_event.stub!(:event_type_name).and_return("event01")
331
- Tengine::Event.should_receive(:parse).with(:message).and_return(mock_raw_event)
332
- # イベントの登録
333
- Tengine::Core::Event.should_receive(:create!).with(:event_type_name => :event01, :key => "uuid", :confirmed => true).and_return(@event1)
334
-
335
- # ハンドラの実行を検証
336
- Tengine::Core::HandlerPath.should_receive(:find_handlers).with("event01").and_return([@handler1])
337
- @handler1.should_receive(:match?).with(@event1).and_return(true)
338
-
339
- # 仕様変更のためイベントハンドラの処理を確認するのは一旦コメントアウトしました
340
- # @kernel.context.should_receive(:puts).with("handler01")
341
-
342
- @header.should_receive(:ack)
343
-
344
- # 実行
345
- @kernel.start
346
- end
347
-
348
- context "*.failed.tengine" do
349
- before do
350
- @uuid = ::UUID.new
351
- @header.stub(:ack)
352
- @sender = mock(:sender)
353
- @kernel.stub(:sender).and_return(@sender)
354
- @sender.should_not_receive(:fire)
355
- end
356
-
357
- context "正常系" do
358
- it "メッセージストアに保存" do
359
- e = Tengine::Event.new key: @uuid.generate, event_type_name: "something.failed.tengine"
360
-
361
- @kernel.process_message @header, e.to_json
362
-
363
- Tengine::Core::Event.where(key: e.key).count.should == 1
364
- Tengine::Core::Event.where(key: e.key).first.event_type_name.should =~ /failed\.tengine$/
365
- end
366
- end
367
-
368
- context "異常系" do
369
- it "無限地獄の回避" do
370
- @header.stub(:reject)
371
- Tengine::Core::Event.stub(:create!).and_raise(Mongo::OperationFailure.new)
372
- e = Tengine::Event.new key: @uuid.generate, event_type_name: "something.failed.tengine"
373
-
374
- @kernel.process_message @header, e.to_json
375
- end
376
- end
377
- end
378
-
379
- context "heartbeat" do
380
- before do
381
- @uuid = ::UUID.new
382
- @header.stub(:ack)
383
- @sender = mock(:sender)
384
- @kernel.stub(:sender).and_return(@sender)
385
- end
386
-
387
- shared_examples "generic heartbeats" do
388
- context "正常系" do
389
- context "初回" do
390
- before do
391
- @u = @uuid.generate
392
- Tengine::Core::Event.where(key: @u).delete_all
393
- end
394
- it "beatは保存される" do
395
- @kernel.process_message(@header, Tengine::Event.new(key: @u, event_type_name: "#{kind}.heartbeat.tengine").to_json).should be_true
396
- Tengine::Core::Event.where(key: @u).count.should == 1
397
- Tengine::Core::Event.where(key: @u).first.event_type_name.should =~ /^#{kind}/
398
- end
399
-
400
- it "finishedは保存される" do
401
- @kernel.process_message(@header, Tengine::Event.new(key: @u, event_type_name: "finished.process.#{kind}.tengine").to_json).should be_true
402
- Tengine::Core::Event.where(key: @u).count.should == 1
403
- Tengine::Core::Event.where(key: @u).first.event_type_name.should =~ /^finished/
404
- end
405
-
406
- it "expiredは保存される" do
407
- @kernel.process_message(@header, Tengine::Event.new(key: @u, event_type_name: "expired.#{kind}.heartbeat.tengine").to_json).should be_true
408
- Tengine::Core::Event.where(key: @u).count.should == 1
409
- Tengine::Core::Event.where(key: @u).first.event_type_name.should =~ /^expired/
410
- end
411
- end
412
-
413
- it "beat -> beat -> beat" do
414
- e = Tengine::Event.new key: @uuid.generate, event_type_name: "#{kind}.heartbeat.tengine"
415
-
416
- @kernel.process_message @header, e.to_json
417
- @kernel.process_message @header, e.to_json
418
- @kernel.process_message @header, e.to_json
419
-
420
- Tengine::Core::Event.where(key: e.key).count.should == 1
421
- Tengine::Core::Event.where(key: e.key).first.event_type_name.should =~ /^#{kind}/
422
- end
423
-
424
- it "beat -> finished (finishedが勝つ)" do
425
- u = @uuid.generate
426
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "#{kind}.heartbeat.tengine").to_json
427
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "finished.process.#{kind}.tengine").to_json
428
-
429
- Tengine::Core::Event.where(key: u).count.should == 1
430
- Tengine::Core::Event.where(key: u).first.event_type_name.should =~ /finished/
431
- end
432
-
433
- it "beat -> expired (expiredが勝つ)" do
434
- u = @uuid.generate
435
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "#{kind}.heartbeat.tengine").to_json
436
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "expired.#{kind}.heartbeat.tengine").to_json
437
-
438
- Tengine::Core::Event.where(key: u).count.should == 1
439
- Tengine::Core::Event.where(key: u).first.event_type_name.should =~ /expired/
440
- end
441
-
442
- it "beat -> finish -> expired (expiredが勝つ)" do
443
- u = @uuid.generate
444
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "#{kind}.heartbeat.tengine").to_json
445
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "finished.process.#{kind}.tengine").to_json
446
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "expired.#{kind}.heartbeat.tengine").to_json
447
-
448
- Tengine::Core::Event.where(key: u).count.should == 1
449
- Tengine::Core::Event.where(key: u).first.event_type_name.should =~ /expired/
450
- end
451
-
452
- it "finished -> beat (finishedが勝つ)" do
453
- u = @uuid.generate
454
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "finished.process.#{kind}.tengine").to_json
455
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "#{kind}.heartbeat.tengine").to_json
456
-
457
- Tengine::Core::Event.where(key: u).count.should == 1
458
- Tengine::Core::Event.where(key: u).first.event_type_name.should =~ /finished/
459
- end
460
-
461
- it "finished -> finished (上書き)" do
462
- e = Tengine::Event.new key: @uuid.generate, event_type_name: "finished.process.#{kind}.tengine"
463
-
464
- @kernel.process_message @header, e.to_json
465
- @kernel.process_message @header, e.to_json
466
-
467
- Tengine::Core::Event.where(key: e.key).count.should == 1
468
- Tengine::Core::Event.where(key: e.key).first.event_type_name.should =~ /finished/
469
- end
470
-
471
- it "finished -> expired (expiredが勝つ)" do
472
- u = @uuid.generate
473
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "finished.process.#{kind}.tengine").to_json
474
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "expired.#{kind}.heartbeat.tengine").to_json
475
-
476
- Tengine::Core::Event.where(key: u).count.should == 1
477
- Tengine::Core::Event.where(key: u).first.event_type_name.should =~ /expired/
478
- end
479
-
480
- it "expired -> beat (expiredが勝つ)" do
481
- u = @uuid.generate
482
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "expired.#{kind}.heartbeat.tengine").to_json
483
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "#{kind}.heartbeat.tengine").to_json
484
-
485
- Tengine::Core::Event.where(key: u).count.should == 1
486
- Tengine::Core::Event.where(key: u).first.event_type_name.should =~ /expired/
487
- end
488
-
489
- it "expired -> finished (expiredが勝つ)" do
490
- u = @uuid.generate
491
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "expired.#{kind}.heartbeat.tengine").to_json
492
- @kernel.process_message @header, Tengine::Event.new(key: u, event_type_name: "finished.process.#{kind}.tengine").to_json
493
-
494
- Tengine::Core::Event.where(key: u).count.should == 1
495
- Tengine::Core::Event.where(key: u).first.event_type_name.should =~ /expired/
496
- end
497
-
498
- it "expired -> expired (上書き)" do
499
- e = Tengine::Event.new key: @uuid.generate, event_type_name: "expired.#{kind}.heartbeat.tengine"
500
-
501
- @kernel.process_message @header, e.to_json
502
- @kernel.process_message @header, e.to_json
503
-
504
- Tengine::Core::Event.where(key: e.key).count.should == 1
505
- Tengine::Core::Event.where(key: e.key).first.event_type_name.should =~ /expired/
506
- end
507
-
508
- it "finished -> finished (失敗する)" do
509
- EM.stub(:next_tick).and_yield
510
- e = Tengine::Event.new key: @uuid.generate, event_type_name: "finished.process.#{kind}.tengine"
511
- @sender.should_receive(:fire).with("finished.process.#{kind}.tengine.failed.tengined", an_instance_of(Hash))
512
-
513
- @kernel.process_message @header, e.to_json
514
- @kernel.process_message @header, e.to_json
515
-
516
- Tengine::Core::Event.where(key: e.key).count.should == 1
517
- Tengine::Core::Event.where(key: e.key).first.event_type_name.should =~ /finished/
518
- end
519
- end
520
-
521
- context "異常系" do
522
- ['"#{kind}.heartbeat.tengine"',
523
- '"finished.process.#{kind}.tengine"',
524
- '"expired.#{kind}.heartbeat.tengine"'
525
- ].each do |name|
526
- context name do
527
- it "Mongo::OperationFailureの場合、failed eventを連鎖" do
528
- @sender.stub(:fire).with("#{kind}.heartbeat.tengine.failed.tengine", an_instance_of(Hash))
529
- Tengine::Core::Event.stub(:create!).and_raise(Mongo::OperationFailure.new)
530
- @kernel.stub(:upsert).and_raise Mongo::OperationFailure
531
-
532
- @kernel.process_message @header, Tengine::Event.new(key: @uuid.generate, event_type_name: eval(name)).to_json
533
- end
534
-
535
- it "Mongoid::Errors::Validationの場合、failed eventを連鎖" do
536
- x = Tengine::Core::Event.new
537
- x.valid? # false
538
- @sender.stub(:fire).with("#{kind}.heartbeat.tengine.failed.tengine", an_instance_of(Hash))
539
- Tengine::Core::Event.stub(:create!).and_raise(Mongoid::Errors::Validations.new(x))
540
- @kernel.stub(:upsert).and_raise Mongoid::Errors::Validations.new(x)
541
-
542
- @kernel.process_message @header, Tengine::Event.new(key: @uuid.generate, event_type_name: eval(name)).to_json
543
- end
544
-
545
- it "その他の場合、例外を外に伝播しない" do
546
- Tengine::Core::Event.stub(:find_or_create_by_key_then_update_with_block).and_raise StandardError
547
- expect do
548
- @kernel.process_message @header, Tengine::Event.new(key: @uuid.generate, event_type_name: eval(name)).to_json
549
- end.to_not raise_exception(StandardError)
550
- @kernel.process_message @header, Tengine::Event.new(key: @uuid.generate, event_type_name: eval(name)).to_json
551
- end
552
- end
553
- end
554
- end
555
- end
556
-
557
- describe "job heartbeat" do
558
- let(:kind) {"job"}
559
- it_behaves_like "generic heartbeats"
560
- end
561
-
562
- describe "core heartbeat" do
563
- let(:kind) {"core"}
564
- it_behaves_like "generic heartbeats"
565
- end
566
-
567
- describe "heartbeat watcher's heartbeat" do
568
- let(:kind) {"hbw"}
569
- it_behaves_like "generic heartbeats"
570
- end
571
-
572
- describe "atd heartbeat" do
573
- let(:kind) {"atd"}
574
- it_behaves_like "generic heartbeats"
575
- end
576
- end
577
-
578
- describe "schedule" do
579
- it "tenginedが調停する" do
580
- @header.stub(:ack)
581
- n = "alert.execution.job.tengine"
582
- s = "test test"
583
- e = Tengine::Event.new event_type_name: n, source_name: s
584
-
585
- @kernel.process_message @header, e.to_json
586
- @kernel.process_message @header, e.to_json
587
- @kernel.process_message @header, e.to_json
588
-
589
- Tengine::Core::Event.where(event_type_name: n, source_name: s).count.should == 1
590
- end
591
-
592
- it "tenginedが調停する #2" do
593
- mock_header1 = mock("header1")
594
- mock_header2 = mock("header2")
595
- mock_header3 = mock("header3")
596
- mock_header1.stub(:ack)
597
- mock_header2.stub(:reject)
598
- mock_header3.stub(:reject)
599
- n = "alert.execution.job.tengine"
600
- s = "test test"
601
- e = Tengine::Event.new event_type_name: n, source_name: s, key: "k1"
602
- f = Tengine::Event.new event_type_name: n, source_name: s, key: "k2"
603
- g = Tengine::Event.new event_type_name: n, source_name: s, key: "k3"
604
-
605
- @kernel.process_message mock_header1, e.to_json
606
- @kernel.process_message mock_header2, f.to_json
607
- @kernel.process_message mock_header3, g.to_json
608
-
609
- Tengine::Core::Event.where(event_type_name: n, source_name: s).count.should == 1
610
- end
611
- end
612
- end
613
- end
614
-
615
- describe :setup_mq_connection do
616
- if RUBY_VERSION >= "1.9.2"
617
- before do
618
- EM.instance_eval do
619
- @timers.each {|i| EM.cancel_timer i } if @timers
620
- @next_tick_queue = nil
621
- end
622
- trigger
623
- config = Tengine::Core::Config::Core.new({
624
- :tengined => {
625
- :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
626
- },
627
- :event_queue => { :connection => { :port => @port } }
628
- })
629
- @kernel = Tengine::Core::Kernel.new(config)
630
- end
631
-
632
- let(:rabbitmq) do
633
- ret = nil
634
- ENV["PATH"].split(/:/).find do |dir|
635
- Dir.glob("#{dir}/rabbitmq-server") do |path|
636
- if File.executable?(path)
637
- ret = path
638
- break
639
- end
640
- end
641
- end
642
-
643
- pending "rabbitmq が見つかりません" unless ret
644
- ret
645
- end
646
-
647
- def trigger port = rand(32768)
648
- require 'tmpdir'
649
- @dir = Dir.mktmpdir
650
- # 指定したポートはもう使われているかもしれないので、その際は
651
- # rabbitmqが起動に失敗するので、何回かポートを変えて試す。
652
- n = 0
653
- begin
654
- envp = {
655
- "RABBITMQ_NODENAME" => "rspec",
656
- "RABBITMQ_NODE_PORT" => port.to_s,
657
- "RABBITMQ_NODE_IP_ADDRESS" => "auto",
658
- "RABBITMQ_MNESIA_BASE" => @dir.to_s,
659
- "RABBITMQ_LOG_BASE" => @dir.to_s,
660
- }
661
- @pid = Process.spawn(envp, rabbitmq, :chdir => @dir, :in => :close, :out => '/dev/null', :err => '/dev/null')
662
- x = Time.now
663
- while Time.now < x + 64 do # まあこんくらい待てばいいでしょ
664
- sleep 0.1
665
- Process.waitpid2(@pid, Process::WNOHANG)
666
- Process.kill 0, @pid
667
- # netstat -an は Linux / BSD ともに有効
668
- # どちらかに限ればもう少し効率的な探し方はある。たとえば Linux 限定でよければ netstat -lnt ...
669
- y = `netstat -an | fgrep LISTEN | fgrep #{port}`
670
- if y.lines.to_a.size > 1
671
- @port = port
672
- return
673
- end
674
- end
675
- pending "failed to invoke rabbitmq in 16 secs."
676
- rescue Errno::ECHILD, Errno::ESRCH
677
- pending "10 attempts to invoke rabbitmq failed." if (n += 1) > 10
678
- port = rand(32768)
679
- retry
680
- end
681
- end
682
-
683
- def finish
684
- if @pid
685
- begin
686
- Process.kill "INT", @pid
687
- Process.waitpid @pid
688
- rescue Errno::ECHILD, Errno::ESRCH
689
- ensure
690
- require 'fileutils'
691
- FileUtils.remove_entry_secure @dir, :force
692
- end
693
- end
694
- end
695
-
696
- after do
697
- finish
698
- end
699
-
700
- it "MQ接続時にエラーなどのイベントハンドリングを行います" do
701
- EM.run do
702
- mq = @kernel.mq
703
-
704
- @kernel.setup_mq_connection
705
-
706
- # ここではイベント発生時の振る舞いもチェックします
707
- @kernel.subscribe_queue do
708
- Tengine::Core.stderr_logger.should_receive(:warn).with('mq.connection.on_tcp_connection_loss.').at_least(1).times
709
- finish
710
- EM.add_timer(1) do
711
- Tengine::Core.stderr_logger.should_receive(:info).with('mq.connection.after_recovery: recovered successfully.')
712
- EM.defer(
713
- lambda { trigger @port; sleep 2; true },
714
- lambda do |a|
715
- Tengine::Core.stderr_logger.should_receive(:error).with('mq.channel.on_error channel_close: "channel close reason object"')
716
- mq.channel.exec_callback_once_yielding_self(:error, "channel close reason object")
717
-
718
- Tengine::Core.stderr_logger.should_receive(:error).with('mq.connection.on_error connection_close: "connection close reason object"')
719
- mq.connection.exec_callback_yielding_self(:error, "connection close reason object")
720
-
721
- EM.next_tick do
722
- mq.stop
723
- end
724
- end
725
- )
726
- end
727
- end
728
- end
729
- end
730
- end
731
- end
732
-
733
- describe :status do
734
- describe :starting do
735
- before do
736
- config = Tengine::Core::Config::Core.new({
737
- :tengined => {
738
- :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
739
- },
740
- })
741
- @kernel = Tengine::Core::Kernel.new(config)
742
- end
743
-
744
- it "カーネルのインスタンス生成直後は「初期化済み」の状態を返す" do
745
- @kernel.status.should == :initialized
746
- end
747
-
748
- it "起動要求を受け取った直後は「起動中」の状態を返す", :start => true do
749
- @kernel.should_receive(:bind)
750
- @kernel.should_receive(:activate)
751
-
752
- @kernel.start
753
- @kernel.status.should == :starting
754
- end
755
-
756
- it "内部で使用されるupdate_statusにおかしな値を入れるとArgumentError" do
757
- expect {
758
- @kernel.send(:update_status, :invalid_status)
759
- }.to raise_error(ArgumentError)
760
- end
761
- end
762
-
763
- describe :waiting_for_activation do
764
- before do
765
- config = Tengine::Core::Config::Core.new({
766
- :tengined => {
767
- :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
768
- :wait_activation => true,
769
- :activation_timeout => 3,
770
- :activation_dir => File.expand_path('.', File.dirname(__FILE__)),
771
- },
772
- })
773
- @kernel = Tengine::Core::Kernel.new(config)
774
- end
775
-
776
- it "起動処理が終了した直後に「稼働要求待ち」の状態を返す" do
777
- @kernel.should_receive(:bind)
778
- @kernel.should_receive(:wait_for_activation)
779
-
780
- @kernel.start
781
- @kernel.status.should == :waiting_activation
782
- end
783
- end
784
-
785
- describe :running do
786
- before do
787
- config = Tengine::Core::Config::Core.new({
788
- :tengined => {
789
- :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
790
- },
791
- })
792
- @kernel = Tengine::Core::Kernel.new(config)
793
- @kernel.should_receive(:bind)
794
- end
795
-
796
- it "稼働要求を受け取った直後では「稼働中」の状態を返す" do
797
- mock_mq = mock("mq")
798
- mock_sender = mock("sender")
799
- @kernel.stub(:mq).and_return(mock_mq)
800
- @kernel.stub(:sender).and_return(mock_sender)
801
- mock_sender.stub(:fire).and_yield
802
- mock_mq.stub(:initiate_termination).and_yield
803
- mock_mq.stub(:unsubscribe).and_yield
804
- mock_mq.stub(:stop).and_yield
805
- mock_mq.stub(:add_hook)
806
- mock_mq.stub(:subscribe).with(nil).with(:ack => true, :nowait => false, :confirm => an_instance_of(Proc)) do |h, b|
807
- h[:confirm].yield(mock("confirm-ok"))
808
- end
809
-
810
- @kernel.should_receive(:setup_mq_connection)
811
- @kernel.start do
812
- @kernel.status.should == :running
813
- @kernel.stop
814
- end
815
- end
816
- end
817
-
818
- describe :stop do
819
- it "停止要求を受け取った直後では「停止中」および「停止済」の状態を返す(稼働中)" do
820
- config = Tengine::Core::Config::Core.new({
821
- :tengined => {
822
- :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
823
- },
824
- })
825
- kernel = Tengine::Core::Kernel.new(config)
826
- kernel.should_receive(:bind)
827
-
828
- mock_mq = mock("mq")
829
- mock_sender = mock("sender")
830
- kernel.stub(:mq).and_return(mock_mq)
831
- kernel.stub(:sender).and_return(mock_sender)
832
- mock_sender.stub(:fire).and_yield
833
- mock_mq.stub(:initiate_termination).and_yield
834
- mock_mq.stub(:unsubscribe).and_yield
835
- mock_mq.stub(:stop).and_yield
836
- mock_mq.stub(:add_hook)
837
- mock_mq.stub(:subscribe).with(nil).with(:ack => true, :nowait => false, :confirm => an_instance_of(Proc)) do |h, b|
838
- h[:confirm].yield(mock("confirm-ok"))
839
- end
840
-
841
- kernel.start do
842
- kernel.status.should == :running
843
-
844
- kernel.stop do
845
- kernel.status.should == :terminated
846
- end
847
- end
848
- end
849
-
850
- it "停止要求を受け取った直後では「停止中」および「停止済」の状態を返す(稼働要求待ち)" do
851
- config = Tengine::Core::Config::Core.new({
852
- :tengined => {
853
- :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
854
- :wait_activation => true,
855
- :activation_timeout => 3,
856
- :activation_dir => File.expand_path('.', File.dirname(__FILE__)),
857
- },
858
- })
859
- kernel = Tengine::Core::Kernel.new(config)
860
- kernel.should_receive(:bind)
861
-
862
- lambda {
863
- kernel.start
864
- # kernel.stop
865
- }.should raise_error(Tengine::Core::ActivationTimeoutError, "activation file found timeout error.")
866
- kernel.status.should == :shutting_down
867
- end
868
-
869
- it "heartbeatの停止" do
870
- kernel = Tengine::Core::Kernel.new(Tengine::Core::Config::Core.new({
871
- :tengined => {
872
- :load_path => File.expand_path('../../../examples/uc01_execute_processing_for_event.rb', File.dirname(__FILE__)),
873
- :wait_activation => true,
874
- :activation_timeout => 3,
875
- :activation_dir => File.expand_path('.', File.dirname(__FILE__)),
876
- },
877
- }))
878
- kernel.instance_eval do
879
- @status = :running
880
- @heartbeat_timer = true
881
- end
882
- mock_mq = mock("mq")
883
- kernel.stub(:mq).and_return(mock_mq)
884
- mock_mq.stub(:initiate_termination).and_yield
885
- mock_mq.stub(:unsubscribe).and_yield
886
- mock_mq.stub(:stop).and_yield
887
- mock_mq.stub(:add_hook)
888
- mock_mq.stub(:subscribe).with(nil).with(:ack => true, :nowait => false, :confirm => an_instance_of(Proc)) do |h, b|
889
- h[:confirm].yield(mock("confirm-ok"))
890
- end
891
- sender = mock(:sender)
892
- kernel.stub(:sender).and_return(sender)
893
-
894
- EM.should_receive(:cancel_timer)
895
- sender.should_receive(:fire).with("finished.process.core.tengine", an_instance_of(Hash))
896
-
897
- kernel.stop
898
- end
899
- end
900
- end
901
-
902
- end