summaryrefslogtreecommitdiff
path: root/modules/simpletest/tests/database_test.test
diff options
context:
space:
mode:
authorwebchick <webchick@24967.no-reply.drupal.org>2011-12-31 16:09:02 -0800
committerwebchick <webchick@24967.no-reply.drupal.org>2011-12-31 16:09:02 -0800
commitd74306729631ead14323638108e3dcdf5f926517 (patch)
treec0b63517798f274f4c9404b245b0175f3cb08b65 /modules/simpletest/tests/database_test.test
parent8703bb7b3d83f79c3a1453f17a8f4eb9da9f442f (diff)
downloadbrdo-d74306729631ead14323638108e3dcdf5f926517.tar.gz
brdo-d74306729631ead14323638108e3dcdf5f926517.tar.bz2
Issue follow-up #1007830 by Damien Tournoud, basic: Fixed Nested transactions throw exceptions when they got out of scope.
Diffstat (limited to 'modules/simpletest/tests/database_test.test')
-rw-r--r--modules/simpletest/tests/database_test.test145
1 files changed, 112 insertions, 33 deletions
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index 4d3a86886..7b15cf3fa 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -3436,35 +3436,89 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
*/
function testTransactionWithDdlStatement() {
// First, test that a commit works normally, even with DDL statements.
- try {
- $this->transactionOuterLayer('D', FALSE, TRUE);
-
- // Because we committed, the inserted rows should both be present.
- $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DavidD'))->fetchField();
- $this->assertIdentical($saved_age, '24', t('Can retrieve DavidD row after commit.'));
- $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DanielD'))->fetchField();
- $this->assertIdentical($saved_age, '19', t('Can retrieve DanielD row after commit.'));
- // The created table should also exist.
- $count = db_query('SELECT COUNT(id) FROM {database_test_1}')->fetchField();
- $this->assertIdentical($count, '0', t('Table was successfully created inside a transaction.'));
- }
- catch (Exception $e) {
- $this->fail((string) $e);
- }
+ $transaction = db_transaction();
+ $this->insertRow('row');
+ $this->executeDDLStatement();
+ unset($transaction);
+ $this->assertRowPresent('row');
- // If we rollback the transaction, an exception might be thrown.
- try {
- $this->transactionOuterLayer('E', TRUE, TRUE);
+ // Even in different order.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $this->executeDDLStatement();
+ $this->insertRow('row');
+ unset($transaction);
+ $this->assertRowPresent('row');
+
+ // Even with stacking.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $transaction2 = db_transaction();
+ $this->executeDDLStatement();
+ unset($transaction2);
+ $transaction3 = db_transaction();
+ $this->insertRow('row');
+ unset($transaction3);
+ unset($transaction);
+ $this->assertRowPresent('row');
+
+ // A transaction after a DDL statement should still work the same.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $transaction2 = db_transaction();
+ $this->executeDDLStatement();
+ unset($transaction2);
+ $transaction3 = db_transaction();
+ $this->insertRow('row');
+ $transaction3->rollback();
+ unset($transaction3);
+ unset($transaction);
+ $this->assertRowAbsent('row');
+
+ // The behavior of a rollback depends on the type of database server.
+ if (Database::getConnection()->supportsTransactionalDDL()) {
+ // For database servers that support transactional DDL, a rollback
+ // of a transaction including DDL statements should be possible.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $this->insertRow('row');
+ $this->executeDDLStatement();
+ $transaction->rollback();
+ unset($transaction);
+ $this->assertRowAbsent('row');
- // Because we rolled back, the inserted rows shouldn't be present.
- $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DavidE'))->fetchField();
- $this->assertNotIdentical($saved_age, '24', t('Cannot retrieve DavidE row after rollback.'));
- $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DanielE'))->fetchField();
- $this->assertNotIdentical($saved_age, '19', t('Cannot retrieve DanielE row after rollback.'));
+ // Including with stacking.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $transaction2 = db_transaction();
+ $this->executeDDLStatement();
+ unset($transaction2);
+ $transaction3 = db_transaction();
+ $this->insertRow('row');
+ unset($transaction3);
+ $transaction->rollback();
+ unset($transaction);
+ $this->assertRowAbsent('row');
}
- catch (Exception $e) {
- // An exception also lets the test pass.
- $this->assertTrue(true, t('Exception thrown on rollback after a DDL statement was executed.'));
+ else {
+ // For database servers that do not support transactional DDL,
+ // the DDL statement should commit the transaction stack.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $this->insertRow('row');
+ $this->executeDDLStatement();
+ // Rollback the outer transaction.
+ try {
+ $transaction->rollback();
+ unset($transaction);
+ // @TODO: an exception should be triggered here, but is not, because
+ // "ROLLBACK" fails silently in MySQL if there is no transaction active.
+ // $this->fail(t('Rolling back a transaction containing DDL should fail.'));
+ }
+ catch (DatabaseTransactionNoActiveException $e) {
+ $this->pass(t('Rolling back a transaction containing DDL should fail.'));
+ }
+ $this->assertRowPresent('row');
}
}
@@ -3480,6 +3534,24 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
}
/**
+ * Execute a DDL statement.
+ */
+ protected function executeDDLStatement() {
+ static $count = 0;
+ $table = array(
+ 'fields' => array(
+ 'id' => array(
+ 'type' => 'serial',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ ),
+ ),
+ 'primary key' => array('id'),
+ );
+ db_create_table('database_test_' . ++$count, $table);
+ }
+
+ /**
* Start over for a new test.
*/
protected function cleanUp() {
@@ -3523,8 +3595,8 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
* Test transaction stacking and commit / rollback.
*/
function testTransactionStacking() {
- // This test won't work right if transactions are supported.
- if (Database::getConnection()->supportsTransactions()) {
+ // This test won't work right if transactions are not supported.
+ if (!Database::getConnection()->supportsTransactions()) {
return;
}
@@ -3603,26 +3675,33 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
$this->insertRow('outer');
$transaction2 = db_transaction();
$this->insertRow('inner');
+ $transaction3 = db_transaction();
+ $this->insertRow('inner2');
// Rollback the outer transaction.
try {
$transaction->rollback();
unset($transaction);
$this->fail(t('Rolling back the outer transaction while the inner transaction is active resulted in an exception.'));
}
- catch (Exception $e) {
+ catch (DatabaseTransactionOutOfOrderException $e) {
$this->pass(t('Rolling back the outer transaction while the inner transaction is active resulted in an exception.'));
}
$this->assertFalse($database->inTransaction(), t('No more in a transaction after rolling back the outer transaction'));
- // Try to commit the inner transaction.
+ // Try to commit one inner transaction.
+ unset($transaction3);
+ $this->pass(t('Trying to commit an inner transaction resulted in an exception.'));
+ // Try to rollback one inner transaction.
try {
+ $transaction->rollback();
unset($transaction2);
- $this->fail(t('Trying to commit the inner transaction resulted in an exception.'));
+ $this->fail(t('Trying to commit an inner transaction resulted in an exception.'));
}
- catch (Exception $e) {
- $this->pass(t('Trying to commit the inner transaction resulted in an exception.'));
+ catch (DatabaseTransactionNoActiveException $e) {
+ $this->pass(t('Trying to commit an inner transaction resulted in an exception.'));
}
$this->assertRowAbsent('outer');
$this->assertRowAbsent('inner');
+ $this->assertRowAbsent('inner2');
}
}