tengine_core 0.5.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +40 -0
  4. data/Gemfile.lock +95 -0
  5. data/README.md +54 -0
  6. data/Rakefile +44 -0
  7. data/VERSION +1 -0
  8. data/bin/tengine_atd +8 -0
  9. data/bin/tengine_heartbeat_watchd +8 -0
  10. data/bin/tengined +182 -0
  11. data/examples/VERSION +1 -0
  12. data/examples/uc01_execute_processing_for_event.rb +11 -0
  13. data/examples/uc02_fire_another_event.rb +16 -0
  14. data/examples/uc03_2handlers_for_1event.rb +16 -0
  15. data/examples/uc08_if_both_a_and_b_occurs.rb +11 -0
  16. data/examples/uc10_if_the_event_occurs_at_the_server.rb +15 -0
  17. data/examples/uc50_commit_event_at_first.rb +17 -0
  18. data/examples/uc51_commit_event_at_first_submit.rb +29 -0
  19. data/examples/uc52_commit_event_after_all_handler_submit.rb +31 -0
  20. data/examples/uc52_never_commit_event_unless_all_handler_submit.rb +31 -0
  21. data/examples/uc60_event_in_handler.rb +18 -0
  22. data/examples/uc62_session_in_driver.rb +16 -0
  23. data/examples/uc64_safety_countup.rb +14 -0
  24. data/examples/uc70_driver_enabled_on_activation.rb +13 -0
  25. data/examples/uc71_driver_disabled_on_activation.rb +14 -0
  26. data/examples/uc72_setup_eventmachine.rb +17 -0
  27. data/examples/uc80_raise_io_error.rb +10 -0
  28. data/examples/uc81_raise_runtime_error.rb +10 -0
  29. data/examples2/driver01.rb +18 -0
  30. data/examples2/driver02.rb +19 -0
  31. data/examples2/uc08_if_both_a_and_b_occurs.rb +13 -0
  32. data/examples2/uc10_if_the_event_occurs_at_the_server.rb +18 -0
  33. data/examples2/uc51_commit_event_at_first_submit_1.rb +16 -0
  34. data/examples2/uc51_commit_event_at_first_submit_2.rb +17 -0
  35. data/examples2/uc51_commit_event_at_first_submit_3.rb +17 -0
  36. data/examples2/uc62_session_in_driver.rb +16 -0
  37. data/examples2/uc71_driver_disabled_on_activation.rb +16 -0
  38. data/failure_examples/VERSION +1 -0
  39. data/failure_examples/uc53_submit_outside_of_handler.rb +15 -0
  40. data/failure_examples/uc61_event_outside_of_handler.rb +12 -0
  41. data/failure_examples/uc63_session_outside_of_driver.rb +13 -0
  42. data/lib/tengine/core.rb +74 -0
  43. data/lib/tengine/core/bootstrap.rb +123 -0
  44. data/lib/tengine/core/collection_accessible.rb +34 -0
  45. data/lib/tengine/core/config.rb +10 -0
  46. data/lib/tengine/core/config/atd.rb +225 -0
  47. data/lib/tengine/core/config/core.rb +319 -0
  48. data/lib/tengine/core/config/heartbeat_watcher.rb +229 -0
  49. data/lib/tengine/core/connection_test/.gitignore +1 -0
  50. data/lib/tengine/core/connection_test/fire_bar_on_foo.rb +16 -0
  51. data/lib/tengine/core/driveable.rb +213 -0
  52. data/lib/tengine/core/driver.rb +69 -0
  53. data/lib/tengine/core/driver/finder.rb +42 -0
  54. data/lib/tengine/core/dsl_evaluator.rb +110 -0
  55. data/lib/tengine/core/dsl_filter_def.rb +11 -0
  56. data/lib/tengine/core/dsl_loader.rb +108 -0
  57. data/lib/tengine/core/event.rb +145 -0
  58. data/lib/tengine/core/event/finder.rb +82 -0
  59. data/lib/tengine/core/event_exception_reportable.rb +88 -0
  60. data/lib/tengine/core/event_wrapper.rb +21 -0
  61. data/lib/tengine/core/find_by_name.rb +31 -0
  62. data/lib/tengine/core/handler.rb +152 -0
  63. data/lib/tengine/core/handler_path.rb +33 -0
  64. data/lib/tengine/core/heartbeat_watcher.rb +161 -0
  65. data/lib/tengine/core/io_to_logger.rb +22 -0
  66. data/lib/tengine/core/kernel.rb +510 -0
  67. data/lib/tengine/core/kernel_runtime.rb +91 -0
  68. data/lib/tengine/core/method_traceable.rb +38 -0
  69. data/lib/tengine/core/mongoid_fix.rb +19 -0
  70. data/lib/tengine/core/mutex.rb +177 -0
  71. data/lib/tengine/core/optimistic_lock.rb +69 -0
  72. data/lib/tengine/core/plugins.rb +54 -0
  73. data/lib/tengine/core/schedule.rb +21 -0
  74. data/lib/tengine/core/scheduler.rb +156 -0
  75. data/lib/tengine/core/selectable_attr.rb +29 -0
  76. data/lib/tengine/core/session.rb +21 -0
  77. data/lib/tengine/core/session_wrapper.rb +68 -0
  78. data/lib/tengine/core/setting.rb +21 -0
  79. data/lib/tengine/core/validation.rb +36 -0
  80. data/lib/tengine/errors.rb +18 -0
  81. data/lib/tengine/rspec.rb +8 -0
  82. data/lib/tengine/rspec/context_wrapper.rb +51 -0
  83. data/lib/tengine/rspec/extension.rb +53 -0
  84. data/lib/tengine_core.rb +23 -0
  85. data/spec/factories/tengine_core_drivers.rb +10 -0
  86. data/spec/factories/tengine_core_events.rb +14 -0
  87. data/spec/factories/tengine_core_handler_paths.rb +9 -0
  88. data/spec/factories/tengine_core_handlers.rb +9 -0
  89. data/spec/factories/tengine_core_sessions.rb +9 -0
  90. data/spec/mongoid.yml +35 -0
  91. data/spec/spec_helper.rb +48 -0
  92. data/spec/support/mongo_index_key_log.rb +91 -0
  93. data/spec/tengine/core/bootstrap_spec.rb +278 -0
  94. data/spec/tengine/core/bugfix/bind_dsl_file_in_multi_byte_dir_spec.rb +21 -0
  95. data/spec/tengine/core/bugfix/enabled_on_activation_spec.rb +112 -0
  96. data/spec/tengine/core/bugfix/receive_event_spec.rb +133 -0
  97. data/spec/tengine/core/bugfix/use_dsl_version_method.rb +12 -0
  98. data/spec/tengine/core/bugfix/use_dsl_version_method_spec.rb +28 -0
  99. data/spec/tengine/core/bugfix/use_event_in_handler_dsl.rb +11 -0
  100. 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 +35 -0
  101. 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 +38 -0
  102. 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 +35 -0
  103. 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 +38 -0
  104. data/spec/tengine/core/config/atd_spec.rb +62 -0
  105. data/spec/tengine/core/config/core_spec.rb +479 -0
  106. data/spec/tengine/core/config/heartbeat_watcher_spec.rb +62 -0
  107. data/spec/tengine/core/config/syntax_error_in_erb.yml.erb +13 -0
  108. data/spec/tengine/core/config/wrong_category_name.yml.erb +13 -0
  109. data/spec/tengine/core/config/wrong_field_name.yml.erb +12 -0
  110. data/spec/tengine/core/config/wrong_yaml.yml.erb +13 -0
  111. data/spec/tengine/core/config_spec/another_port.yml +54 -0
  112. data/spec/tengine/core/config_spec/config_with_dir_absolute_load_path.yml +16 -0
  113. data/spec/tengine/core/config_spec/config_with_dir_relative_load_path.yml +16 -0
  114. data/spec/tengine/core/config_spec/config_with_file_absolute_load_path.yml +16 -0
  115. data/spec/tengine/core/config_spec/config_with_file_relative_load_path.yml +16 -0
  116. data/spec/tengine/core/config_spec/log_config_spec.rb +235 -0
  117. data/spec/tengine/core/driveable_spec.rb +240 -0
  118. data/spec/tengine/core/driver_spec.rb +159 -0
  119. data/spec/tengine/core/dsl_loader_spec.rb +172 -0
  120. data/spec/tengine/core/dsls/uc08_if_both_a_and_b_occurs_spec.rb +35 -0
  121. data/spec/tengine/core/dsls/uc10_if_the_event_occurs_at_the_server_spec.rb +58 -0
  122. data/spec/tengine/core/dsls/uc50_commit_event_at_first_spec.rb +29 -0
  123. data/spec/tengine/core/dsls/uc52_commit_event_after_all_handler_submit_spec.rb +33 -0
  124. data/spec/tengine/core/dsls/uc52_never_commit_event_unless_all_handler_submit_spec.rb +37 -0
  125. data/spec/tengine/core/dsls/uc53_submit_outside_of_handler_spec.rb +37 -0
  126. data/spec/tengine/core/dsls/uc60_event_in_handler_spec.rb +31 -0
  127. data/spec/tengine/core/dsls/uc61_event_outside_of_handler_spec.rb +37 -0
  128. data/spec/tengine/core/dsls/uc62_session_in_driver_spec.rb +36 -0
  129. data/spec/tengine/core/dsls/uc63_session_outside_of_driver_spec.rb +35 -0
  130. data/spec/tengine/core/dsls/uc64_safety_countup_spec.rb +134 -0
  131. data/spec/tengine/core/dsls/uc70_driver_enabled_on_activation_spec.rb +39 -0
  132. data/spec/tengine/core/dsls/uc71_driver_disabled_on_activation_spec.rb +36 -0
  133. data/spec/tengine/core/dsls/uc72_setup_eventmachine_spec.rb +39 -0
  134. data/spec/tengine/core/dsls/uc80_raise_io_error_spec.rb +53 -0
  135. data/spec/tengine/core/dsls/uc81_raise_runtime_error_spec.rb +49 -0
  136. data/spec/tengine/core/event/finder_spec.rb +136 -0
  137. data/spec/tengine/core/event_exception_reportable_spec.rb +33 -0
  138. data/spec/tengine/core/event_spec.rb +161 -0
  139. data/spec/tengine/core/event_wrapper_spec.rb +35 -0
  140. data/spec/tengine/core/handler_path_spec.rb +87 -0
  141. data/spec/tengine/core/handler_spec.rb +190 -0
  142. data/spec/tengine/core/heartbeat_watcher_spec.rb +131 -0
  143. data/spec/tengine/core/io_to_logger_spec.rb +30 -0
  144. data/spec/tengine/core/kernel_spec.rb +885 -0
  145. data/spec/tengine/core/mutex_spec.rb +184 -0
  146. data/spec/tengine/core/optimistic_lock_spec.rb +55 -0
  147. data/spec/tengine/core/scheculer_spec.rb +121 -0
  148. data/spec/tengine/core/selectable_attr_spec.rb +30 -0
  149. data/spec/tengine/core/session_spec.rb +104 -0
  150. data/spec/tengine/core/setting_spec.rb +79 -0
  151. data/spec/tengine/core_spec.rb +13 -0
  152. data/spec/tengine_spec.rb +14 -0
  153. data/tengine_core.gemspec +248 -0
  154. data/tmp/log/.gitignore +1 -0
  155. data/tmp/tengined_status/.gitignore +1 -0
  156. metadata +421 -0
