Skip to content
Browse files

test ConnectionProxy correctly delegates to master vs. slave

  • Loading branch information...
1 parent 3e2af08 commit cc319af7d086c49bb8c2b31138e2baac51c29236 @mislav committed Apr 12, 2009
Showing with 71 additions and 13 deletions.
  1. +13 −10 lib/active_reload/connection_proxy.rb
  2. +58 −3 test/connection_proxy_test.rb
View
23 lib/active_reload/connection_proxy.rb
@@ -43,8 +43,13 @@ def self.configuration_for(type)
def self.setup_for(master, slave = nil)
slave ||= ActiveRecord::Base
- slave.__send__(:include, ActiveRecordConnectionMethods)
- ActiveRecord::Observer.__send__(:include, ActiveReload::ObserverExtensions)
+
+ unless slave.respond_to?(:connection_proxy=)
+ slave.__send__(:include, ActiveRecordConnectionMethods)
+ end
+ unless ActiveRecord::Observer.instance_methods.include?('update_with_master')
+ ActiveRecord::Observer.__send__(:include, ActiveReload::ObserverExtensions)
+ end
# wire up MasterDatabase and SlaveDatabase
establish_connections
@@ -149,22 +154,20 @@ def reload_with_master(*args, &block)
end
end
- # extend observer to always use the master database
- # observers only get triggered on writes, so shouldn't be a performance hit
- # removes a race condition if you are using conditionals in the observer
+ # make observers always use the master database
module ObserverExtensions
def self.included(base)
- base.alias_method_chain :update, :masterdb
+ base.alias_method_chain :update, :master
end
# Send observed_method(object) if the method exists.
- def update_with_masterdb(observed_method, object) #:nodoc:
+ def update_with_master(observed_method, object)
if object.respond_to?(:connection) && object.connection.respond_to?(:with_master)
- object.class.connection.with_master do
- update_without_masterdb(observed_method, object)
+ object.connection.with_master do
+ update_without_master(observed_method, object)
end
else
- update_without_masterdb(observed_method, object)
+ update_without_master(observed_method, object)
end
end
end
View
61 test/connection_proxy_test.rb
@@ -1,4 +1,5 @@
require 'test/unit'
+require 'mocha'
require 'active_support'
require 'active_support/test_case'
require 'active_record'
@@ -13,7 +14,6 @@ def self.env() RAILS_ENV end
class MasochismTestCase < ActiveSupport::TestCase
setup do
ActiveRecord::Base.configurations = default_configuration
- ActiveRecord::Base.establish_connection
end
def self.default_configuration
@@ -24,16 +24,20 @@ def config
ActiveRecord::Base.configurations
end
+ def connection
+ ActiveRecord::Base.connection
+ end
+
def enable_masochism
ActiveReload::ConnectionProxy.setup!
end
def master
- ActiveRecord::Base.connection.master
+ connection.master
end
def slave
- ActiveRecord::Base.connection.slave
+ connection.slave
end
end
@@ -92,3 +96,54 @@ def test_slave_database_within_environment
assert_equal [], slave.tables, 'Master and Slave should be different databases'
end
end
+
+class DelegatingTest < MasochismTestCase
+ setup :place_mocks
+
+ def place_mocks
+ # this doesn't actually establish any connections,
+ # but we don't need them
+ enable_masochism
+ @master = mock
+ @slave = mock
+ connection.stubs(:master).returns(@master)
+ connection.stubs(:slave).returns(@slave)
+ end
+
+ def test_connection_is_a_proxy
+ assert_equal 'ActiveReload::ConnectionProxy', connection.class.name
+ end
+
+ def test_reads_go_to_slave
+ @slave.expects(:select_rows).with('SELECT').returns(['bar'])
+ assert_equal ['bar'], connection.select_rows('SELECT')
+ end
+
+ def test_writes_go_to_master
+ @master.expects(:insert).with('INSERT').returns(1)
+ assert_equal 1, connection.insert('INSERT')
+ end
+
+ def test_execute_gos_to_master
+ @master.expects(:execute).with('QUERY').returns('result')
+ assert_equal 'result', connection.execute('QUERY')
+ end
+
+ def test_with_master
+ @master.expects(:select_rows).returns(['foo'])
+ @slave.expects(:select_rows).returns(['bar'])
+
+ connection.with_master do
+ assert_equal ['foo'], connection.select_rows
+ end
+ assert_equal ['bar'], connection.select_rows
+ end
+
+ def test_transactions_run_on_master
+ @master.expects(:transaction).with({:foo => 'bar'})
+
+ ActiveRecord::Base.transaction(:foo => 'bar') do
+ # hardcore transaction stuff
+ end
+ end
+end

0 comments on commit cc319af

Please sign in to comment.
Something went wrong with that request. Please try again.