X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=vendor%2Frails%2Factiverecord%2Ftest%2Fcases%2Ftransactions_test.rb;fp=vendor%2Frails%2Factiverecord%2Ftest%2Fcases%2Ftransactions_test.rb;h=0000000000000000000000000000000000000000;hb=36d9f3351a3b4e8159279445190e2287ffdea86c;hp=f6533b539640aa2c32261629ba0854b134389609;hpb=913cf6054b1d29b5d2f5e620304af7ee77cc1f1f;p=feedcatcher.git diff --git a/vendor/rails/activerecord/test/cases/transactions_test.rb b/vendor/rails/activerecord/test/cases/transactions_test.rb deleted file mode 100644 index f6533b5..0000000 --- a/vendor/rails/activerecord/test/cases/transactions_test.rb +++ /dev/null @@ -1,522 +0,0 @@ -require "cases/helper" -require 'models/topic' -require 'models/reply' -require 'models/developer' -require 'models/book' - -class TransactionTest < ActiveRecord::TestCase - self.use_transactional_fixtures = false - fixtures :topics, :developers - - def setup - @first, @second = Topic.find(1, 2).sort_by { |t| t.id } - end - - def test_successful - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - end - - assert Topic.find(1).approved?, "First should have been approved" - assert !Topic.find(2).approved?, "Second should have been unapproved" - end - - def transaction_with_return - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - return - end - end - - def test_successful_with_return - class << Topic.connection - alias :real_commit_db_transaction :commit_db_transaction - def commit_db_transaction - $committed = true - real_commit_db_transaction - end - end - - $committed = false - transaction_with_return - assert $committed - - assert Topic.find(1).approved?, "First should have been approved" - assert !Topic.find(2).approved?, "Second should have been unapproved" - ensure - class << Topic.connection - alias :commit_db_transaction :real_commit_db_transaction rescue nil - end - end - - def test_successful_with_instance_method - @first.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - end - - assert Topic.find(1).approved?, "First should have been approved" - assert !Topic.find(2).approved?, "Second should have been unapproved" - end - - def test_failing_on_exception - begin - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - raise "Bad things!" - end - rescue - # caught it - end - - assert @first.approved?, "First should still be changed in the objects" - assert !@second.approved?, "Second should still be changed in the objects" - - assert !Topic.find(1).approved?, "First shouldn't have been approved" - assert Topic.find(2).approved?, "Second should still be approved" - end - - def test_raising_exception_in_callback_rollbacks_in_save - add_exception_raising_after_save_callback_to_topic - - begin - @first.approved = true - @first.save - flunk - rescue => e - assert_equal "Make the transaction rollback", e.message - assert !Topic.find(1).approved? - ensure - remove_exception_raising_after_save_callback_to_topic - end - end - - def test_cancellation_from_before_destroy_rollbacks_in_destroy - add_cancelling_before_destroy_with_db_side_effect_to_topic - begin - nbooks_before_destroy = Book.count - status = @first.destroy - assert !status - assert_nothing_raised(ActiveRecord::RecordNotFound) { @first.reload } - assert_equal nbooks_before_destroy, Book.count - ensure - remove_cancelling_before_destroy_with_db_side_effect_to_topic - end - end - - def test_cancellation_from_before_filters_rollbacks_in_save - %w(validation save).each do |filter| - send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") - begin - nbooks_before_save = Book.count - original_author_name = @first.author_name - @first.author_name += '_this_should_not_end_up_in_the_db' - status = @first.save - assert !status - assert_equal original_author_name, @first.reload.author_name - assert_equal nbooks_before_save, Book.count - ensure - send("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") - end - end - end - - def test_cancellation_from_before_filters_rollbacks_in_save! - %w(validation save).each do |filter| - send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") - begin - nbooks_before_save = Book.count - original_author_name = @first.author_name - @first.author_name += '_this_should_not_end_up_in_the_db' - @first.save! - flunk - rescue => e - assert_equal original_author_name, @first.reload.author_name - assert_equal nbooks_before_save, Book.count - ensure - send("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") - end - end - end - - def test_callback_rollback_in_create - new_topic = Topic.new( - :title => "A new topic", - :author_name => "Ben", - :author_email_address => "ben@example.com", - :written_on => "2003-07-16t15:28:11.2233+01:00", - :last_read => "2004-04-15", - :bonus_time => "2005-01-30t15:28:00.00+01:00", - :content => "Have a nice day", - :approved => false) - new_record_snapshot = new_topic.new_record? - id_present = new_topic.has_attribute?(Topic.primary_key) - id_snapshot = new_topic.id - - # Make sure the second save gets the after_create callback called. - 2.times do - begin - add_exception_raising_after_create_callback_to_topic - new_topic.approved = true - new_topic.save - flunk - rescue => e - assert_equal "Make the transaction rollback", e.message - assert_equal new_record_snapshot, new_topic.new_record?, "The topic should have its old new_record value" - assert_equal id_snapshot, new_topic.id, "The topic should have its old id" - assert_equal id_present, new_topic.has_attribute?(Topic.primary_key) - ensure - remove_exception_raising_after_create_callback_to_topic - end - end - end - - def test_nested_explicit_transactions - Topic.transaction do - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - end - end - - assert Topic.find(1).approved?, "First should have been approved" - assert !Topic.find(2).approved?, "Second should have been unapproved" - end - - def test_manually_rolling_back_a_transaction - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - - raise ActiveRecord::Rollback - end - - assert @first.approved?, "First should still be changed in the objects" - assert !@second.approved?, "Second should still be changed in the objects" - - assert !Topic.find(1).approved?, "First shouldn't have been approved" - assert Topic.find(2).approved?, "Second should still be approved" - end - - def test_invalid_keys_for_transaction - assert_raise ArgumentError do - Topic.transaction :nested => true do - end - end - end - - def test_force_savepoint_in_nested_transaction - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save! - @second.save! - - begin - Topic.transaction :requires_new => true do - @first.happy = false - @first.save! - raise - end - rescue - end - end - - assert @first.reload.approved? - assert !@second.reload.approved? - end if Topic.connection.supports_savepoints? - - def test_no_savepoint_in_nested_transaction_without_force - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save! - @second.save! - - begin - Topic.transaction do - @first.approved = false - @first.save! - raise - end - rescue - end - end - - assert !@first.reload.approved? - assert !@second.reload.approved? - end if Topic.connection.supports_savepoints? - - def test_many_savepoints - Topic.transaction do - @first.content = "One" - @first.save! - - begin - Topic.transaction :requires_new => true do - @first.content = "Two" - @first.save! - - begin - Topic.transaction :requires_new => true do - @first.content = "Three" - @first.save! - - begin - Topic.transaction :requires_new => true do - @first.content = "Four" - @first.save! - raise - end - rescue - end - - @three = @first.reload.content - raise - end - rescue - end - - @two = @first.reload.content - raise - end - rescue - end - - @one = @first.reload.content - end - - assert_equal "One", @one - assert_equal "Two", @two - assert_equal "Three", @three - end if Topic.connection.supports_savepoints? - - def test_rollback_when_commit_raises - Topic.connection.expects(:begin_db_transaction) - Topic.connection.expects(:commit_db_transaction).raises('OH NOES') - Topic.connection.expects(:outside_transaction?).returns(false) - Topic.connection.expects(:rollback_db_transaction) - - assert_raise RuntimeError do - Topic.transaction do - # do nothing - end - end - end - - if current_adapter?(:PostgreSQLAdapter) && defined?(PGconn::PQTRANS_IDLE) - def test_outside_transaction_works - assert Topic.connection.outside_transaction? - Topic.connection.begin_db_transaction - assert !Topic.connection.outside_transaction? - Topic.connection.rollback_db_transaction - assert Topic.connection.outside_transaction? - end - - def test_rollback_wont_be_executed_if_no_transaction_active - assert_raise RuntimeError do - Topic.transaction do - Topic.connection.rollback_db_transaction - Topic.connection.expects(:rollback_db_transaction).never - raise "Rails doesn't scale!" - end - end - end - - def test_open_transactions_count_is_reset_to_zero_if_no_transaction_active - Topic.transaction do - Topic.transaction do - Topic.connection.rollback_db_transaction - end - assert_equal 0, Topic.connection.open_transactions - end - assert_equal 0, Topic.connection.open_transactions - end - end - - def test_sqlite_add_column_in_transaction - return true unless current_adapter?(:SQLite3Adapter, :SQLiteAdapter) - - # Test first if column creation/deletion works correctly when no - # transaction is in place. - # - # We go back to the connection for the column queries because - # Topic.columns is cached and won't report changes to the DB - - assert_nothing_raised do - Topic.reset_column_information - Topic.connection.add_column('topics', 'stuff', :string) - assert Topic.column_names.include?('stuff') - - Topic.reset_column_information - Topic.connection.remove_column('topics', 'stuff') - assert !Topic.column_names.include?('stuff') - end - - if Topic.connection.supports_ddl_transactions? - assert_nothing_raised do - Topic.transaction { Topic.connection.add_column('topics', 'stuff', :string) } - end - else - Topic.transaction do - assert_raise(ActiveRecord::StatementInvalid) { Topic.connection.add_column('topics', 'stuff', :string) } - raise ActiveRecord::Rollback - end - end - end - - private - def add_exception_raising_after_save_callback_to_topic - Topic.class_eval { def after_save() raise "Make the transaction rollback" end } - end - - def remove_exception_raising_after_save_callback_to_topic - Topic.class_eval { remove_method :after_save } - end - - def add_exception_raising_after_create_callback_to_topic - Topic.class_eval { def after_create() raise "Make the transaction rollback" end } - end - - def remove_exception_raising_after_create_callback_to_topic - Topic.class_eval { remove_method :after_create } - end - - %w(validation save destroy).each do |filter| - define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do - Topic.class_eval "def before_#{filter}() Book.create; false end" - end - - define_method("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") do - Topic.class_eval "remove_method :before_#{filter}" - end - end -end - -class TransactionsWithTransactionalFixturesTest < ActiveRecord::TestCase - self.use_transactional_fixtures = true - fixtures :topics - - def test_automatic_savepoint_in_outer_transaction - @first = Topic.find(1) - - begin - Topic.transaction do - @first.approved = true - @first.save! - raise - end - rescue - assert !@first.reload.approved? - end - end - - def test_no_automatic_savepoint_for_inner_transaction - @first = Topic.find(1) - - Topic.transaction do - @first.approved = true - @first.save! - - begin - Topic.transaction do - @first.approved = false - @first.save! - raise - end - rescue - end - end - - assert !@first.reload.approved? - end -end if Topic.connection.supports_savepoints? - -if current_adapter?(:PostgreSQLAdapter) - class ConcurrentTransactionTest < TransactionTest - use_concurrent_connections - - # This will cause transactions to overlap and fail unless they are performed on - # separate database connections. - def test_transaction_per_thread - assert_nothing_raised do - threads = (1..3).map do - Thread.new do - Topic.transaction do - topic = Topic.find(1) - topic.approved = !topic.approved? - topic.save! - topic.approved = !topic.approved? - topic.save! - end - end - end - - threads.each { |t| t.join } - end - end - - # Test for dirty reads among simultaneous transactions. - def test_transaction_isolation__read_committed - # Should be invariant. - original_salary = Developer.find(1).salary - temporary_salary = 200000 - - assert_nothing_raised do - threads = (1..3).map do - Thread.new do - Developer.transaction do - # Expect original salary. - dev = Developer.find(1) - assert_equal original_salary, dev.salary - - dev.salary = temporary_salary - dev.save! - - # Expect temporary salary. - dev = Developer.find(1) - assert_equal temporary_salary, dev.salary - - dev.salary = original_salary - dev.save! - - # Expect original salary. - dev = Developer.find(1) - assert_equal original_salary, dev.salary - end - end - end - - # Keep our eyes peeled. - threads << Thread.new do - 10.times do - sleep 0.05 - Developer.transaction do - # Always expect original salary. - assert_equal original_salary, Developer.find(1).salary - end - end - end - - threads.each { |t| t.join } - end - - assert_equal original_salary, Developer.find(1).salary - end - end -end