aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/adapter_test_sqlserver.rb67
-rw-r--r--activerecord/test/locking_test.rb155
-rw-r--r--activerecord/test/migration_test.rb17
3 files changed, 157 insertions, 82 deletions
diff --git a/activerecord/test/adapter_test_sqlserver.rb b/activerecord/test/adapter_test_sqlserver.rb
new file mode 100644
index 0000000000..11f244e9f7
--- /dev/null
+++ b/activerecord/test/adapter_test_sqlserver.rb
@@ -0,0 +1,67 @@
+require 'abstract_unit'
+require 'fixtures/default'
+require 'fixtures/post'
+require 'fixtures/task'
+
+class SqlServerAdapterTest < Test::Unit::TestCase
+ fixtures :posts, :tasks
+
+ def setup
+ @connection = ActiveRecord::Base.connection
+ end
+
+ def test_execute_without_block_closes_statement
+ assert_all_statements_used_are_closed do
+ @connection.execute("SELECT 1")
+ end
+ end
+
+ def test_execute_with_block_closes_statement
+ assert_all_statements_used_are_closed do
+ @connection.execute("SELECT 1") do |sth|
+ assert !sth.finished?, "Statement should still be alive within block"
+ end
+ end
+ end
+
+ def test_insert_with_identity_closes_statement
+ assert_all_statements_used_are_closed do
+ @connection.insert("INSERT INTO accounts ([id], [firm_id],[credit_limit]) values (999, 1, 50)")
+ end
+ end
+
+ def test_insert_without_identity_closes_statement
+ assert_all_statements_used_are_closed do
+ @connection.insert("INSERT INTO accounts ([firm_id],[credit_limit]) values (1, 50)")
+ end
+ end
+
+ def test_active_closes_statement
+ assert_all_statements_used_are_closed do
+ @connection.active?
+ end
+ end
+
+ def assert_all_statements_used_are_closed(&block)
+ existing_handles = []
+ ObjectSpace.each_object(DBI::StatementHandle) {|handle| existing_handles << handle}
+ GC.disable
+
+ yield
+
+ used_handles = []
+ ObjectSpace.each_object(DBI::StatementHandle) {|handle| used_handles << handle unless existing_handles.include? handle}
+
+ assert_block "No statements were used within given block" do
+ used_handles.size > 0
+ end
+
+ ObjectSpace.each_object(DBI::StatementHandle) do |handle|
+ assert_block "Statement should have been closed within given block" do
+ handle.finished?
+ end
+ end
+ ensure
+ GC.enable
+ end
+end
diff --git a/activerecord/test/locking_test.rb b/activerecord/test/locking_test.rb
index 58c34a69e3..00df4bb8e4 100644
--- a/activerecord/test/locking_test.rb
+++ b/activerecord/test/locking_test.rb
@@ -63,91 +63,96 @@ end
# is so cumbersome. Will deadlock Ruby threads if the underlying db.execute
# blocks, so separate script called by Kernel#system is needed.
# (See exec vs. async_exec in the PostgreSQL adapter.)
-class PessimisticLockingTest < Test::Unit::TestCase
- self.use_transactional_fixtures = false
- fixtures :people
- def setup
- @allow_concurrency = ActiveRecord::Base.allow_concurrency
- ActiveRecord::Base.allow_concurrency = true
- end
-
- def teardown
- ActiveRecord::Base.allow_concurrency = @allow_concurrency
- end
+# TODO: The SQL Server adapter currently has no support for pessimistic locking
- # Test that the adapter doesn't blow up on add_lock!
- def test_sane_find_with_lock
- assert_nothing_raised do
- Person.transaction do
- Person.find 1, :lock => true
- end
+unless current_adapter?(:SQLServerAdapter)
+ class PessimisticLockingTest < Test::Unit::TestCase
+ self.use_transactional_fixtures = false
+ fixtures :people
+
+ def setup
+ @allow_concurrency = ActiveRecord::Base.allow_concurrency
+ ActiveRecord::Base.allow_concurrency = true
end
- end
-
- # Test no-blowup for scoped lock.
- def test_sane_find_with_lock
- assert_nothing_raised do
- Person.transaction do
- Person.with_scope(:find => { :lock => true }) do
- Person.find 1
+
+ def teardown
+ ActiveRecord::Base.allow_concurrency = @allow_concurrency
+ end
+
+ # Test that the adapter doesn't blow up on add_lock!
+ def test_sane_find_with_lock
+ assert_nothing_raised do
+ Person.transaction do
+ Person.find 1, :lock => true
end
end
end
- end
-
- # Locking a record reloads it.
- def test_sane_lock_method
- assert_nothing_raised do
- Person.transaction do
- person = Person.find 1
- old, person.first_name = person.first_name, 'fooman'
- person.lock!
- assert_equal old, person.first_name
+
+ # Test no-blowup for scoped lock.
+ def test_sane_find_with_lock
+ assert_nothing_raised do
+ Person.transaction do
+ Person.with_scope(:find => { :lock => true }) do
+ Person.find 1
+ end
+ end
end
end
- end
-
- if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
- def test_no_locks_no_wait
- first, second = duel { Person.find 1 }
- assert first.end > second.end
- end
-
- def test_second_lock_waits
- assert [0.2, 1, 5].any? { |zzz|
- first, second = duel(zzz) { Person.find 1, :lock => true }
- second.end > first.end
- }
+
+ # Locking a record reloads it.
+ def test_sane_lock_method
+ assert_nothing_raised do
+ Person.transaction do
+ person = Person.find 1
+ old, person.first_name = person.first_name, 'fooman'
+ person.lock!
+ assert_equal old, person.first_name
+ end
+ end
end
-
- protected
- def duel(zzz = 5)
- t0, t1, t2, t3 = nil, nil, nil, nil
-
- a = Thread.new do
- t0 = Time.now
- Person.transaction do
- yield
- sleep zzz # block thread 2 for zzz seconds
+
+ if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
+ def test_no_locks_no_wait
+ first, second = duel { Person.find 1 }
+ assert first.end > second.end
+ end
+
+ def test_second_lock_waits
+ assert [0.2, 1, 5].any? { |zzz|
+ first, second = duel(zzz) { Person.find 1, :lock => true }
+ second.end > first.end
+ }
+ end
+
+ protected
+ def duel(zzz = 5)
+ t0, t1, t2, t3 = nil, nil, nil, nil
+
+ a = Thread.new do
+ t0 = Time.now
+ Person.transaction do
+ yield
+ sleep zzz # block thread 2 for zzz seconds
+ end
+ t1 = Time.now
end
- t1 = Time.now
- end
-
- b = Thread.new do
- sleep zzz / 2.0 # ensure thread 1 tx starts first
- t2 = Time.now
- Person.transaction { yield }
- t3 = Time.now
+
+ b = Thread.new do
+ sleep zzz / 2.0 # ensure thread 1 tx starts first
+ t2 = Time.now
+ Person.transaction { yield }
+ t3 = Time.now
+ end
+
+ a.join
+ b.join
+
+ assert t1 > t0 + zzz
+ assert t2 > t0
+ assert t3 > t2
+ [t0.to_f..t1.to_f, t2.to_f..t3.to_f]
end
-
- a.join
- b.join
-
- assert t1 > t0 + zzz
- assert t2 > t0
- assert t3 > t2
- [t0.to_f..t1.to_f, t2.to_f..t3.to_f]
- end
+ end
end
end
diff --git a/activerecord/test/migration_test.rb b/activerecord/test/migration_test.rb
index 3d4dfedf3e..649ee54439 100644
--- a/activerecord/test/migration_test.rb
+++ b/activerecord/test/migration_test.rb
@@ -39,8 +39,8 @@ if ActiveRecord::Base.connection.supports_migrations?
end
Reminder.reset_column_information
- %w(last_name key bio age height wealth birthday favorite_day male
- mail administrator).each do |column|
+ %w(last_name key bio age height wealth birthday favorite_day
+ male administrator).each do |column|
Person.connection.remove_column('people', column) rescue nil
end
Person.connection.remove_column("people", "first_name") rescue nil
@@ -177,11 +177,13 @@ if ActiveRecord::Base.connection.supports_migrations?
Person.connection.create_table :testings do |t|
t.column :foo, :string
end
- Person.connection.execute "insert into testings values (1, 'hello')"
+
+ con = Person.connection
+ Person.connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}) values (1, 'hello')"
assert_nothing_raised {Person.connection.add_column :testings, :bar, :string, :null => false, :default => "default" }
assert_raises(ActiveRecord::StatementInvalid) do
- Person.connection.execute "insert into testings values (2, 'hello', NULL)"
+ Person.connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) values (2, 'hello', NULL)"
end
ensure
Person.connection.drop_table :testings rescue nil
@@ -267,7 +269,7 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_equal Time, bob.birthday.class
if current_adapter?(:SQLServerAdapter, :OracleAdapter, :SybaseAdapter)
- # SQL Server, Sybase, and Oracle don't differentiate between date/time
+ # Sybase, and Oracle don't differentiate between date/time
assert_equal Time, bob.favorite_day.class
else
assert_equal Date, bob.favorite_day.class
@@ -355,7 +357,8 @@ if ActiveRecord::Base.connection.supports_migrations?
ActiveRecord::Base.connection.rename_table :octopuses, :octopi
# Using explicit id in insert for compatibility across all databases
- assert_nothing_raised { ActiveRecord::Base.connection.execute "INSERT INTO octopi VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')" }
+ con = ActiveRecord::Base.connection
+ assert_nothing_raised { con.execute "INSERT INTO octopi (#{con.quote_column_name('id')}, #{con.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')" }
assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', ActiveRecord::Base.connection.select_value("SELECT url FROM octopi WHERE id=1")
@@ -379,7 +382,7 @@ if ActiveRecord::Base.connection.supports_migrations?
old_columns = Topic.connection.columns(Topic.table_name, "#{name} Columns")
assert old_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true }
assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => false }
- new_columns = Topic.connection.columns(Topic.table_name, "#{name} Columns")
+ new_columns = Topic.connection.columns(Topic.table_name, "#{name} Columns")
assert_nil new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true }
assert new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == false }
assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => true }