tengine_core 0.5.28

Sign up to get free protection for your applications and to get access to all the features.
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