@@ -0,0 +1,23 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'logger'
3
+
4
+ module Tengine
5
+ autoload :Core, 'tengine/core'
6
+ autoload :Errors, 'tengine/errors'
7
+
8
+ class DslError < StandardError
9
+ end
10
+
11
+ class << self
12
+ def logger
13
+ @logger ||= ::Logger.new(STDOUT)
14
+ end
15
+ attr_writer :logger
16
+
17
+ def plugins
18
+ @plugins ||= Tengine::Core::Plugins.new
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,10 @@
1
+ # Read about factories at http://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :"tengine/core/driver" do
5
+ name("MyString")
6
+ version("MyString")
7
+ enabled(false)
8
+ enabled_on_activation(false)
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ # Read about factories at http://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :"tengine/core/event" do
5
+ event_type_name("event01")
6
+ key { @uuid ||= UUID.new; @uuid.generate }
7
+ source_name("server1")
8
+ occurred_at { Time.now.utc }
9
+ level(2) # info
10
+ confirmed(false)
11
+ sender_name("server1")
12
+ properties({})
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ # Read about factories at http://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :"tengine/core/handler_path" do
5
+ event_type_name("MyString")
6
+ driver(nil)
7
+ handler_id("")
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # Read about factories at http://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :"tengine/core/handler" do
5
+ event_type_names(["abc", "123"])
6
+ filepath("relative_path/from/dsl_dir/to/dsl.rb")
7
+ lineno(10)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # Read about factories at http://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :"tengine/core/session" do
5
+ lock_version(1)
6
+ properties({"a"=>"1", "b"=>"2"})
7
+ system_properties({"a"=>"1", "b"=>"2"})
8
+ end
9
+ end
data/spec/mongoid.yml ADDED
@@ -0,0 +1,35 @@
1
+ defaults: &defaults
2
+ # mongoid defaults for configurable settings
3
+ # autocreate_indexes: false
4
+ # allow_dynamic_fields: true
5
+ # include_root_in_json: false
6
+ # parameterize_keys: true
7
+ persist_in_safe_mode: true
8
+ # raise_not_found_error: true
9
+ # reconnect_time: 3
10
+ logger: false
11
+
12
+ development:
13
+ <<: *defaults
14
+ host: localhost
15
+ database: tengine_core_development
16
+
17
+ test:
18
+ <<: *defaults
19
+ host: localhost
20
+ database: tengine_core_test
21
+ autocreate_indexes: true
22
+
23
+ # set these environment variables on your prod server
24
+ production:
25
+ <<: *defaults
26
+ host: <%= ENV['MONGOID_HOST'] %>
27
+ port: <%= ENV['MONGOID_PORT'] %>
28
+ username: <%= ENV['MONGOID_USERNAME'] %>
29
+ password: <%= ENV['MONGOID_PASSWORD'] %>
30
+ database: <%= ENV['MONGOID_DATABASE'] %>
31
+ # slaves:
32
+ # - host: slave1.local
33
+ # port: 27018
34
+ # - host: slave2.local
35
+ # port: 27019
@@ -0,0 +1,48 @@
1
+ # -*- coding: utf-8 -*-
2
+ ENV["RACK_ENV"] ||= "test" # Mongoid.load!で参照しています
3
+
4
+ require 'coverage'
5
+ class << Coverage
6
+ alias original_result result
7
+ def result
8
+ original_result.inject({}) {|r, (k, v)|
9
+ x = k.dup.force_encoding(Encoding.default_external).freeze
10
+ r.update x => v
11
+ }
12
+ end
13
+ end
14
+
15
+ require 'simplecov'
16
+ SimpleCov.start if ENV["COVERAGE"]
17
+
18
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
19
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
20
+ require 'rspec'
21
+ require 'factory_girl'
22
+
23
+ require 'tengine_core'
24
+ require 'mongoid'
25
+ Mongoid.load!(File.expand_path('mongoid.yml', File.dirname(__FILE__)))
26
+
27
+ # Requires supporting files with custom matchers and macros, etc,
28
+ # in ./support/ and its subdirectories.
29
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
30
+
31
+ Tengine::Core::MethodTraceable.disabled = true
32
+ require 'logger'
33
+ log_path = File.expand_path("../tmp/log/test.log", File.dirname(__FILE__))
34
+ Tengine.logger = Logger.new(log_path)
35
+ Tengine.logger.level = Logger::DEBUG
36
+ Tengine::Core.stdout_logger = Logger.new(log_path)
37
+ Tengine::Core.stdout_logger.level = Logger::DEBUG
38
+ Tengine::Core.stderr_logger = Logger.new(log_path)
39
+ Tengine::Core.stderr_logger.level = Logger::DEBUG
40
+
41
+ Tengine::Core::Kernel.event_exception_reporter = :raise_all
42
+ Tengine::Core::Config::Core::Tengined.default_cache_drivers = true
43
+
44
+ RSpec.configure do |config|
45
+ config.include Factory::Syntax::Methods
46
+ end
47
+
48
+ Dir["#{File.expand_path('factories', File.dirname(__FILE__))}/**/*.rb"].each {|f| require f}
@@ -0,0 +1,91 @@
1
+ # -*- coding: utf-8 -*-
2
+ # 使い方
3
+ # テスト実行時に 環境変数MONGO_INDEX_KEY_LOGにログの出力先のファイル名を指定しておくと、
4
+ # そこにmongoに対してどんな検索条件やソート、ヒントなどをどのように指定しているのかを出力できます
5
+ #
6
+ # この出力された結果のファイルに対して sort と uniq をかけることにより、どんなインデックスを
7
+ # 作れば良いのか判断する材料となります。
8
+ #
9
+ # export MONGO_INDEX_KEY_LOG=$HOME/tmp/mongo_index_key.log
10
+ # cd tenigne_core && rake spec
11
+ # cd tenigne_resource && rake spec
12
+ # cd tenigne_job && rake spec
13
+ # cd tenigne_console && rake spec
14
+ # cd $HOME/tmp
15
+ # cat mongo_index_key.log | sort | uniq > mongo_index_key_summary.log
16
+ #
17
+ # これで $HOME/tmp/mongo_index_key_summary.log にどのようなキーが使われているのかがまとめられます
18
+ #
19
+ if ENV['MONGO_INDEX_KEY_LOG']
20
+ file_path = File.expand_path(ENV['MONGO_INDEX_KEY_LOG'])
21
+ STDOUT.puts("MONGO_INDEX_KEY_LOG enable logging key infomation for index to #{file_path}")
22
+
23
+ Mongo::Collection.class_eval do
24
+ def index_key_log_file
25
+ unless defined?(@@index_key_log_file)
26
+ file_path = File.expand_path(ENV['MONGO_INDEX_KEY_LOG'])
27
+ @@index_key_log_file = File.open(file_path, "a")
28
+ end
29
+ @@index_key_log_file
30
+ end
31
+
32
+ def find_with_index_key_log(selector={}, opts={}, &block)
33
+ result = find_without_index_key_log(selector, opts, &block)
34
+ index_key_log_file.puts("#{self.name}.find({#{_hash_keys_(selector)}}, {#{_hash_keys_(opts.dup)}}): #{_explain_summary_(result.explain)}")
35
+ result
36
+ end
37
+ alias_method :find_without_index_key_log, :find
38
+ alias_method :find, :find_with_index_key_log
39
+
40
+
41
+ def find_and_modify_with_index_key_log(opts={}, &block)
42
+ o = opts.dup
43
+ query = o.delete(:query)
44
+ index_key_log_file.puts("#{self.name}.find_and_modify({#{_hash_keys_(query)}}, {#{_hash_keys_(o)}})")
45
+ find_and_modify_without_index_key_log(opts, &block)
46
+ end
47
+ alias_method :find_and_modify_without_index_key_log, :find_and_modify
48
+ alias_method :find_and_modify, :find_and_modify_with_index_key_log
49
+
50
+ def _hash_keys_(hash)
51
+ res = []
52
+ [:sort, :hint, :limit].each do |key|
53
+ if value = hash.delete(key)
54
+ res << "#{key.inspect} => #{value.inspect}"
55
+ end
56
+ end
57
+ res += hash.keys.map(&:inspect)
58
+ res.join(',')
59
+ end
60
+
61
+ def _explain_summary_(hash)
62
+ case cursor = hash['cursor']
63
+ when /^BtreeCursor/ then
64
+ res = []
65
+ %w[cursor].each do |key|
66
+ if value = hash.delete(key)
67
+ res << "#{key.inspect} => #{value.inspect}"
68
+ end
69
+ end
70
+ res += hash.keys.map(&:inspect)
71
+ "{" << res.join(',') << "}"
72
+ else
73
+ res = []
74
+ res << "'cursor' => #{hash.delete('cursor').inspect}"
75
+ {"nscanned" => 1, "nscannedObjects" => 1, "n" => 1, "millis" => 0, "nYields"=>0, "nChunkSkips"=>0 }.each do |key, border|
76
+ if value = hash.delete(key)
77
+ if value > border
78
+ res << "#{key.inspect} => '>#{border.inspect}'"
79
+ else
80
+ res << "#{key.inspect} => #{value.inspect}"
81
+ end
82
+ end
83
+ end
84
+ res += hash.keys.map(&:inspect)
85
+ "{" << res.join(',') << "}"
86
+ end
87
+ end
88
+
89
+ end
90
+
91
+ end
@@ -0,0 +1,278 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'amqp'
4
+ require 'eventmachine'
5
+ require 'tengine/mq'
6
+ require 'tengine/event'
7
+
8
+ describe "Tengine::Core::Bootstrap" do
9
+
10
+ describe "bootメソッドでは" do
11
+ context "config[:action] => load の場合" do
12
+ it "load_dslがよばれること" do
13
+ options = { :action => "load" }
14
+ bootstrap = Tengine::Core::Bootstrap.new(options)
15
+ bootstrap.should_receive(:load_dsl)
16
+ bootstrap.boot
17
+ end
18
+ end
19
+
20
+ context "config[:action] => start かつ skipオプションが設定されている場合" do
21
+ it "load_dslはよばれず、start_kernelのみよばれること" do
22
+ options = {
23
+ :action => "start",
24
+ :tengined => {
25
+ :skip_load => true,
26
+ :skip_enablement => true,
27
+ :wait_activation => false
28
+ }
29
+ }
30
+ bootstrap = Tengine::Core::Bootstrap.new(options)
31
+ bootstrap.should_receive(:start_kernel)
32
+ # skip_loadオプションを指定してもtengine_core-0.5系の再設計により無視するように変更しました。
33
+ # bootstrap.should_not_receive(:load_dsl)
34
+ bootstrap.should_receive(:load_dsl)
35
+ bootstrap.boot
36
+ end
37
+ end
38
+
39
+ context "config[:action] => enable の場合" do
40
+ it "enable_driversがよばれること" do
41
+ options = { :action => "enable" }
42
+ bootstrap = Tengine::Core::Bootstrap.new(options)
43
+ bootstrap.should_receive(:enable_drivers)
44
+ bootstrap.boot
45
+ end
46
+ end
47
+
48
+ context "config[:action] => startで、skipオプションの指定がない場合" do
49
+ it "load_dslとstart_kernelがよばれること" do
50
+ options = { :action => "start" }
51
+ bootstrap = Tengine::Core::Bootstrap.new(options)
52
+ bootstrap.should_receive(:load_dsl)
53
+ bootstrap.should_receive(:start_kernel)
54
+ bootstrap.boot
55
+ end
56
+ end
57
+
58
+ context "config[:action] => test の場合" do
59
+ it "load_dsl, start_kernel, start_connection_test, stop_kernelがよばれること" do
60
+ bootstrap = Tengine::Core::Bootstrap.new(:action => "test")
61
+ bootstrap.should_receive(:load_dsl)
62
+ bootstrap.should_receive(:start_kernel)
63
+ # #stop_kernel は、#start_kernel に渡されるブロックから呼び出されます
64
+ # bootstrap.should_receive(:stop_kernel)
65
+ Tengine::Core.stdout_logger.should_receive(:info).with("Connection test success.")
66
+ bootstrap.boot
67
+ end
68
+
69
+ it "start_kernelに渡されたブロックを実行する" do
70
+ bootstrap = Tengine::Core::Bootstrap.new(:action => "test")
71
+ bootstrap.should_receive(:load_dsl)
72
+ mock_mq = mock(:mq)
73
+ bootstrap.should_receive(:start_kernel).and_yield(mock_mq)
74
+ EM.should_receive(:defer).with(an_instance_of(Proc), an_instance_of(Proc))
75
+ Tengine::Core.stdout_logger.should_receive(:info).with("Connection test success.")
76
+ bootstrap.boot
77
+ end
78
+
79
+ it "start_kernelに失敗するとstdout_loggerに出力する" do
80
+ bootstrap = Tengine::Core::Bootstrap.new(:action => "test")
81
+ bootstrap.should_receive(:load_dsl)
82
+ bootstrap.should_receive(:start_kernel).and_raise(IOError.new("Something wrong."))
83
+ Tengine::Core.stderr_logger.should_receive(:error).with("Connection test failure: [IOError] Something wrong.")
84
+ bootstrap.boot
85
+ end
86
+ end
87
+
88
+ context "config[:action]に想定外の値が設定された場合" do
89
+ it "ArgumentErrorをraiseする" do
90
+ options = { :action => 1 }
91
+ bootstrap = Tengine::Core::Bootstrap.new(options)
92
+ expect {
93
+ bootstrap.boot
94
+ }.to raise_error(ArgumentError, /config[:action] must be test|load|start|enable|stop|force-stop but was/)
95
+ end
96
+ end
97
+ end
98
+
99
+ describe :prepare_trap do
100
+ it "シグナルハンドラが定義される" do
101
+ mock_kernel = mock(:kernel)
102
+ Signal.should_receive(:trap).with(:HUP)
103
+ # Signal.should_receive(:trap).with(:QUIT)
104
+ bootstrap = Tengine::Core::Bootstrap.new({})
105
+ end
106
+ end
107
+
108
+ describe :load_dsl do
109
+ it "Tengine::Core::DslLoaderのevaluateがよばれる" do
110
+ options = { :action => "load" }
111
+
112
+ bootstrap = Tengine::Core::Bootstrap.new(options)
113
+ mock_config = mock(:config)
114
+ mock_config.should_receive(:dsl_version).and_return("test2011102623595999")
115
+ bootstrap.should_receive(:config).twice.and_return(mock_config)
116
+ bootstrap.kernel.context.tap do |context|
117
+ context.should_receive(:__evaluate__)
118
+ end
119
+ bootstrap.load_dsl
120
+ end
121
+
122
+ context "拡張モジュールあり" do
123
+ before(:all) do
124
+ @ext_mod1 = Module.new{}
125
+ @ext_mod1.instance_eval do
126
+ def dsl_loader; self; end
127
+ end
128
+ Tengine.plugins.add(@ext_mod1)
129
+ end
130
+
131
+ it "拡張モジュールがextendされ、Tengine::Core::DslLoaderとのevaluateがよばれる" do
132
+ options = { :action => "load" }
133
+ bootstrap = Tengine::Core::Bootstrap.new(options)
134
+ mock_config = mock(:config)
135
+ mock_config.should_receive(:dsl_version).and_return("test2011102623595999")
136
+ bootstrap.should_receive(:config).twice.and_return(mock_config)
137
+ bootstrap.kernel.context.tap do |context|
138
+ context.is_a?(@ext_mod1).should be_true
139
+ context.should_receive(:__evaluate__)
140
+ end
141
+ bootstrap.load_dsl
142
+ end
143
+
144
+ end
145
+
146
+ context "Tengine::Core::Settingとしてdsl_versionが保存される" do
147
+ shared_examples_for "dsl_versionに値が設定される" do
148
+ it do
149
+ Tengine::Core::Driver.delete_all
150
+ Tengine::Core::Session.delete_all
151
+ config = Tengine::Core::Config::Core.new({
152
+ :tengined => {
153
+ :load_path => File.expand_path('../../../examples/uc08_if_both_a_and_b_occurs.rb', File.dirname(__FILE__)),
154
+ },
155
+ })
156
+ @bootstrap = Tengine::Core::Bootstrap.new(config)
157
+ @bootstrap.load_dsl
158
+ dsl_version_document = Tengine::Core::Setting.first(:conditions => {:name => "dsl_version"})
159
+ dsl_version_document.should_not be_nil
160
+ dsl_version_document.value.should == "20110902213500" # examples/VERSION の中身
161
+ end
162
+ end
163
+
164
+ context "Tengine::Core::Settingにname=dsl_versionのドキュメントが存在しない" do
165
+ before do
166
+ Tengine::Core::Setting.delete_all
167
+ end
168
+ it_should_behave_like "dsl_versionに値が設定される"
169
+ end
170
+
171
+ context "Tengine::Core::Settingにname=dsl_versionのドキュメントが存在する場合" do
172
+ before do
173
+ Tengine::Core::Setting.delete_all
174
+ Tengine::Core::Setting.create!(:name => "dsl_version", :value => "fooo")
175
+ end
176
+ it_should_behave_like "dsl_versionに値が設定される"
177
+ end
178
+
179
+
180
+ end
181
+
182
+ end
183
+
184
+ describe :start_kernel do
185
+ it "Tengine::Core::Kernel#start がよばれる" do
186
+ options = { :action => "start" }
187
+ bootstrap = Tengine::Core::Bootstrap.new(options)
188
+
189
+ mock_config = mock(:config)
190
+ bootstrap.should_receive(:config).and_return(mock_config)
191
+ mock_kernel = mock(:kernel)
192
+ Tengine::Core::Kernel.should_receive(:new).with(mock_config).and_return(mock_kernel)
193
+ mock_kernel.should_receive(:start)
194
+ bootstrap.start_kernel
195
+ end
196
+
197
+ end
198
+
199
+ describe :enable_drivers do
200
+ before do
201
+ # capistranoのデフォルトのデプロイ先を想定しています
202
+ # see "BACK TO CONFIGURATION" in https://github.com/capistrano/capistrano/wiki/2.x-From-The-Beginning
203
+ # http://www.slideshare.net/T2J/capistrano-tips-tips
204
+ Dir.stub!(:pwd).and_return("/u/apps/app1/current")
205
+ end
206
+
207
+ before do
208
+ Tengine::Core::Driver.delete_all
209
+ t = Time.utc(2011,9,5,17,28,30)
210
+ Time.stub!(:now).and_return(t)
211
+ @time_str = "20110905172830"
212
+ @d1 = Tengine::Core::Driver.create!(:name=>"driver1", :version=>@time_str, :enabled=>false, :enabled_on_activation=>true)
213
+ @d2 = Tengine::Core::Driver.create!(:name=>"driver2", :version=>@time_str, :enabled=>false, :enabled_on_activation=>true)
214
+ @d3 = Tengine::Core::Driver.create!(:name=>"driver3", :version=>@time_str, :enabled=>false, :enabled_on_activation=>true)
215
+ end
216
+
217
+ it "enabled=true に更新される" do
218
+ Dir.stub!(:exist?).with("/u/apps/app1/current/examples").and_return(true)
219
+ File.stub!(:exist?).with("/u/apps/app1/current/examples/VERSION").and_return(false)
220
+ options = {
221
+ :action => "enable",
222
+ :tengined => { :load_path => "examples" }
223
+ }
224
+ bootstrap = Tengine::Core::Bootstrap.new(options)
225
+ bootstrap.config.dsl_version.should == @time_str
226
+ bootstrap.boot
227
+
228
+ Tengine::Core::Driver.where(:version => @time_str).each do |d|
229
+ d.enabled.should be_true
230
+ end
231
+ end
232
+ end
233
+
234
+ describe :start_connection_test do
235
+ before do
236
+ class << Tengine
237
+ attr_accessor :callback_for_test
238
+ end
239
+ end
240
+ after do
241
+ class << Tengine
242
+ remove_method :callback_for_test, :callback_for_test=
243
+ end
244
+ end
245
+
246
+ it "イベント:fooを発火して、テスト用のDSLが受信後にbarを発火、それを受け取るイベントハンドラから通知が来るまで待つ" do
247
+ bootstrap = Tengine::Core::Bootstrap.new(:action => "test")
248
+ mock_mq = mock(:mq)
249
+ Tengine::Event.should_receive(:fire).with(:foo, :level_key => :info, :keep_connection => true)
250
+ bootstrap.should_receive(:loop).and_yield
251
+ bootstrap.start_connection_test(mock_mq)
252
+ #
253
+ Tengine::Core.stdout_logger.should_receive(:info).with("handing :foo successfully.")
254
+ Tengine.callback_for_test.call(:foo)
255
+ Tengine::Core.stdout_logger.should_receive(:info).with("handing :bar successfully.")
256
+ Tengine.callback_for_test.call(:bar)
257
+ Tengine::Core.stderr_logger.should_receive(:error).with("Unexpected event: baz")
258
+ Tengine.callback_for_test.call(:baz)
259
+ end
260
+ end
261
+
262
+ describe :stop_kernel do
263
+ it "Tengine::Core::Kernel#stop がよばれること" do
264
+ options = { :action => "stop" }
265
+ bootstrap = Tengine::Core::Bootstrap.new(options)
266
+
267
+ mock_config = mock(:config)
268
+ bootstrap.should_receive(:config).and_return(mock_config)
269
+ mock_kernel = mock(:kernel)
270
+ Tengine::Core::Kernel.should_receive(:new).with(mock_config).and_return(mock_kernel)
271
+ mock_kernel.should_receive(:start)
272
+ bootstrap.start_kernel
273
+ mock_kernel.should_receive(:stop)
274
+ bootstrap.stop_kernel
275
+ end
276
+ end
277
+
278
+ end