summaryrefslogtreecommitdiffstatshomepage
path: root/modules/simpletest/tests/database_test.test
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2011-08-01 20:04:11 -0400
committerDries Buytaert <dries@buytaert.net>2011-08-01 20:04:11 -0400
commitd902c2f214e88ad53cdc2985f533c85aa98db39b (patch)
treec2c952277194fa74120edc67fd1aa948ff5b8ba6 /modules/simpletest/tests/database_test.test
parentac7020aed30540f8522a1edacc3402886a517254 (diff)
downloaddrupal-d902c2f214e88ad53cdc2985f533c85aa98db39b.tar.gz
drupal-d902c2f214e88ad53cdc2985f533c85aa98db39b.zip
- Patch #1185780 by Damien Tournoud: make transactions more flexible and useful.
Diffstat (limited to 'modules/simpletest/tests/database_test.test')
-rw-r--r--modules/simpletest/tests/database_test.test159
1 files changed, 158 insertions, 1 deletions
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index 143640d60b3..e27693c9753 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -3433,7 +3433,7 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
$this->assertIdentical($count, '0', t('Table was successfully created inside a transaction.'));
}
catch (Exception $e) {
- $this->fail($e->getMessage());
+ $this->fail((string) $e);
}
// If we rollback the transaction, an exception might be thrown.
@@ -3451,6 +3451,163 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
$this->assertTrue(true, t('Exception thrown on rollback after a DDL statement was executed.'));
}
}
+
+ /**
+ * Insert a single row into the testing table.
+ */
+ protected function insertRow($name) {
+ db_insert('test')
+ ->fields(array(
+ 'name' => $name,
+ ))
+ ->execute();
+ }
+
+ /**
+ * Start over for a new test.
+ */
+ protected function cleanUp() {
+ db_truncate('test')
+ ->execute();
+ }
+
+ /**
+ * Assert that a given row is present in the test table.
+ *
+ * @param $name
+ * The name of the row.
+ * @param $message
+ * The message to log for the assertion.
+ */
+ function assertRowPresent($name, $message = NULL) {
+ if (!isset($message)) {
+ $message = t('Row %name is present.', array('%name' => $name));
+ }
+ $present = (boolean) db_query('SELECT 1 FROM {test} WHERE name = :name', array(':name' => $name))->fetchField();
+ return $this->assertTrue($present, $message);
+ }
+
+ /**
+ * Assert that a given row is absent from the test table.
+ *
+ * @param $name
+ * The name of the row.
+ * @param $message
+ * The message to log for the assertion.
+ */
+ function assertRowAbsent($name, $message = NULL) {
+ if (!isset($message)) {
+ $message = t('Row %name is absent.', array('%name' => $name));
+ }
+ $present = (boolean) db_query('SELECT 1 FROM {test} WHERE name = :name', array(':name' => $name))->fetchField();
+ return $this->assertFalse($present, $message);
+ }
+
+ /**
+ * Test transaction stacking and commit / rollback.
+ */
+ function testTransactionStacking() {
+ // This test won't work right if transactions are supported.
+ if (Database::getConnection()->supportsTransactions()) {
+ return;
+ }
+
+ $database = Database::getConnection();
+
+ // Standard case: pop the inner transaction before the outer transaction.
+ $transaction = db_transaction();
+ $this->insertRow('outer');
+ $transaction2 = db_transaction();
+ $this->insertRow('inner');
+ // Pop the inner transaction.
+ unset($transaction2);
+ $this->assertTrue($database->inTransaction(), t('Still in a transaction after popping the inner transaction'));
+ // Pop the outer transaction.
+ unset($transaction);
+ $this->assertFalse($database->inTransaction(), t('Transaction closed after popping the outer transaction'));
+ $this->assertRowPresent('outer');
+ $this->assertRowPresent('inner');
+
+ // Pop the transaction in a different order they have been pushed.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $this->insertRow('outer');
+ $transaction2 = db_transaction();
+ $this->insertRow('inner');
+ // Pop the outer transaction, nothing should happen.
+ unset($transaction);
+ $this->insertRow('inner-after-outer-commit');
+ $this->assertTrue($database->inTransaction(), t('Still in a transaction after popping the outer transaction'));
+ // Pop the inner transaction, the whole transaction should commit.
+ unset($transaction2);
+ $this->assertFalse($database->inTransaction(), t('Transaction closed after popping the inner transaction'));
+ $this->assertRowPresent('outer');
+ $this->assertRowPresent('inner');
+ $this->assertRowPresent('inner-after-outer-commit');
+
+ // Rollback the inner transaction.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $this->insertRow('outer');
+ $transaction2 = db_transaction();
+ $this->insertRow('inner');
+ // Now rollback the inner transaction.
+ $transaction2->rollback();
+ unset($transaction2);
+ $this->assertTrue($database->inTransaction(), t('Still in a transaction after popping the outer transaction'));
+ // Pop the outer transaction, it should commit.
+ $this->insertRow('outer-after-inner-rollback');
+ unset($transaction);
+ $this->assertFalse($database->inTransaction(), t('Transaction closed after popping the inner transaction'));
+ $this->assertRowPresent('outer');
+ $this->assertRowAbsent('inner');
+ $this->assertRowPresent('outer-after-inner-rollback');
+
+ // Rollback the inner transaction after committing the outer one.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $this->insertRow('outer');
+ $transaction2 = db_transaction();
+ $this->insertRow('inner');
+ // Pop the outer transaction, nothing should happen.
+ unset($transaction);
+ $this->assertTrue($database->inTransaction(), t('Still in a transaction after popping the outer transaction'));
+ // Now rollback the inner transaction, it should rollback.
+ $transaction2->rollback();
+ unset($transaction2);
+ $this->assertFalse($database->inTransaction(), t('Transaction closed after popping the inner transaction'));
+ $this->assertRowPresent('outer');
+ $this->assertRowAbsent('inner');
+
+ // Rollback the outer transaction while the inner transaction is active.
+ // In that case, an exception will be triggered because we cannot
+ // ensure that the final result will have any meaning.
+ $this->cleanUp();
+ $transaction = db_transaction();
+ $this->insertRow('outer');
+ $transaction2 = db_transaction();
+ $this->insertRow('inner');
+ // 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) {
+ $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 {
+ unset($transaction2);
+ $this->fail(t('Trying to commit the inner transaction resulted in an exception.'));
+ }
+ catch (Exception $e) {
+ $this->pass(t('Trying to commit the inner transaction resulted in an exception.'));
+ }
+ $this->assertRowAbsent('outer');
+ $this->assertRowAbsent('inner');
+ }
}