activerecord-turntable 1.0.0

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 (130) hide show
  1. data/.document +5 -0
  2. data/.gitignore +25 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +25 -0
  5. data/Guardfile +9 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.rdoc +290 -0
  8. data/Rakefile +101 -0
  9. data/activerecord-turntable.gemspec +47 -0
  10. data/lib/active_record/turntable.rb +58 -0
  11. data/lib/active_record/turntable/active_record_ext.rb +26 -0
  12. data/lib/active_record/turntable/active_record_ext/.gitkeep +0 -0
  13. data/lib/active_record/turntable/active_record_ext/abstract_adapter.rb +50 -0
  14. data/lib/active_record/turntable/active_record_ext/clever_load.rb +90 -0
  15. data/lib/active_record/turntable/active_record_ext/fixtures.rb +131 -0
  16. data/lib/active_record/turntable/active_record_ext/log_subscriber.rb +64 -0
  17. data/lib/active_record/turntable/active_record_ext/persistence.rb +95 -0
  18. data/lib/active_record/turntable/active_record_ext/schema_dumper.rb +107 -0
  19. data/lib/active_record/turntable/active_record_ext/sequencer.rb +28 -0
  20. data/lib/active_record/turntable/active_record_ext/transactions.rb +33 -0
  21. data/lib/active_record/turntable/algorithm.rb +7 -0
  22. data/lib/active_record/turntable/algorithm/.gitkeep +0 -0
  23. data/lib/active_record/turntable/algorithm/base.rb +11 -0
  24. data/lib/active_record/turntable/algorithm/range_algorithm.rb +37 -0
  25. data/lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb +41 -0
  26. data/lib/active_record/turntable/base.rb +130 -0
  27. data/lib/active_record/turntable/cluster.rb +70 -0
  28. data/lib/active_record/turntable/compatible.rb +19 -0
  29. data/lib/active_record/turntable/config.rb +24 -0
  30. data/lib/active_record/turntable/connection_proxy.rb +218 -0
  31. data/lib/active_record/turntable/connection_proxy/mixable.rb +39 -0
  32. data/lib/active_record/turntable/error.rb +8 -0
  33. data/lib/active_record/turntable/helpers.rb +5 -0
  34. data/lib/active_record/turntable/helpers/test_helper.rb +25 -0
  35. data/lib/active_record/turntable/master_shard.rb +28 -0
  36. data/lib/active_record/turntable/migration.rb +132 -0
  37. data/lib/active_record/turntable/mixer.rb +203 -0
  38. data/lib/active_record/turntable/mixer/fader.rb +34 -0
  39. data/lib/active_record/turntable/mixer/fader/calculate_shards_sum_result.rb +15 -0
  40. data/lib/active_record/turntable/mixer/fader/insert_shards_merge_result.rb +24 -0
  41. data/lib/active_record/turntable/mixer/fader/select_shards_merge_result.rb +22 -0
  42. data/lib/active_record/turntable/mixer/fader/specified_shard.rb +12 -0
  43. data/lib/active_record/turntable/mixer/fader/update_shards_merge_result.rb +17 -0
  44. data/lib/active_record/turntable/pool_proxy.rb +56 -0
  45. data/lib/active_record/turntable/rack.rb +5 -0
  46. data/lib/active_record/turntable/rack/connection_management.rb +18 -0
  47. data/lib/active_record/turntable/railtie.rb +14 -0
  48. data/lib/active_record/turntable/railties/databases.rake +205 -0
  49. data/lib/active_record/turntable/seq_shard.rb +14 -0
  50. data/lib/active_record/turntable/sequencer.rb +46 -0
  51. data/lib/active_record/turntable/sequencer/api.rb +36 -0
  52. data/lib/active_record/turntable/sequencer/mysql.rb +32 -0
  53. data/lib/active_record/turntable/shard.rb +48 -0
  54. data/lib/active_record/turntable/sql_tree_patch.rb +199 -0
  55. data/lib/active_record/turntable/version.rb +5 -0
  56. data/lib/activerecord-turntable.rb +2 -0
  57. data/lib/generators/active_record/turntable/install_generator.rb +14 -0
  58. data/lib/generators/templates/turntable.yml +40 -0
  59. data/sample_app/.gitignore +16 -0
  60. data/sample_app/Gemfile +41 -0
  61. data/sample_app/README.rdoc +261 -0
  62. data/sample_app/Rakefile +7 -0
  63. data/sample_app/app/assets/images/rails.png +0 -0
  64. data/sample_app/app/assets/javascripts/application.js +15 -0
  65. data/sample_app/app/assets/stylesheets/application.css +13 -0
  66. data/sample_app/app/controllers/application_controller.rb +3 -0
  67. data/sample_app/app/helpers/application_helper.rb +2 -0
  68. data/sample_app/app/mailers/.gitkeep +0 -0
  69. data/sample_app/app/models/.gitkeep +0 -0
  70. data/sample_app/app/models/user.rb +4 -0
  71. data/sample_app/app/views/layouts/application.html.erb +14 -0
  72. data/sample_app/config.ru +4 -0
  73. data/sample_app/config/application.rb +65 -0
  74. data/sample_app/config/boot.rb +6 -0
  75. data/sample_app/config/database.yml +70 -0
  76. data/sample_app/config/environment.rb +5 -0
  77. data/sample_app/config/environments/development.rb +37 -0
  78. data/sample_app/config/environments/production.rb +67 -0
  79. data/sample_app/config/environments/test.rb +37 -0
  80. data/sample_app/config/initializers/backtrace_silencers.rb +7 -0
  81. data/sample_app/config/initializers/inflections.rb +15 -0
  82. data/sample_app/config/initializers/mime_types.rb +5 -0
  83. data/sample_app/config/initializers/secret_token.rb +7 -0
  84. data/sample_app/config/initializers/session_store.rb +8 -0
  85. data/sample_app/config/initializers/wrap_parameters.rb +14 -0
  86. data/sample_app/config/locales/en.yml +5 -0
  87. data/sample_app/config/routes.rb +58 -0
  88. data/sample_app/config/turntable.yml +64 -0
  89. data/sample_app/db/migrate/20120316073058_create_users.rb +11 -0
  90. data/sample_app/db/seeds.rb +7 -0
  91. data/sample_app/lib/assets/.gitkeep +0 -0
  92. data/sample_app/lib/tasks/.gitkeep +0 -0
  93. data/sample_app/log/.gitkeep +0 -0
  94. data/sample_app/public/404.html +26 -0
  95. data/sample_app/public/422.html +26 -0
  96. data/sample_app/public/500.html +25 -0
  97. data/sample_app/public/favicon.ico +0 -0
  98. data/sample_app/public/index.html +241 -0
  99. data/sample_app/public/robots.txt +5 -0
  100. data/sample_app/script/rails +6 -0
  101. data/sample_app/vendor/assets/javascripts/.gitkeep +0 -0
  102. data/sample_app/vendor/assets/stylesheets/.gitkeep +0 -0
  103. data/sample_app/vendor/plugins/.gitkeep +0 -0
  104. data/script/performance/algorithm +32 -0
  105. data/spec/active_record/turntable/active_record_ext/clever_load_spec.rb +81 -0
  106. data/spec/active_record/turntable/active_record_ext/persistence_spec.rb +151 -0
  107. data/spec/active_record/turntable/algorithm/range_algorithm_spec.rb +35 -0
  108. data/spec/active_record/turntable/algorithm_spec.rb +69 -0
  109. data/spec/active_record/turntable/base_spec.rb +13 -0
  110. data/spec/active_record/turntable/cluster_spec.rb +18 -0
  111. data/spec/active_record/turntable/config_spec.rb +17 -0
  112. data/spec/active_record/turntable/connection_proxy_spec.rb +186 -0
  113. data/spec/active_record/turntable/finder_spec.rb +27 -0
  114. data/spec/active_record/turntable/mixer/fader_spec.rb +4 -0
  115. data/spec/active_record/turntable/mixer_spec.rb +114 -0
  116. data/spec/active_record/turntable/shard_spec.rb +21 -0
  117. data/spec/active_record/turntable_spec.rb +30 -0
  118. data/spec/config/database.yml +45 -0
  119. data/spec/config/turntable.yml +17 -0
  120. data/spec/fabricators/.gitkeep +0 -0
  121. data/spec/fabricators/turntable_fabricator.rb +14 -0
  122. data/spec/migrations/.gitkeep +0 -0
  123. data/spec/migrations/001_create_users.rb +16 -0
  124. data/spec/migrations/002_create_user_statuses.rb +16 -0
  125. data/spec/migrations/003_create_cards.rb +14 -0
  126. data/spec/migrations/004_create_cards_users.rb +15 -0
  127. data/spec/spec_helper.rb +23 -0
  128. data/spec/test_models.rb +27 -0
  129. data/spec/turntable_helper.rb +29 -0
  130. metadata +367 -0
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-Agent: *
5
+ # Disallow: /
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
File without changes
File without changes
File without changes
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rspec'
3
+ require File.join(File.dirname(__FILE__), '../../../spec/spec_helper')
4
+ require 'benchmark'
5
+
6
+ def setup_algorithm(n, alg = "Range")
7
+ config = {
8
+ "shards" => n.times.map do |i|
9
+ {"connection" => "connection_#{i}", "less_than" => (i+1) * 100}
10
+ end
11
+ }
12
+ "ActiveRecord::Turntable::Algorithm::#{alg}Algorithm".constantize.new(config)
13
+ end
14
+
15
+ Benchmark.bm(40) do |x|
16
+ %w(Range RangeBsearch).each do |alg|
17
+ [2, 4, 8, 16, 32, 64, 128, 256, 512].map do |n|
18
+ algorithm = setup_algorithm(n, alg)
19
+ x.report("#{alg}: selrand(#{n}) * 1000") {
20
+ 1000.times do
21
+ algorithm.calculate(rand(n*100))
22
+ end
23
+ }
24
+ x.report("#{alg}: sellast(#{n}) * 1000") {
25
+ 1000.times do
26
+ algorithm.calculate(n*100-1)
27
+ end
28
+ }
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+ require 'logger'
3
+
4
+ describe ActiveRecord::Turntable::ActiveRecordExt::CleverLoad do
5
+ before(:all) do
6
+ reload_turntable!(File.join(File.dirname(__FILE__), "../../../config/turntable.yml"))
7
+ end
8
+
9
+ before(:each) do
10
+ establish_connection_to("test")
11
+ truncate_shard
12
+
13
+ @user1 = User.new({:nickname => 'user1'})
14
+ @user1.id = 1
15
+ @user1.save
16
+ @user1_status = @user1.create_user_status(:hp => 10, :mp => 10)
17
+ @user2 = User.new({:nickname => 'user2'})
18
+ @user2.id = 2
19
+ @user2.save
20
+ @user2_status = @user2.create_user_status(:hp => 20, :mp => 10)
21
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
22
+ end
23
+
24
+ context "When a model has has_one relation" do
25
+ context "When call clever_load!" do
26
+ before(:each) do
27
+ @strio = StringIO.new
28
+ ActiveRecord::Base.logger = Logger.new(@strio)
29
+ @users = User.clever_load!(:user_status)
30
+ puts @strio.string
31
+ end
32
+ it "should send merged user_status select query" do
33
+ @strio.string.should =~ //
34
+ end
35
+
36
+ it "should target loaded" do
37
+ @users.each do |user|
38
+ user.association(:user_status).loaded?.should be_true
39
+ end
40
+ end
41
+
42
+ it "should assigned reverse relation" do
43
+ pending "should be implemented"
44
+ end
45
+ end
46
+ end
47
+
48
+ context "When a model has belongs_to relation" do
49
+ context "When call clever_load!" do
50
+ before(:each) do
51
+ @strio = StringIO.new
52
+ @strio = StringIO.new
53
+ ActiveRecord::Base.logger = Logger.new(@strio)
54
+ @user_statuses = UserStatus.clever_load!(:user)
55
+ puts @strio.string
56
+ end
57
+
58
+ it "should send merged user_status select query" do
59
+ @strio.string.should =~ //
60
+ end
61
+
62
+ it "should target loaded" do
63
+ @user_statuses.each do |user_status|
64
+ user_status.association(:user).loaded?.should be_true
65
+ end
66
+ end
67
+
68
+ it "should assigned reverse relation" do
69
+ pending "should be implemented"
70
+ end
71
+ end
72
+ end
73
+
74
+ context "When a model has has_many relation" do
75
+ it "should send query only 2 times." do
76
+ pending "not implemented yet"
77
+ end
78
+ end
79
+
80
+
81
+ end
@@ -0,0 +1,151 @@
1
+ require 'spec_helper'
2
+ require 'logger'
3
+
4
+ describe ActiveRecord::Turntable::ActiveRecordExt::Persistence do
5
+ before(:all) do
6
+ reload_turntable!(File.join(File.dirname(__FILE__), "../../../config/turntable.yml"))
7
+ end
8
+
9
+ before(:each) do
10
+ establish_connection_to("test")
11
+ truncate_shard
12
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
13
+ end
14
+
15
+ let(:user) {
16
+ u = User.new({:nickname => 'foobar'})
17
+ u.id = 1
18
+ u.updated_at = Time.current - 1.day
19
+ u.save
20
+ u
21
+ }
22
+ let(:user_status){
23
+ stat = user.create_user_status(:hp => 10, :mp => 10)
24
+ stat.updated_at = Time.current - 1.day
25
+ stat.save
26
+ stat
27
+ }
28
+ let(:card){
29
+ Card.create!(:name => 'foobar')
30
+ }
31
+
32
+ context "When the model is sharded by surrogate key" do
33
+ it "should not changed from normal operation when updating" do
34
+ user.nickname = "fizzbuzz"
35
+ strio = StringIO.new
36
+ ActiveRecord::Base.logger = Logger.new(strio)
37
+ expect {
38
+ user.save!
39
+ }.to_not raise_error
40
+ strio.string.should =~ /WHERE `users`\.`id` = #{user.id}[^\s]*$/
41
+ end
42
+
43
+ it "should change updated_at when updating" do
44
+ user.nickname = "fizzbuzz"
45
+
46
+ lambda {
47
+ user.save!
48
+ }.should change(user, :updated_at)
49
+ end
50
+
51
+ it "should not changed from normal operation when destroying" do
52
+ strio = StringIO.new
53
+ ActiveRecord::Base.logger = Logger.new(strio)
54
+ expect {
55
+ user.destroy
56
+ }.to_not raise_error
57
+ strio.string.should =~ /WHERE `users`\.`id` = #{user.id}[^\s]*$/
58
+ end
59
+ end
60
+
61
+ context "When called Callbacks" do
62
+ before do
63
+ class ::User
64
+ after_destroy :on_destroy
65
+ after_save :on_update
66
+
67
+ def on_destroy
68
+ end
69
+
70
+ def on_update
71
+ end
72
+ end
73
+ end
74
+
75
+ context "on update once" do
76
+ it "callback should be called once" do
77
+ mock(user).on_update.times(1)
78
+ user.save
79
+ end
80
+ end
81
+ context "on destroy once" do
82
+ it "callback should be called once" do
83
+ mock(user).on_destroy.times(1)
84
+ user.destroy
85
+ end
86
+ end
87
+ end
88
+
89
+ context "When the model is sharded by other key" do
90
+ it "should send shard_key condition when updating" do
91
+ user_status.hp = 20
92
+
93
+ strio = StringIO.new
94
+ ActiveRecord::Base.logger = Logger.new(strio)
95
+ expect {
96
+ user_status.save!
97
+ }.to_not raise_error
98
+ strio.string.should =~ /WHERE `user_statuses`\.`id` = #{user_status.id} AND `user_statuses`\.`user_id` = #{user_status.user_id}[^\s]*$/
99
+ end
100
+
101
+ it "should change updated_at when updating" do
102
+ user_status.hp = 20
103
+
104
+ lambda {
105
+ user_status.save!
106
+ }.should change(user_status, :updated_at)
107
+ end
108
+
109
+ it "should send shard_key condition when destroying" do
110
+ strio = StringIO.new
111
+ ActiveRecord::Base.logger = Logger.new(strio)
112
+ expect {
113
+ user_status.destroy
114
+ }.to_not raise_error
115
+ puts strio.string
116
+ strio.string.should =~ /WHERE `user_statuses`\.`id` = #{user_status.id} AND `user_statuses`\.`user_id` = #{user_status.user_id}[^\s]*$/
117
+ end
118
+
119
+ it "should warn when creating without shard_key" do
120
+ pending "doesn't need to implemented soon"
121
+ end
122
+ end
123
+
124
+ context "When the model is not sharded" do
125
+ it "should not send shard_key condition when updating" do
126
+ card.name = "barbaz"
127
+ strio = StringIO.new
128
+ ActiveRecord::Base.logger = Logger.new(strio)
129
+ expect {
130
+ card.save!
131
+ }.to_not raise_error
132
+ strio.string.should =~ /WHERE `cards`\.`id` = #{card.id}[^\s]*$/
133
+ end
134
+
135
+ it "should not send shard_key condition when destroying" do
136
+ strio = StringIO.new
137
+ ActiveRecord::Base.logger = Logger.new(strio)
138
+ expect {
139
+ card.destroy
140
+ }.to_not raise_error
141
+ strio.string.should =~ /WHERE `cards`\.`id` = #{card.id}[^\s]*$/
142
+ end
143
+ end
144
+
145
+ context "When call reload" do
146
+ subject { user_status.reload }
147
+ it { should be_instance_of(UserStatus)}
148
+ it { should == user_status }
149
+ end
150
+
151
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRecord::Turntable::Algorithm::RangeAlgorithm do
4
+ before(:all) do
5
+ reload_turntable!(File.join(File.dirname(__FILE__), "../../../config/turntable.yml"))
6
+ end
7
+
8
+ context "When initialized" do
9
+ before do
10
+ @alg = ActiveRecord::Turntable::Algorithm::RangeAlgorithm.new(ActiveRecord::Base.turntable_config[:clusters][:user_cluster])
11
+ end
12
+
13
+ context "#calculate with 1" do
14
+ subject { @alg.calculate(1) }
15
+ it { should == ActiveRecord::Base.turntable_config[:clusters][:user_cluster][:shards][0][:connection] }
16
+ end
17
+
18
+ context "#calculate with 19999" do
19
+ subject { @alg.calculate(19999) }
20
+ it { should == ActiveRecord::Base.turntable_config[:clusters][:user_cluster][:shards][0][:connection] }
21
+ end
22
+
23
+ context "#calculate with 20000" do
24
+ subject { @alg.calculate(20000) }
25
+ it { should == ActiveRecord::Base.turntable_config[:clusters][:user_cluster][:shards][1][:connection] }
26
+ end
27
+
28
+ context "#calculate with 10000000" do
29
+ it "raises ActiveRecord::Turntable::CannotSpecifyShardError" do
30
+ lambda { @alg.calculate(10000000) }.should raise_error(ActiveRecord::Turntable::CannotSpecifyShardError)
31
+ end
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRecord::Turntable::Algorithm do
4
+ before(:all) do
5
+ reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
6
+ end
7
+
8
+ describe ActiveRecord::Turntable::Algorithm::RangeBsearchAlgorithm do
9
+ let(:algorithm) { ActiveRecord::Turntable::Algorithm::RangeBsearchAlgorithm.new(ActiveRecord::Base.turntable_config[:clusters][:user_cluster]) }
10
+ context "#calculate" do
11
+ it "called with 1 returns user_shard_1" do
12
+ algorithm.calculate(1).should == "user_shard_1"
13
+ end
14
+
15
+ it "called with 100000 returns user_shard_3" do
16
+ algorithm.calculate(100000).should == "user_shard_3"
17
+ end
18
+ end
19
+
20
+ context "#calculate_used_shards_with_weight" do
21
+ it "called with 10 returns 1 item" do
22
+ algorithm.calculate_used_shards_with_weight(10).should have(1).items
23
+ end
24
+
25
+ it "called with 10 returns {\"user_shard_1\" => 10}" do
26
+ algorithm.calculate_used_shards_with_weight(10).should == {"user_shard_1" => 10}
27
+ end
28
+
29
+ it "called with 65000 returns 2 items" do
30
+ algorithm.calculate_used_shards_with_weight(65000).should have(2).items
31
+ end
32
+
33
+ it "called with 65000 returns {\"user_shard_1\" => 39999, \"user_shard_2\" => 25001}" do
34
+ algorithm.calculate_used_shards_with_weight(65000).should == {"user_shard_1" => 39999, "user_shard_2" => 25001}
35
+ end
36
+ end
37
+ end
38
+
39
+ describe ActiveRecord::Turntable::Algorithm::RangeAlgorithm do
40
+ let(:algorithm) { ActiveRecord::Turntable::Algorithm::RangeAlgorithm.new(ActiveRecord::Base.turntable_config[:clusters][:user_cluster]) }
41
+ context "#calculate" do
42
+ it "called with 1 returns user_shard_1" do
43
+ algorithm.calculate(1).should == "user_shard_1"
44
+ end
45
+
46
+ it "called with 100000 returns user_shard_3" do
47
+ algorithm.calculate(100000).should == "user_shard_3"
48
+ end
49
+ end
50
+
51
+ context "#calculate_used_shards_with_weight" do
52
+ it "called with 10 returns 1 item" do
53
+ algorithm.calculate_used_shards_with_weight(10).should have(1).items
54
+ end
55
+
56
+ it "called with 10 returns {\"user_shard_1\" => 10}" do
57
+ algorithm.calculate_used_shards_with_weight(10).should == {"user_shard_1" => 10}
58
+ end
59
+
60
+ it "called with 65000 returns 2 items" do
61
+ algorithm.calculate_used_shards_with_weight(65000).should have(2).items
62
+ end
63
+
64
+ it "called with 65000 returns {\"user_shard_1\" => 39999, \"user_shard_2\" => 25001}" do
65
+ algorithm.calculate_used_shards_with_weight(65000).should == {"user_shard_1" => 39999, "user_shard_2" => 25001}
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRecord::Turntable::Base do
4
+ before(:all) do
5
+ reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
6
+ end
7
+
8
+ context "When installed to ActiveRecord::Base" do
9
+ it "ActiveRecord::Base respond_to 'turntable'" do
10
+ ActiveRecord::Base.should respond_to(:turntable)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRecord::Turntable::Cluster do
4
+ before(:all) do
5
+ reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
6
+ end
7
+
8
+ context "When initialized" do
9
+ before do
10
+ establish_connection_to("test")
11
+ truncate_shard
12
+ end
13
+
14
+ subject { ActiveRecord::Turntable::Cluster.new(User, ActiveRecord::Base.turntable_config[:clusters][:user_cluster]) }
15
+ its(:klass) { should == User }
16
+ its(:shards) { should have(3).items }
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRecord::Turntable::Config do
4
+ before(:all) do
5
+ reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
6
+ end
7
+
8
+ subject { ActiveRecord::Turntable::Config }
9
+
10
+ it "has config hash" do
11
+ subject.instance.instance_variable_get(:@config).should be_an_kind_of(Hash)
12
+ end
13
+
14
+ it "has cluster setting" do
15
+ subject[:clusters][:user_cluster].should be_instance_of(ActiveSupport::HashWithIndifferentAccess)
16
+ end
17
+ end