2010-05-28 Eric Uhrhane <ericu@chromium.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 29 May 2010 03:45:50 +0000 (03:45 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 29 May 2010 03:45:50 +0000 (03:45 +0000)
        Reviewed by Dmitry Titov.

        Refactor DB layout tests so that they work in Web Workers as well as Pages.
        This is a big set of ports, but there are still more to come.
        In general, this is all just trivial changes.  For each test file, I pull out the meat into a .js file [with no functional changes].  Then I include that from both the DOM test and a new worker test; in both cases, the .html files are trivial wrappers.  All boilerplate code is pulled out into the resource files.

        In a couple of these tests, there were try/catch wrappers that suppressed errors.  I don't see why you'd want to do that in a test; let's let those errors cause test failures, then fix them.  I took out the wrappers and saw no difference in behavior.

        https://bugs.webkit.org/show_bug.cgi?id=34995

        * fast/workers/storage/multiple-databases-garbage-collection-expected.txt: Added.
        * fast/workers/storage/multiple-databases-garbage-collection.html: Added.
        * fast/workers/storage/multiple-transactions-expected.txt: Added.
        * fast/workers/storage/multiple-transactions.html: Added.
        * fast/workers/storage/multiple-transactions-on-different-handles-expected.txt: Added.
        * fast/workers/storage/multiple-transactions-on-different-handles.html: Added.
        * fast/workers/storage/change-version-handle-reuse-worker.html: Pulled out even more boilerplate.
        * fast/workers/storage/execute-sql-args-worker.html: Pulled out even more boilerplate.
        * fast/workers/storage/resources/database-worker-controller: Here's where the boilerplate went.
        * fast/workers/storage/resources/database-worker.js:
        * storage/multiple-databases-garbage-collection.html:
        * storage/multiple-databases-garbage-collection.js: Added.
        * storage/multiple-transactions-on-different-handles.html:
        * storage/multiple-transactions-on-different-handles.js: Added.
        * storage/multiple-transactions.html:
        * storage/multiple-transactions.js: Added.
        * storage/hash-change-with-xhr-expected.txt: Trivial whitespace change.
        * storage/hash-change-with-xhr.html:
        * storage/hash-change-with-xhr.js: Added.
        * storage/open-database-while-transaction-in-progress.html:
        * storage/open-database-while-transaction-in-progress.js: Added.
        * storage/read-and-write-transactions-dont-run-together.html:
        * storage/read-and-write-transactions-dont-run-together.js: Added.
        * storage/test-authorizer.html:
        * storage/test-authorizer.js: Added.
        I made a small common include for all the non-worker tests to remove a little boilerplate.
        * storage/resources/database-common.js: Added.
        These two tests had already been ported to workers; I updated them to use the common include file.
        * storage/change-version-handle-reuse.html:
        * storage/execute-sql-args.html:
        * fast/workers/storage/open-database-while-transaction-in-progress-expected.txt: Added.
        * fast/workers/storage/open-database-while-transaction-in-progress.html: Added.
        * fast/workers/storage/read-and-write-transactions-dont-run-together-expected.txt: Added.
        * fast/workers/storage/read-and-write-transactions-dont-run-together.html: Added.
        * fast/workers/storage/test-authorizer-expected.txt: Added.
        * fast/workers/storage/test-authorizer.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@60387 268f45cc-cd09-0410-ab3c-d52691b4dbfc

37 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/workers/storage/change-version-handle-reuse-worker.html
LayoutTests/fast/workers/storage/execute-sql-args-worker.html
LayoutTests/fast/workers/storage/multiple-databases-garbage-collection-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/multiple-databases-garbage-collection.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/multiple-transactions-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/multiple-transactions.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/read-and-write-transactions-dont-run-together-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/read-and-write-transactions-dont-run-together.html [new file with mode: 0644]
LayoutTests/fast/workers/storage/resources/database-worker-controller.js
LayoutTests/fast/workers/storage/resources/database-worker.js
LayoutTests/fast/workers/storage/test-authorizer-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/storage/test-authorizer.html [new file with mode: 0644]
LayoutTests/storage/change-version-handle-reuse.html
LayoutTests/storage/change-version-handle-reuse.js
LayoutTests/storage/execute-sql-args.html
LayoutTests/storage/execute-sql-args.js
LayoutTests/storage/hash-change-with-xhr-expected.txt
LayoutTests/storage/hash-change-with-xhr.html
LayoutTests/storage/hash-change-with-xhr.js [new file with mode: 0644]
LayoutTests/storage/multiple-databases-garbage-collection.html
LayoutTests/storage/multiple-databases-garbage-collection.js [new file with mode: 0644]
LayoutTests/storage/multiple-transactions-on-different-handles.html
LayoutTests/storage/multiple-transactions-on-different-handles.js [new file with mode: 0644]
LayoutTests/storage/multiple-transactions.html
LayoutTests/storage/multiple-transactions.js [new file with mode: 0644]
LayoutTests/storage/open-database-while-transaction-in-progress.html
LayoutTests/storage/open-database-while-transaction-in-progress.js [new file with mode: 0644]
LayoutTests/storage/read-and-write-transactions-dont-run-together.html
LayoutTests/storage/read-and-write-transactions-dont-run-together.js [new file with mode: 0644]
LayoutTests/storage/resources/database-common.js [new file with mode: 0644]
LayoutTests/storage/test-authorizer.html
LayoutTests/storage/test-authorizer.js [new file with mode: 0644]

index 39be8c9..229698c 100644 (file)
@@ -2,6 +2,55 @@
 
         Reviewed by Dmitry Titov.
 
+        Refactor DB layout tests so that they work in Web Workers as well as Pages.
+        This is a big set of ports, but there are still more to come.
+        In general, this is all just trivial changes.  For each test file, I pull out the meat into a .js file [with no functional changes].  Then I include that from both the DOM test and a new worker test; in both cases, the .html files are trivial wrappers.  All boilerplate code is pulled out into the resource files.
+
+        In a couple of these tests, there were try/catch wrappers that suppressed errors.  I don't see why you'd want to do that in a test; let's let those errors cause test failures, then fix them.  I took out the wrappers and saw no difference in behavior.
+
+        https://bugs.webkit.org/show_bug.cgi?id=34995
+
+        * fast/workers/storage/multiple-databases-garbage-collection-expected.txt: Added.
+        * fast/workers/storage/multiple-databases-garbage-collection.html: Added.
+        * fast/workers/storage/multiple-transactions-expected.txt: Added.
+        * fast/workers/storage/multiple-transactions.html: Added.
+        * fast/workers/storage/multiple-transactions-on-different-handles-expected.txt: Added.
+        * fast/workers/storage/multiple-transactions-on-different-handles.html: Added.
+        * fast/workers/storage/change-version-handle-reuse-worker.html: Pulled out even more boilerplate.
+        * fast/workers/storage/execute-sql-args-worker.html: Pulled out even more boilerplate.
+        * fast/workers/storage/resources/database-worker-controller: Here's where the boilerplate went.
+        * fast/workers/storage/resources/database-worker.js:
+        * storage/multiple-databases-garbage-collection.html:
+        * storage/multiple-databases-garbage-collection.js: Added.
+        * storage/multiple-transactions-on-different-handles.html:
+        * storage/multiple-transactions-on-different-handles.js: Added.
+        * storage/multiple-transactions.html:
+        * storage/multiple-transactions.js: Added.
+        * storage/hash-change-with-xhr-expected.txt: Trivial whitespace change.
+        * storage/hash-change-with-xhr.html:
+        * storage/hash-change-with-xhr.js: Added.
+        * storage/open-database-while-transaction-in-progress.html:
+        * storage/open-database-while-transaction-in-progress.js: Added.
+        * storage/read-and-write-transactions-dont-run-together.html:
+        * storage/read-and-write-transactions-dont-run-together.js: Added.
+        * storage/test-authorizer.html:
+        * storage/test-authorizer.js: Added.
+        I made a small common include for all the non-worker tests to remove a little boilerplate.
+        * storage/resources/database-common.js: Added.
+        These two tests had already been ported to workers; I updated them to use the common include file.
+        * storage/change-version-handle-reuse.html:
+        * storage/execute-sql-args.html:
+        * fast/workers/storage/open-database-while-transaction-in-progress-expected.txt: Added.
+        * fast/workers/storage/open-database-while-transaction-in-progress.html: Added.
+        * fast/workers/storage/read-and-write-transactions-dont-run-together-expected.txt: Added.
+        * fast/workers/storage/read-and-write-transactions-dont-run-together.html: Added.
+        * fast/workers/storage/test-authorizer-expected.txt: Added.
+        * fast/workers/storage/test-authorizer.html: Added.
+
+2010-05-28  Eric Uhrhane  <ericu@chromium.org>
+
+        Reviewed by Dmitry Titov.
+
         We don't test the async DB success callback in an isolated world.
         https://bugs.webkit.org/show_bug.cgi?id=39849
 
index f0c255a..44ad0de 100644 (file)
@@ -1,22 +1,8 @@
 <html> 
 <head>
 <script src="resources/database-worker-controller.js"></script> 
-<script> 
-
-function setupAndRunTest()
-{
-    if (window.layoutTestController) {
-        layoutTestController.waitUntilDone();
-        layoutTestController.dumpAsText();
-    }
-    document.getElementById("console").innerText = "";
-    databaseWorker.postMessage("importScripts:../../../storage/change-version-handle-reuse.js");
-    databaseWorker.postMessage("runTest");
-}
-</script> 
 </head> 
-<body onload="setupAndRunTest()"> 
+<body onload="runTest('change-version-handle-reuse.js')"> 
 <div>This tests that a database can be accessed after changing its version. You should see an error about FooBar table below, not about mismatching versions.
 <pre id="console"> 
 FAILURE: test didn't run.
index 3d0f6cd..3c5adbe 100644 (file)
@@ -1,23 +1,12 @@
 <html>
 <head>
 <script src="resources/database-worker-controller.js"></script>
-<script>
-
-function setupAndRunTest()
-{
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
-        layoutTestController.waitUntilDone();
-    }
-    databaseWorker.postMessage("importScripts:../../../storage/execute-sql-args.js");
-    databaseWorker.postMessage("runTest");
-}
-
-</script>
 </head>
 
-<body onload="setupAndRunTest()">
-<pre id="console"></pre>
+<body onload="runTest('execute-sql-args.js')">
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
 </body>
 
 </html>
diff --git a/LayoutTests/fast/workers/storage/multiple-databases-garbage-collection-expected.txt b/LayoutTests/fast/workers/storage/multiple-databases-garbage-collection-expected.txt
new file mode 100644 (file)
index 0000000..d01514a
--- /dev/null
@@ -0,0 +1,4 @@
+This test opens two databases, queues up a series of operations on both, then "forgets" about one of them. After forcing GC, resources associated with that database should be freed gracefully.
+Forgotten Database Transaction Complete
+Persistent Database Transaction Complete
+
diff --git a/LayoutTests/fast/workers/storage/multiple-databases-garbage-collection.html b/LayoutTests/fast/workers/storage/multiple-databases-garbage-collection.html
new file mode 100644 (file)
index 0000000..0ec34f4
--- /dev/null
@@ -0,0 +1,12 @@
+<html>
+<head>
+<script src="resources/database-worker-controller.js"></script>
+</head>
+<body onload="runTest('multiple-databases-garbage-collection.js');">
+This test opens two databases, queues up a series of operations on both, then "forgets" about one of them.
+After forcing GC, resources associated with that database should be freed gracefully.<br>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/storage/multiple-transactions-expected.txt b/LayoutTests/fast/workers/storage/multiple-transactions-expected.txt
new file mode 100644 (file)
index 0000000..3e9c0f6
--- /dev/null
@@ -0,0 +1,6 @@
+This is a test to see if the database API allows multiple transactions to be queued on the same database at once:
+Transaction 1 Started
+Transaction 1 Succeeded
+Transaction 2 Started
+Transaction 2 Succeeded
+
diff --git a/LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles-expected.txt b/LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles-expected.txt
new file mode 100644 (file)
index 0000000..ba6a2d1
--- /dev/null
@@ -0,0 +1,8 @@
+This is a test to see if queueing up multiple transactions on different handles to the same database results in a deadlock.
+db1 read statement succeeded
+db1 write statement succeeded
+db1 transaction succeeded
+db2 read statement succeeded
+db2 write statement succeeded
+db2 transaction succeeded
+
diff --git a/LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles.html b/LayoutTests/fast/workers/storage/multiple-transactions-on-different-handles.html
new file mode 100644 (file)
index 0000000..d0620f2
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<script src="resources/database-worker-controller.js"></script>
+</head>
+
+<body onload="runTest('multiple-transactions-on-different-handles.js')">
+This is a test to see if queueing up multiple transactions on different handles to the same database results in a deadlock.<br>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
+</body>
+
+</html>
diff --git a/LayoutTests/fast/workers/storage/multiple-transactions.html b/LayoutTests/fast/workers/storage/multiple-transactions.html
new file mode 100644 (file)
index 0000000..60e13e6
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<script src="resources/database-worker-controller.js"></script>
+</head>
+
+<body onload="runTest('multiple-transactions.js')">
+This is a test to see if the database API allows multiple transactions to be queued on the same database at once:<br>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
+</body>
+
+</html>
diff --git a/LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress-expected.txt b/LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress-expected.txt
new file mode 100644 (file)
index 0000000..acac8af
--- /dev/null
@@ -0,0 +1,3 @@
+This is a test to see if opening a database while a transaction is running on a different handle to the same database results in a deadlock.
+openDatabase() succeeded.
+
diff --git a/LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress.html b/LayoutTests/fast/workers/storage/open-database-while-transaction-in-progress.html
new file mode 100644 (file)
index 0000000..3012cde
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<script src="resources/database-worker-controller.js"></script>
+</head>
+
+<body onload="runTest('open-database-while-transaction-in-progress.js')">
+This is a test to see if opening a database while a transaction is running on a different handle to the same database results in a deadlock.<br>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
+</body>
+
+</html>
diff --git a/LayoutTests/fast/workers/storage/read-and-write-transactions-dont-run-together-expected.txt b/LayoutTests/fast/workers/storage/read-and-write-transactions-dont-run-together-expected.txt
new file mode 100644 (file)
index 0000000..cc8979c
--- /dev/null
@@ -0,0 +1,12 @@
+This test tests that read and write transactions on different handles to the same database don't run together.
+Transaction successful.
+Transaction successful.
+Transaction successful.
+Transaction successful.
+Transaction successful.
+Transaction successful.
+Transaction successful.
+Transaction successful.
+Transaction successful.
+Transaction successful.
+
diff --git a/LayoutTests/fast/workers/storage/read-and-write-transactions-dont-run-together.html b/LayoutTests/fast/workers/storage/read-and-write-transactions-dont-run-together.html
new file mode 100644 (file)
index 0000000..8aeffc8
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<script src="resources/database-worker-controller.js"></script>
+</head>
+
+<body onload="runTest('read-and-write-transactions-dont-run-together.js')">
+This test tests that read and write transactions on different handles to the same database don't run together.<br>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
+</body>
+
+</html>
index 10ae415..a8a9753 100644 (file)
@@ -8,11 +8,15 @@ databaseWorker.onerror = function(event) {
 };
 
 databaseWorker.onmessage = function(event) {
-    if (event.data.indexOf('log:') == 0)
+    if (event.data.indexOf('log:') == 0) {
         log(event.data.substring(4));
-    else if (event.data == 'notifyDone') {
+    else if (event.data == 'notifyDone') {
         if (window.layoutTestController)
             layoutTestController.notifyDone();
+    } else if (event.data.indexOf('setLocationHash:') == '0') {
+        location.hash = event.data.substring('setLocationHash:'.length);
+    } else if (event.data == 'back') {
+        history.back();
     } else
         throw new Error("Unrecognized message: " + event);
 };
@@ -21,3 +25,15 @@ function log(message)
 {
     document.getElementById("console").innerText += message + "\n";
 }
+
+function runTest(testFile)
+{
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+    document.getElementById("console").innerText = "";
+    databaseWorker.postMessage("importScripts:../../../storage/" + testFile);
+    databaseWorker.postMessage("runTest");
+}
+
index 32d6c13..7014d30 100644 (file)
@@ -27,3 +27,13 @@ onmessage = function(event) {
 };
 
 var DB_TEST_SUFFIX = "_worker";
+
+function openDatabaseWithSuffix(name, version, description, size, callback)
+{
+    if (arguments.length > 4) {
+        return openDatabase(name + DB_TEST_SUFFIX, version, description, size, callback);
+    } else {
+        return openDatabase(name + DB_TEST_SUFFIX, version, description, size);
+    }
+}
+
diff --git a/LayoutTests/fast/workers/storage/test-authorizer-expected.txt b/LayoutTests/fast/workers/storage/test-authorizer-expected.txt
new file mode 100644 (file)
index 0000000..9ee0603
--- /dev/null
@@ -0,0 +1,68 @@
+This test tests the database authorizer.
+SQLITE_CREATE_TABLE statement succeeded.
+SQLITE_CREATE_INDEX statement succeeded.
+SQLITE_CREATE_TEMP_TABLE statement succeeded.
+SQLITE_CREATE_TEMP_TRIGGER statement succeeded.
+SQLITE_CREATE_TEMP_VIEW statement succeeded.
+SQLITE_CREATE_TRIGGER statement succeeded.
+SQLITE_CREATE_VIEW statement succeeded.
+SQLITE_CREATE_VTABLE statement failed: not authorized
+SQLITE_READ statement succeeded.
+SQLITE_SELECT statement succeeded.
+SQLITE_DELETE statement succeeded.
+SQLITE_INSERT statement succeeded.
+SQLITE_UPDATE statement succeeded.
+SQLITE_PRAGMA statement failed: not authorized
+SQLITE_ALTER_TABLE statement succeeded.
+SQLITE_ALTER_TABLE statement succeeded.
+SQLITE_TRANSACTION statement failed: not authorized
+SQLITE_ATTACH statement failed: not authorized
+SQLITE_DETACH statement failed: not authorized
+SQLITE_REINDEX statement succeeded.
+SQLITE_ANALYZE statement failed: not authorized
+SQLITE_DROP_INDEX statement succeeded.
+SQLITE_DROP_TEMP_TABLE statement succeeded.
+SQLITE_DROP_TEMP_TRIGGER statement succeeded.
+SQLITE_DROP_TEMP_VIEW statement succeeded.
+SQLITE_DROP_TRIGGER statement succeeded.
+SQLITE_DROP_VIEW statement succeeded.
+SQLITE_DROP_TABLE statement succeeded.
+Write transaction succeeded.
+SQLITE_CREATE_TABLE statement failed: not authorized
+SQLITE_CREATE_TABLE statement succeeded.
+SQLITE_CREATE_INDEX statement failed: not authorized
+SQLITE_CREATE_TEMP_TABLE statement failed: not authorized
+SQLITE_CREATE_TEMP_TRIGGER statement failed: not authorized
+SQLITE_CREATE_TEMP_VIEW statement failed: not authorized
+SQLITE_CREATE_TRIGGER statement failed: not authorized
+SQLITE_CREATE_VIEW statement failed: not authorized
+SQLITE_CREATE_VTABLE statement failed: not authorized
+SQLITE_CREATE_INDEX statement succeeded.
+SQLITE_CREATE_TEMP_TABLE statement succeeded.
+SQLITE_CREATE_TEMP_TRIGGER statement succeeded.
+SQLITE_CREATE_TEMP_VIEW statement succeeded.
+SQLITE_CREATE_TRIGGER statement succeeded.
+SQLITE_CREATE_VIEW statement succeeded.
+SQLITE_CREATE_VTABLE statement failed: not authorized
+SQLITE_READ statement succeeded.
+SQLITE_SELECT statement succeeded.
+SQLITE_DELETE statement failed: not authorized
+SQLITE_INSERT statement failed: not authorized
+SQLITE_UPDATE statement failed: not authorized
+SQLITE_PRAGMA statement failed: not authorized
+SQLITE_ALTER_TABLE statement failed: not authorized
+SQLITE_ALTER_TABLE statement failed: no such table: TestTable
+SQLITE_TRANSACTION statement failed: not authorized
+SQLITE_ATTACH statement failed: not authorized
+SQLITE_DETACH statement failed: not authorized
+SQLITE_REINDEX statement failed: not authorized
+SQLITE_ANALYZE statement failed: not authorized
+SQLITE_DROP_INDEX statement failed: not authorized
+SQLITE_DROP_TEMP_TABLE statement failed: not authorized
+SQLITE_DROP_TEMP_TRIGGER statement failed: not authorized
+SQLITE_DROP_TEMP_VIEW statement failed: not authorized
+SQLITE_DROP_TRIGGER statement failed: not authorized
+SQLITE_DROP_VIEW statement failed: not authorized
+SQLITE_DROP_TABLE statement failed: not authorized
+Read transactions succeeded.
+
diff --git a/LayoutTests/fast/workers/storage/test-authorizer.html b/LayoutTests/fast/workers/storage/test-authorizer.html
new file mode 100644 (file)
index 0000000..946b1c0
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+<script src="resources/database-worker-controller.js"></script>
+</head>
+
+<body onload="runTest('test-authorizer.js')">
+This test tests the database authorizer.<br>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
+</body>
+
+</html>
index dd32198..af3fbf4 100644 (file)
@@ -1,27 +1,7 @@
 <html> 
 <head>
+<script src="resources/database-common.js"></script>
 <script src="change-version-handle-reuse.js"></script>
-<script> 
-
-var DB_TEST_SUFFIX = "_dom";
-
-function log(message)
-{
-    document.getElementById("console").innerText += message + "\n";
-}
-
-function setupAndRunTest()
-{
-    if (window.layoutTestController) {
-        layoutTestController.waitUntilDone();
-        layoutTestController.dumpAsText();
-    }
-    document.getElementById("console").innerText = "";
-    runTest();
-}
-</script> 
 </head> 
 <body onload="setupAndRunTest()"> 
 <div>This tests that a database can be accessed after changing its version. You should see an error about FooBar table below, not about mismatching versions.
index e948614..847a58c 100644 (file)
@@ -9,7 +9,7 @@ function finishTest()
 function runTest()
 {
     try {
-        db = openDatabase("ChangeVersion" + DB_TEST_SUFFIX, "", "Test that changing a database version doesn't kill our handle to it", 1);
+        db = openDatabaseWithSuffix("ChangeVersion", "", "Test that changing a database version doesn't kill our handle to it", 1);
         var version = db.version;
         var newVersion = version ? (parseInt(version) + 1).toString() : "1"; 
         db.changeVersion(version, newVersion, function(tx) {
index 8a36a7a..b9f2a43 100644 (file)
@@ -1,30 +1,13 @@
 <html>
-
 <head>
+<script src="resources/database-common.js"></script>
 <script src="execute-sql-args.js"></script>
-<script>
-
-var DB_TEST_SUFFIX = "_dom";
-
-function log(message)
-{
-    document.getElementById("console").innerText += message + "\n";
-}
-
-function setupAndRunTest()
-{
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
-        layoutTestController.waitUntilDone();
-    }
-    runTest();
-}
-
-</script>
 </head>
 
 <body onload="setupAndRunTest()">
-<pre id="console"></pre>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
 </body>
 
 </html>
index babeb5d..3b9414d 100644 (file)
@@ -81,6 +81,6 @@ function runTransactionTests(transaction)
 function runTest()
 {
 
-    var db = openDatabase("ExecuteSQLArgsTest" + DB_TEST_SUFFIX, "1.0", "Test of handling of the arguments to SQLTransaction.executeSql", 1);
+    var db = openDatabaseWithSuffix("ExecuteSQLArgsTest", "1.0", "Test of handling of the arguments to SQLTransaction.executeSql", 1);
     db.transaction(runTransactionTests);
 }
index a481746..8e964e6 100644 (file)
@@ -1,3 +1,4 @@
 Changing the hash to create history entries.
 Db is warmed up
 Test Complete, SUCCESS
+
index 9cbf276..584320f 100644 (file)
 <html> 
 <head> 
 <title>Hash Change with an Open XHR should not stop database transactions</title>
-
-<script type="text/javascript"> 
-var DB_UPDATE_INTERVAL = 100;
-var SEND_XHR_INTERVAL = 100;
-var BACK_INTERVAL = 100;
-var CREATE_HEALTH_TABLE = 'CREATE TABLE IF NOT EXISTS health (key VARCHAR(16) PRIMARY KEY);';
-var UPDATE_DATA = 'REPLACE INTO health VALUES("health-check-key");';
-var db = window.openDatabase('bug25710', '1.0', 'LayoutTest for bug 25710', 102400);
-var backIterations;
-var msgDiv;
-var xhrFctIntervalId;
-var backFctIntervalId;
-var successCheckIntervalId;
-var dbFctIntervalId;
-var successes;
-var databaseUpdates;
-var stoppedIntervals;
-function log(msg)
-{
-    var newMsg = document.createElement('div');
-    newMsg.innerText = msg;
-    msgDiv.appendChild(newMsg);
-}
-
-function stopIntervals()
-{
-    stoppedIntervals = true;
-    window.clearInterval(dbFctIntervalId);
-    window.clearInterval(xhrFctIntervalId);
-    window.clearInterval(backFctIntervalId);
-}
-
-function stopTest(message)
-{
-    if (!stoppedIntervals)
-        stopIntervals();
-
-    log(message);
-
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-    
-function updateDatabase()
-{
-    databaseUpdates++;  
-    db.transaction(function(transaction) {
-        transaction.executeSql(UPDATE_DATA, [], function() {}, errorHandler);
-    }, errorHandler, function() {
-        successes++;
-    });
-}
-
-function checkForSuccess()
-{
-    if (successes == databaseUpdates) {
-        stopTest('Test Complete, SUCCESS');
-        window.clearInterval(successCheckIntervalId);
-    }
-}
-function errorHandler(tx, error)
-{
-    log('DB error, code: ' + error.code + ', msg: ' + error.message);
-    stopTest('Test Complete, FAILED');
-}
-function sendXhr()
-{
-    xhr = new XMLHttpRequest();
-    xhr.open('GET', location.href, true);
-    xhr.send('');
-}
-function invokeBack()
-{
-    backIterations--;
-    if (backIterations) {
-        history.back();
-    } else {
-        stopIntervals();
-        // Allow a little time for all the database transactions to complete now we've stopped making them.
-        successCheckIntervalId = window.setInterval(checkForSuccess, 250);
-        // If we don't finish before this time, then we consider the test failed.
-        window.setTimeout(function() { stopTest('Timed out waiting for transactions to complete. FAILED'); }, 20000);
-        
-    }
-}
-
-function runTest()
-{
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
-        layoutTestController.waitUntilDone();
-    }
-  
-    msgDiv = document.getElementById('msgs');
-
-    msgDiv.innerHTML = '';
-    backIterations = 10;
-    consecutiveFailures = 0;
-    successes = 0;
-    databaseUpdates = 0;
-    stoppedIntervals = false;
-
-    // Create some hashes so we can call history.back().
-    log('Changing the hash to create history entries.');
-    for (var i = 0; i < backIterations; i++) {
-        location.hash = i;
-    }
-
-    // Init the database.
-    db.transaction(function(transaction) {
-        transaction.executeSql(CREATE_HEALTH_TABLE, [], function() {}, errorHandler);
-    }, errorHandler, function() {
-        // Give a little for the database to 'warm up' before making xhr requests
-        // and calling history.back().
-        window.setTimeout(function() {
-            log('Db is warmed up');
-
-            // NOTE: If we don't make any xhr requests, then the test
-            // successfully passes (comment this line out).
-            xhrFctIntervalId = window.setInterval(sendXhr, SEND_XHR_INTERVAL);
-            backFctIntervalId = window.setInterval(invokeBack, BACK_INTERVAL);
-            dbFctIntervalId = window.setInterval(updateDatabase, DB_UPDATE_INTERVAL);
-        }, 500);
-    });
-}
-</script> 
+<script src="resources/database-common.js"></script>
+<script src="hash-change-with-xhr.js"></script>
 </head> 
-<body onload="runTest()"> 
-<div id="msgs"></div> 
+<body onload="setupAndRunTest()"> 
+<pre id="console">
+FAILURE: test didn't run.
+</pre>
 </body> 
 </html>
diff --git a/LayoutTests/storage/hash-change-with-xhr.js b/LayoutTests/storage/hash-change-with-xhr.js
new file mode 100644 (file)
index 0000000..4290681
--- /dev/null
@@ -0,0 +1,112 @@
+var DB_UPDATE_INTERVAL = 100;
+var SEND_XHR_INTERVAL = 100;
+var BACK_INTERVAL = 100;
+var CREATE_HEALTH_TABLE = 'CREATE TABLE IF NOT EXISTS health (key VARCHAR(16) PRIMARY KEY);';
+var UPDATE_DATA = 'REPLACE INTO health VALUES("health-check-key");';
+var db = openDatabaseWithSuffix('bug25710', '1.0', 'LayoutTest for bug 25710', 102400);
+var backIterations;
+var xhrFctIntervalId;
+var backFctIntervalId;
+var successCheckIntervalId;
+var dbFctIntervalId;
+var successes;
+var databaseUpdates;
+var stoppedIntervals;
+function stopIntervals()
+{
+    stoppedIntervals = true;
+    clearInterval(dbFctIntervalId);
+    clearInterval(xhrFctIntervalId);
+    clearInterval(backFctIntervalId);
+}
+
+function stopTest(message)
+{
+    if (!stoppedIntervals)
+        stopIntervals();
+
+    log(message);
+
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+    
+function updateDatabase()
+{
+    databaseUpdates++;  
+    db.transaction(function(transaction) {
+        transaction.executeSql(UPDATE_DATA, [], function() {}, errorHandler);
+    }, errorHandler, function() {
+        successes++;
+    });
+}
+
+function checkForSuccess()
+{
+    if (successes == databaseUpdates) {
+        stopTest('Test Complete, SUCCESS');
+        clearInterval(successCheckIntervalId);
+    }
+}
+function errorHandler(tx, error)
+{
+    log('DB error, code: ' + error.code + ', msg: ' + error.message);
+    stopTest('Test Complete, FAILED');
+}
+function sendXhr()
+{
+    xhr = new XMLHttpRequest();
+    xhr.open('GET', location.href, true);
+    xhr.send('');
+}
+function invokeBack()
+{
+    backIterations--;
+    if (backIterations) {
+        history.back();
+    } else {
+        stopIntervals();
+        // Allow a little time for all the database transactions to complete now we've stopped making them.
+        successCheckIntervalId = setInterval(checkForSuccess, 250);
+        // If we don't finish before this time, then we consider the test failed.
+        setTimeout(function() { stopTest('Timed out waiting for transactions to complete. FAILED'); }, 20000);
+        
+    }
+}
+
+function runTest()
+{
+    backIterations = 10;
+    consecutiveFailures = 0;
+    successes = 0;
+    databaseUpdates = 0;
+    stoppedIntervals = false;
+
+    // Create some hashes so we can call history.back().
+    log('Changing the hash to create history entries.');
+    for (var i = 0; i < backIterations; i++) {
+        setLocationHash(i);
+    }
+
+    // Init the database.
+    db.transaction(function(transaction) {
+        transaction.executeSql(CREATE_HEALTH_TABLE, [], function() {}, errorHandler);
+    }, errorHandler, function() {
+        // Give a little for the database to 'warm up' before making xhr requests
+        // and calling history.back().
+        setTimeout(function() {
+            log('Db is warmed up');
+
+            // NOTE: If we don't make any xhr requests, then the test
+            // successfully passes (comment this line out).
+            xhrFctIntervalId = setInterval(sendXhr, SEND_XHR_INTERVAL);
+            backFctIntervalId = setInterval(invokeBack, BACK_INTERVAL);
+            dbFctIntervalId = setInterval(updateDatabase, DB_UPDATE_INTERVAL);
+        }, 500);
+    });
+}
index 45246a9..8451acf 100644 (file)
@@ -1,77 +1,12 @@
 <html>
 <head>
-<script>
-
-function log(message)
-{
-    document.body.innerHTML += message + "<br>";
-}
-
-function GC()
-{
-    // Force GC.
-    if (window.GCController)
-        GCController.collect();
-    else {
-        for (var i = 0; i < 10000; ++i) {
-            ({ });
-        }
-    }
-}
-
-// Variable for the database that will never be forgotten
-var persistentDB = 0;
-// Variable for the forgotten database
-var forgottenDB = 0;
-
-var completed = 0;
-function checkCompletion()
-{
-    if (++completed == 2 && window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
-function runTest()
-{
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
-        layoutTestController.waitUntilDone();
-    }
-    
-    persistentDB = openDatabase("MultipleDatabasesTest1", "1.0", "Test one out of a set of databases being destroyed (1)", 32768);
-    forgottenDB = openDatabase("MultipleDatabasesTest2", "1.0", "Test one out of a set of databases being destroyed (2)", 32768);
-
-    persistentDB.transaction(function(tx) {
-        tx.executeSql("CREATE TABLE IF NOT EXISTS DataTest (randomData)", [], function(tx, result) { 
-            for (var i = 0; i < 25; ++i)
-                tx.executeSql("INSERT INTO DataTest (randomData) VALUES (1)", []);
-        }); 
-    }, function(err) {
-        log("Persistent Database Transaction Errored - " + err);
-        checkCompletion();
-    }, function() {
-        log("Persistent Database Transaction Complete");
-        checkCompletion();
-    });
-
-    forgottenDB.transaction(function(tx) {
-        tx.executeSql("CREATE TABLE IF NOT EXISTS EmptyTable (unimportantData)", []);
-    }, function(err) {
-        log("Forgotten Database Transaction Errored - " + err);
-        forgottenDB = 0;
-        GC();
-        checkCompletion();
-    }, function() {
-        log("Forgotten Database Transaction Complete");
-        forgottenDB = 0;
-        GC();
-        checkCompletion();
-    });
-}
-
-</script>
-<body onload="runTest();">
+<script src="resources/database-common.js"></script>
+<script src="multiple-databases-garbage-collection.js"></script>
+<body onload="setupAndRunTest();">
 This test opens two databases, queues up a series of operations on both, then "forgets" about one of them.
 After forcing GC, resources associated with that database should be freed gracefully.<br>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
 </body>
 </html>
diff --git a/LayoutTests/storage/multiple-databases-garbage-collection.js b/LayoutTests/storage/multiple-databases-garbage-collection.js
new file mode 100644 (file)
index 0000000..9a2b27f
--- /dev/null
@@ -0,0 +1,56 @@
+function GC()
+{
+    // Force GC.
+    if (window.GCController)
+        GCController.collect();
+    else {
+        for (var i = 0; i < 10000; ++i) {
+            ({ });
+        }
+    }
+}
+
+// Variable for the database that will never be forgotten
+var persistentDB = 0;
+// Variable for the forgotten database
+var forgottenDB = 0;
+
+var completed = 0;
+function checkCompletion()
+{
+    if (++completed == 2 && window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function runTest()
+{
+    persistentDB = openDatabaseWithSuffix("MultipleDatabasesTest1", "1.0", "Test one out of a set of databases being destroyed (1)", 32768);
+    forgottenDB = openDatabaseWithSuffix("MultipleDatabasesTest2", "1.0", "Test one out of a set of databases being destroyed (2)", 32768);
+
+    persistentDB.transaction(function(tx) {
+        tx.executeSql("CREATE TABLE IF NOT EXISTS DataTest (randomData)", [], function(tx, result) { 
+            for (var i = 0; i < 25; ++i)
+                tx.executeSql("INSERT INTO DataTest (randomData) VALUES (1)", []);
+        }); 
+    }, function(err) {
+        log("Persistent Database Transaction Errored - " + err);
+        checkCompletion();
+    }, function() {
+        log("Persistent Database Transaction Complete");
+        checkCompletion();
+    });
+
+    forgottenDB.transaction(function(tx) {
+        tx.executeSql("CREATE TABLE IF NOT EXISTS EmptyTable (unimportantData)", []);
+    }, function(err) {
+        log("Forgotten Database Transaction Errored - " + err);
+        forgottenDB = 0;
+        GC();
+        checkCompletion();
+    }, function() {
+        log("Forgotten Database Transaction Complete");
+        forgottenDB = 0;
+        GC();
+        checkCompletion();
+    });
+}
index bcdab82..0a18c32 100644 (file)
@@ -1,96 +1,12 @@
 <html>
 <head>
-<script>
-
-function log(message)
-{
-    document.body.innerHTML += message + "<br>";
-}
-
-var complete = 0;
-
-function checkCompletion()
-{
-    // The test should end after two transactions
-    if (++complete == 2 && window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
-// Opens the database used in this test case
-function openTestDatabase()
-{
-    return openDatabase("MultipleTransactionsOnDifferentHandlesTest",
-                        "1.0",
-                        "Test to make sure that queueing multiple transactions on different DB handles does not result in a deadlock.",
-                        32768);
-}
-
-function statementSuccessCallback(dbName, statementType)
-{
-    log(dbName + " " + statementType + " statement succeeded");
-}
-
-function statementErrorCallback(dbName, statementType, error)
-{
-    log(dbName + " " + statementType + " statement failed: " + error.message);
-}
-
-// Runs a transaction on the given database
-function runTransaction(db, dbName, val)
-{
-    db.transaction(function(tx) {
-       // Execute a read-only statement
-       tx.executeSql("SELECT COUNT(*) FROM Test;", [],
-                     function(result) { statementSuccessCallback(dbName, "read"); },
-                     function(tx, error) { statementErrorCallback(dbName, "read", error); });
-
-       // Execute a write statement to make sure SQLite tries to acquire an exclusive lock on the DB file
-       tx.executeSql("INSERT INTO Test VALUES (?);", [val],
-                     function(result) { statementSuccessCallback(dbName, "write"); },
-                     function(tx, error) { statementErrorCallback(dbName, "write", error); });
-       }, function(error) {
-           // Transaction failure callback
-           log(dbName + " transaction failed: " + error.message);
-           checkCompletion();
-       }, function() {
-           // Transaction success callback
-           log(dbName + " transaction succeeded");
-           checkCompletion();
-       });
-}
-
-// We need to guarantee that the Test table exists before we run our test.
-// Therefore, the test code is in the successCallback of the transaction that creates the table.
-function runTest() {
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
-        layoutTestController.waitUntilDone();
-    }
-
-    try {
-        var db = openTestDatabase();
-        db.transaction(function(tx) {
-            // Create the Test table if it does not exist
-            tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo int);", [],
-                          function(result) {}, function(tx, error) {});
-            }, function(error) {
-                log("Creating the Test table failed: " + error.message);
-            }, function() {
-                // The Test table was created successfully
-                var db1 = openTestDatabase();
-                var db2 = openTestDatabase();
-                if (db1 == db2)
-                    log("failure: db1 == db2");
-                else {
-                    runTransaction(db1, "db1", 1);
-                    runTransaction(db2, "db2", 2);
-                }
-            });
-    } catch(err) {}
-}
-</script>
+<script src="resources/database-common.js"></script>
+<script src="multiple-transactions-on-different-handles.js"></script>
 </head>
-<body onload="runTest();">
+<body onload="setupAndRunTest();">
 This is a test to see if queueing up multiple transactions on different handles to the same database results in a deadlock.<br>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
 </body>
 </html>
diff --git a/LayoutTests/storage/multiple-transactions-on-different-handles.js b/LayoutTests/storage/multiple-transactions-on-different-handles.js
new file mode 100644 (file)
index 0000000..9ab4b93
--- /dev/null
@@ -0,0 +1,78 @@
+var complete = 0;
+
+function checkCompletion()
+{
+    // The test should end after two transactions
+    if (++complete == 2 && window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+// Opens the database used in this test case
+function openTestDatabase()
+{
+    return openDatabaseWithSuffix("MultipleTransactionsOnDifferentHandlesTest",
+                                  "1.0",
+                                  "Test to make sure that queueing multiple transactions on different DB handles does not result in a deadlock.",
+                                  32768);
+}
+
+function statementSuccessCallback(dbName, statementType)
+{
+    log(dbName + " " + statementType + " statement succeeded");
+}
+
+function statementErrorCallback(dbName, statementType, error)
+{
+    log(dbName + " " + statementType + " statement failed: " + error.message);
+}
+
+// Runs a transaction on the given database
+function runTransaction(db, dbName, val)
+{
+    db.transaction(function(tx) {
+       // Execute a read-only statement
+       tx.executeSql("SELECT COUNT(*) FROM Test;", [],
+                     function(result) { statementSuccessCallback(dbName, "read"); },
+                     function(tx, error) { statementErrorCallback(dbName, "read", error); });
+
+       // Execute a write statement to make sure SQLite tries to acquire an exclusive lock on the DB file
+       tx.executeSql("INSERT INTO Test VALUES (?);", [val],
+                     function(result) { statementSuccessCallback(dbName, "write"); },
+                     function(tx, error) { statementErrorCallback(dbName, "write", error); });
+       }, function(error) {
+           // Transaction failure callback
+           log(dbName + " transaction failed: " + error.message);
+           checkCompletion();
+       }, function() {
+           // Transaction success callback
+           log(dbName + " transaction succeeded");
+           checkCompletion();
+       });
+}
+
+// We need to guarantee that the Test table exists before we run our test.
+// Therefore, the test code is in the successCallback of the transaction that creates the table.
+function runTest() {
+    try {
+        var db = openTestDatabase();
+        db.transaction(function(tx) {
+            // Create the Test table if it does not exist
+            tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo int);", [],
+                          function(result) {}, function(tx, error) {});
+            }, function(error) {
+                log("Creating the Test table failed: " + error.message);
+            }, function() {
+                // The Test table was created successfully
+                var db1 = openTestDatabase();
+                var db2 = openTestDatabase();
+                if (db1 == db2)
+                    log("failure: db1 == db2");
+                else {
+                    runTransaction(db1, "db1", 1);
+                    runTransaction(db2, "db2", 2);
+                }
+            });
+    } catch(err) {}
+}
+
+
index 56656ca..3597440 100644 (file)
@@ -1,53 +1,12 @@
 <html>
 <head>
-<script>
-
-function log(message)
-{
-    document.body.innerHTML += message + "<br>";
-}
-
-var complete = 0;
-
-function checkCompletion()
-{
-    if (++complete == 2 && window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
-function runTest()
-{
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
-        layoutTestController.waitUntilDone();
-    }
-    
-    var db = openDatabase("MultipleTransactionsTest", "1.0", "Test to make sure multiple transactions can be queued at once for an HTML5 database", 32768);
-
-    db.transaction(function(tx) {
-        log("Transaction 1 Started");
-    }, function(err) {
-        log("Transaction 1 Errored - " + err);
-        checkCompletion();
-    }, function() {
-        log("Transaction 1 Succeeded");
-        checkCompletion();
-    });
-
-    db.transaction(function(tx) {
-        log("Transaction 2 Started");
-    }, function(err) {
-        log("Transaction 2 Errored - " + err);
-        checkCompletion();
-    }, function() {
-        log("Transaction 2 Succeeded");
-        checkCompletion();
-    });
-}
-
-</script>
+<script src="resources/database-common.js"></script>
+<script src="multiple-transactions.js"></script>
 <head>
-<body onload="runTest();">
+<body onload="setupAndRunTest();">
 This is a test to see if the database API allows multiple transactions to be queued on the same database at once:<br>
+<pre id="console"> 
+FAILURE: test didn't run.
+</pre> 
 </body>
 </html>
diff --git a/LayoutTests/storage/multiple-transactions.js b/LayoutTests/storage/multiple-transactions.js
new file mode 100644 (file)
index 0000000..85cdabc
--- /dev/null
@@ -0,0 +1,32 @@
+var complete = 0;
+
+function checkCompletion()
+{
+    if (++complete == 2 && window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function runTest()
+{
+    var db = openDatabaseWithSuffix("MultipleTransactionsTest", "1.0", "Test to make sure multiple transactions can be queued at once for an HTML5 database", 32768);
+
+    db.transaction(function(tx) {
+        log("Transaction 1 Started");
+    }, function(err) {
+        log("Transaction 1 Errored - " + err);
+        checkCompletion();
+    }, function() {
+        log("Transaction 1 Succeeded");
+        checkCompletion();
+    });
+
+    db.transaction(function(tx) {
+        log("Transaction 2 Started");
+    }, function(err) {
+        log("Transaction 2 Errored - " + err);
+        checkCompletion();
+    }, function() {
+        log("Transaction 2 Succeeded");
+        checkCompletion();
+    });
+}
index 691f6fe..707a1a4 100644 (file)
@@ -1,71 +1,12 @@
 <html>
 <head>
-<script>
-
-function log(message)
-{
-    document.body.innerHTML += message + "<br>";
-}
-
-var complete = 0;
-
-function checkCompletion()
-{
-    // The test should end after two transactions
-    if (++complete == 1 && window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
-// Opens the database used in this test case
-function openTestDatabase()
-{
-    return openDatabase("OpenDatabaseWhileTransactionInProgressTest",
-                        "1.0",
-                        "Test to make sure that calling openDatabase() while a transaction is in progress on a different handle to the same database does not result in a deadlock.",
-                        2100000); // 2MB + epsilon
-}
-
-// See https://bugs.webkit.org/show_bug.cgi?id=28207
-// In order to trigger this bug, the transaction must acquire an exclusive
-// lock on the DB file before trying to obtain a second handle to the same DB.
-// The only way to force SQLite to obtain an exclusive lock is to change more
-// than cache_size * page_size bytes in the database. The default value for
-// cache_size is 2000 pages, and the default page_size is 1024 bytes. So the
-// size of the blob must be at least 2MB.
-function runTest()
-{
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
-        layoutTestController.waitUntilDone();
-    }
-
-    try {
-        var db1 = openTestDatabase();
-        db1.transaction(function(tx) {
-            // Create the Test table if it does not exist
-            tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo BLOB);");
-            tx.executeSql("INSERT INTO Test VALUES (ZEROBLOB(2097152));", [],
-                          function(result) {
-                              var db2 = openTestDatabase();
-                              log("openDatabase() succeeded.");
-                          },
-                          function(tx, error) {
-                              log("Executing statement failed: " + error.message);
-                          });
-
-            // Clean up the DB to allow for repeated runs of this test
-            // without needing to increase the default allowed quota (5MB)
-            tx.executeSql("DELETE FROM Test;");
-        }, function(error) {
-            log("Transaction failed: " + error.message);
-        }, function() {
-            checkCompletion();
-        });
-    } catch(err) {}
-}
-</script>
+<script src="resources/database-common.js"></script>
+<script src="open-database-while-transaction-in-progress.js"></script>
 </head>
-<body onload="runTest();">
+<body onload="setupAndRunTest();">
 This is a test to see if opening a database while a transaction is running on a different handle to the same database results in a deadlock.<br>
+<pre id="console">
+FAILURE: test didn't run.
+</pre>
 </body>
 </html>
diff --git a/LayoutTests/storage/open-database-while-transaction-in-progress.js b/LayoutTests/storage/open-database-while-transaction-in-progress.js
new file mode 100644 (file)
index 0000000..7a1a0c0
--- /dev/null
@@ -0,0 +1,41 @@
+// Opens the database used in this test case
+function openTestDatabase()
+{
+    return openDatabaseWithSuffix("OpenDatabaseWhileTransactionInProgressTest",
+                                  "1.0",
+                                  "Test to make sure that calling openDatabase() while a transaction is in progress on a different handle to the same database does not result in a deadlock.",
+                                  2100000); // 2MB + epsilon
+}
+
+// See https://bugs.webkit.org/show_bug.cgi?id=28207
+// In order to trigger this bug, the transaction must acquire an exclusive
+// lock on the DB file before trying to obtain a second handle to the same DB.
+// The only way to force SQLite to obtain an exclusive lock is to change more
+// than cache_size * page_size bytes in the database. The default value for
+// cache_size is 2000 pages, and the default page_size is 1024 bytes. So the
+// size of the blob must be at least 2MB.
+function runTest()
+{
+    var db1 = openTestDatabase();
+    db1.transaction(function(tx) {
+        // Create the Test table if it does not exist
+        tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo BLOB);");
+        tx.executeSql("INSERT INTO Test VALUES (ZEROBLOB(2097152));", [],
+                      function(result) {
+                          var db2 = openTestDatabase();
+                          log("openDatabase() succeeded.");
+                      },
+                      function(tx, error) {
+                          log("Executing statement failed: " + error.message);
+                      });
+
+        // Clean up the DB to allow for repeated runs of this test
+        // without needing to increase the default allowed quota (5MB)
+        tx.executeSql("DELETE FROM Test;");
+    }, function(error) {
+        log("Transaction failed: " + error.message);
+    }, function() {
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    });
+}
index a7565b5..11da356 100644 (file)
 <html>
 <head>
-<script>
-
-function log(message)
-{
-    document.body.innerHTML += message + "<br>";
-}
-
-function terminateTest()
-{
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
-function openTestDatabase()
-{
-    return openDatabase("ReadAndWriteTransactionsDontRunTogetherTest",
-                        "1.0",
-                        "Test to make sure that read and write transactions on different DB handles to the same DB don't run at the same time.",
-                        32768);
-}
-
-var readTransactionsInProgress = 0;
-var writeTransactionsInProgress = 0;
-var totalTransactions = 0;
-var finishedTransactions = 0;
-
-function runTransaction(db, readOnly)
-{
-    var transactionFunction = (readOnly ? db.readTransaction : db.transaction);
-    transactionFunction.call(db, function(tx) {
-            if (readOnly) {
-                if (writeTransactionsInProgress != 0) {
-                    log("Read transaction starting while write transaction in progress.");
-                    terminateTest();
-                }
-                readTransactionsInProgress++;
-            } else {
-                if ((readTransactionsInProgress != 0) || (writeTransactionsInProgress != 0)) {
-                    log("Write transaction starting while another transaction in progress.");
-                    terminateTest();
-                }
-                writeTransactionsInProgress++;
-            }
-            tx.executeSql("SELECT * FROM Test;");
-        }, function(error) {
-            log((readOnly ? "Read" : "Write") + " transaction failed: " + error.message);
-            terminateTest();
-        }, function() {
-             finishedTransactions++;
-             if (readOnly)
-                 readTransactionsInProgress--;
-             else
-                 writeTransactionsInProgress--;
-             log("Transaction successful.");
-             if ((finishedTransactions == totalTransactions) && (readTransactionsInProgress == 0) && (writeTransactionsInProgress == 0))
-                 terminateTest();
-        });
-}
-
-function runReadAndWriteTransactions(db1, db2, db3)
-{
-    totalTransactions = 10;
-    finishedTransactions = 0;
-    runTransaction(db1, true);
-    runTransaction(db2, true);
-    runTransaction(db1, false);
-    runTransaction(db1, true);
-    runTransaction(db2, true);
-    runTransaction(db3, true);
-    runTransaction(db1, false);
-    runTransaction(db2, false);
-    runTransaction(db1, true);
-    runTransaction(db3, true);
-}
-
-function runTest() {
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
-        layoutTestController.waitUntilDone();
-    }
-
-    try {
-        var db1 = openTestDatabase();
-        var db2 = openTestDatabase();
-        var db3 = openTestDatabase();
-        db1.transaction(function(tx) {
-                tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo int);");
-            }, function(error) {
-                log("Cannot create the Test table: " + error.message);
-                terminateTest();
-            }, function() {
-                runReadAndWriteTransactions(db1, db2, db3);
-            });
-     } catch(err) {}
-}
-</script>
+<script src="resources/database-common.js"></script>
+<script src="read-and-write-transactions-dont-run-together.js"></script>
 </head>
-<body onload="runTest();">
+<body onload="setupAndRunTest();">
 This test tests that read and write transactions on different handles to the same database don't run together.<br>
+<pre id="console">
+FAILURE: test didn't run.
+</pre>
 </body>
 </html>
diff --git a/LayoutTests/storage/read-and-write-transactions-dont-run-together.js b/LayoutTests/storage/read-and-write-transactions-dont-run-together.js
new file mode 100644 (file)
index 0000000..5b817ba
--- /dev/null
@@ -0,0 +1,81 @@
+function terminateTest()
+{
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function openTestDatabase()
+{
+    return openDatabaseWithSuffix("ReadAndWriteTransactionsDontRunTogetherTest",
+                                  "1.0",
+                                  "Test to make sure that read and write transactions on different DB handles to the same DB don't run at the same time.",
+                                  32768);
+}
+
+var readTransactionsInProgress = 0;
+var writeTransactionsInProgress = 0;
+var totalTransactions = 0;
+var finishedTransactions = 0;
+
+function runTransaction(db, readOnly)
+{
+    var transactionFunction = (readOnly ? db.readTransaction : db.transaction);
+    transactionFunction.call(db, function(tx) {
+            if (readOnly) {
+                if (writeTransactionsInProgress != 0) {
+                    log("Read transaction starting while write transaction in progress.");
+                    terminateTest();
+                }
+                readTransactionsInProgress++;
+            } else {
+                if ((readTransactionsInProgress != 0) || (writeTransactionsInProgress != 0)) {
+                    log("Write transaction starting while another transaction in progress.");
+                    terminateTest();
+                }
+                writeTransactionsInProgress++;
+            }
+            tx.executeSql("SELECT * FROM Test;");
+        }, function(error) {
+            log((readOnly ? "Read" : "Write") + " transaction failed: " + error.message);
+            terminateTest();
+        }, function() {
+             finishedTransactions++;
+             if (readOnly)
+                 readTransactionsInProgress--;
+             else
+                 writeTransactionsInProgress--;
+             log("Transaction successful.");
+             if ((finishedTransactions == totalTransactions) && (readTransactionsInProgress == 0) && (writeTransactionsInProgress == 0))
+                 terminateTest();
+        });
+}
+
+function runReadAndWriteTransactions(db1, db2, db3)
+{
+    totalTransactions = 10;
+    finishedTransactions = 0;
+    runTransaction(db1, true);
+    runTransaction(db2, true);
+    runTransaction(db1, false);
+    runTransaction(db1, true);
+    runTransaction(db2, true);
+    runTransaction(db3, true);
+    runTransaction(db1, false);
+    runTransaction(db2, false);
+    runTransaction(db1, true);
+    runTransaction(db3, true);
+}
+
+function runTest() {
+    var db1 = openTestDatabase();
+    var db2 = openTestDatabase();
+    var db3 = openTestDatabase();
+    db1.transaction(function(tx) {
+            tx.executeSql("CREATE TABLE IF NOT EXISTS Test (Foo int);");
+        }, function(error) {
+            log("Cannot create the Test table: " + error.message);
+            terminateTest();
+        }, function() {
+            runReadAndWriteTransactions(db1, db2, db3);
+        });
+}
diff --git a/LayoutTests/storage/resources/database-common.js b/LayoutTests/storage/resources/database-common.js
new file mode 100644 (file)
index 0000000..d1eb410
--- /dev/null
@@ -0,0 +1,29 @@
+var DB_TEST_SUFFIX = "_dom";
+
+function openDatabaseWithSuffix(name, version, description, size, callback)
+{
+    if (arguments.length > 4) {
+        return openDatabase(name + DB_TEST_SUFFIX, version, description, size, callback);
+    } else {
+        return openDatabase(name + DB_TEST_SUFFIX, version, description, size);
+    }
+}
+
+function log(message)
+{
+    document.getElementById("console").innerText += message + "\n";
+}
+
+function setLocationHash(hash) {
+    location.hash = hash;
+}
+
+function setupAndRunTest()
+{
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+    document.getElementById("console").innerText = "";
+    runTest();
+}
index 57785a6..8baf10a 100644 (file)
 <html>
 <head>
-<script>
-
-function log(message)
-{
-    document.body.innerHTML += message + "<br>";
-}
-
-function terminateTest()
-{
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
-function logAndTerminateTest(message, error)
-{
-    log(message + ": " + error.message);
-    terminateTest();
-}
-
-function cleanup(db)
-{
-    db.transaction(function(tx) {
-            tx.executeSql("DROP TABLE IF EXISTS Test;");
-            tx.executeSql("DROP INDEX IF EXISTS TestIndex;");
-            tx.executeSql("DROP VIEW IF EXISTS TestView;");
-            tx.executeSql("DROP TRIGGER IF EXISTS TestTrigger;");
-        }, function(error) { logAndTerminateTest("Cleanup failed", error); });
-}
-
-function statementSuccessCallback(statementType)
-{
-    log(statementType + " statement succeeded.");
-}
-
-function statementErrorCallback(statementType, error)
-{
-    log(statementType + " statement failed: " + error.message);
-    return false;
-}
-
-function executeStatement(tx, statement, operation)
-{
-    tx.executeSql(statement, [],
-                  function(result) { statementSuccessCallback(operation); },
-                  function(tx, error) { return statementErrorCallback(operation, error); });
-}
-
-function createTableCallback(tx)
-{
-    executeStatement(tx, "CREATE TABLE Test (Foo int);", "SQLITE_CREATE_TABLE");
-}
-
-function createStatementsCallback(tx)
-{
-    executeStatement(tx, "CREATE INDEX TestIndex ON Test (Foo);", "SQLITE_CREATE_INDEX");
-
-    // Even though the following query should trigger a SQLITE_CREATE_TEMP_INDEX operation
-    // (according to http://www.sqlite.org/tempfiles.html), it doesn't, and I'm not aware
-    // of any other way to trigger this operation. So we'll skip it for now.
-    //executeStatement(tx, "SELECT * FROM Test WHERE Foo IN (1, 2, 3);", "SQLITE_CREATE_TEMP_INDEX");
-
-    executeStatement(tx, "CREATE TEMP TABLE TestTempTable (Foo int);", "SQLITE_CREATE_TEMP_TABLE");
-    executeStatement(tx, "CREATE TEMP TRIGGER TestTempTrigger INSERT ON Test BEGIN SELECT COUNT(*) FROM Test; END;", "SQLITE_CREATE_TEMP_TRIGGER");
-    executeStatement(tx, "CREATE TEMP VIEW TestTempView AS SELECT COUNT(*) FROM Test;", "SQLITE_CREATE_TEMP_VIEW");
-    executeStatement(tx, "CREATE TRIGGER TestTrigger INSERT ON Test BEGIN SELECT COUNT(*) FROM Test; END;", "SQLITE_CREATE_TRIGGER");
-    executeStatement(tx, "CREATE VIEW TestView AS SELECT COUNT(*) FROM Test;", "SQLITE_CREATE_VIEW");
-    executeStatement(tx, "CREATE VIRTUAL TABLE TestVirtualTable USING MissingModule;", "SQLITE_CREATE_VTABLE");
-}
-
-function otherStatementsCallback(tx)
-{
-    executeStatement(tx, "SELECT COUNT(*) FROM Test;", "SQLITE_READ");
-    executeStatement(tx, "SELECT COUNT(*) FROM Test;", "SQLITE_SELECT");
-    executeStatement(tx, "DELETE FROM Test;", "SQLITE_DELETE");
-    executeStatement(tx, "INSERT INTO Test VALUES (1);", "SQLITE_INSERT");
-    executeStatement(tx, "UPDATE Test SET Foo = 2 WHERE Foo = 1;", "SQLITE_UPDATE");
-    executeStatement(tx, "PRAGMA cache_size;", "SQLITE_PRAGMA");
-
-    executeStatement(tx, "ALTER TABLE Test RENAME TO TestTable;", "SQLITE_ALTER_TABLE");
-    // Rename the table back to its original name
-    executeStatement(tx, "ALTER TABLE TestTable RENAME To Test;", "SQLITE_ALTER_TABLE");
-
-    executeStatement(tx, "BEGIN TRANSACTION;", "SQLITE_TRANSACTION");
-    executeStatement(tx, "ATTACH main AS TestMain;", "SQLITE_ATTACH");
-    executeStatement(tx, "DETACH TestMain;", "SQLITE_DETACH");
-    executeStatement(tx, "REINDEX;", "SQLITE_REINDEX");
-    executeStatement(tx, "ANALYZE;", "SQLITE_ANALYZE");
-
-    // SQLITE_FUNCTION: allowed write mode
-    // There is no SQL/Javascript API to add user-defined functions to SQLite,
-    // so we cannot test this operation
-}
-
-function dropStatementsCallback(tx)
-{
-    executeStatement(tx, "DROP INDEX TestIndex;", "SQLITE_DROP_INDEX");
-
-    // SQLITE_DROP_TEMP_INDEX: allowed in write mode
-    // Not sure how to test this: temp indexes are automatically dropped when
-    // the database is closed, but HTML5 doesn't specify a closeDatabase() call.
-
-    executeStatement(tx, "DROP TABLE TestTempTable;", "SQLITE_DROP_TEMP_TABLE");
-    executeStatement(tx, "DROP TRIGGER TestTempTrigger;", "SQLITE_DROP_TEMP_TRIGGER");
-    executeStatement(tx, "DROP VIEW TestTempView;", "SQLITE_DROP_TEMP_VIEW");
-    executeStatement(tx, "DROP TRIGGER TestTrigger;", "SQLITE_DROP_TRIGGER");
-    executeStatement(tx, "DROP VIEW TestView;", "SQLITE_DROP_VIEW");
-
-    // SQLITE_DROP_VTABLE: allowed in write mode
-    // Not sure how to test this: we cannot create a virtual table because we do not
-    // have SQL/Javascript APIs to register a module that implements a virtual table.
-    // Therefore, trying to drop a virtual table will always fail (no such table)
-    // before even getting to the authorizer.
-
-    executeStatement(tx, "DROP TABLE Test;", "SQLITE_DROP_TABLE");
-}
-
-function testReadWriteMode(db)
-{
-    db.transaction(function(tx) {
-            createTableCallback(tx);
-            createStatementsCallback(tx);
-            otherStatementsCallback(tx);
-            dropStatementsCallback(tx);
-        },
-        function(error) { logAndTerminateTest("Write transaction failed", error); },
-        function() { log("Write transaction succeeded."); });
-}
-
-function testReadOnlyMode(db)
-{
-    // Test the 'CREATE TABLE' operation; it should be disallowed
-    db.readTransaction(createTableCallback,
-        function(error) { logAndTerminateTest("Read 'CREATE TABLE' transaction failed", error); });
-
-    // In order to test all other 'CREATE' operations, we must create the table first
-    db.transaction(createTableCallback,
-        function(error) { logAndTerminateTest("Write 'CREATE TABLE' transaction failed", error); });
-    db.readTransaction(createStatementsCallback,
-        function(error) { logAndTerminateTest("Read 'CREATE' transaction failed", error); });
-
-    // In order to test the 'DROP' and 'other' operations, we need to first create the respective entities
-    db.transaction(createStatementsCallback,
-        function(error) { logAndTerminateTest("Write 'CREATE' transaction failed", error); });
-    db.readTransaction(otherStatementsCallback,
-        function(error) { logAndTerminateTest("Read 'other' transaction failed", error); });
-
-    // Hack: insert an empty write transaction to guaratee that these transactions are executed sequentially
-    db.transaction(function(tx) { });
-    db.readTransaction(dropStatementsCallback,
-        function(error) { logAndTerminateTest("Read 'DROP' transaction failed", error); },
-        function() { log("Read transactions succeeded."); terminateTest(); });
-}
-
-function runTest()
-{
-    if (window.layoutTestController) {
-        layoutTestController.dumpAsText();
-        layoutTestController.waitUntilDone();
-    }
-
-    try {
-        var db = openDatabase("AuthorizerTest", "1.0", "Tests the database authorizer.", 32768);
-        cleanup(db);
-        testReadWriteMode(db);
-        testReadOnlyMode(db);
-    } catch(err) {}
-}
-</script>
+<script src="resources/database-common.js"></script>
+<script src="test-authorizer.js"></script>
 </head>
-<body onload="runTest();">
+<body onload="setupAndRunTest();">
 This test tests the database authorizer.<br>
+<pre id="console">
+FAILURE: test didn't run.
+</pre>
 </body>
 </html>
diff --git a/LayoutTests/storage/test-authorizer.js b/LayoutTests/storage/test-authorizer.js
new file mode 100644 (file)
index 0000000..4a08c89
--- /dev/null
@@ -0,0 +1,153 @@
+function terminateTest()
+{
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function logAndTerminateTest(message, error)
+{
+    log(message + ": " + error.message);
+    terminateTest();
+}
+
+function cleanup(db)
+{
+    db.transaction(function(tx) {
+            tx.executeSql("DROP TABLE IF EXISTS Test;");
+            tx.executeSql("DROP INDEX IF EXISTS TestIndex;");
+            tx.executeSql("DROP VIEW IF EXISTS TestView;");
+            tx.executeSql("DROP TRIGGER IF EXISTS TestTrigger;");
+        }, function(error) { logAndTerminateTest("Cleanup failed", error); });
+}
+
+function statementSuccessCallback(statementType)
+{
+    log(statementType + " statement succeeded.");
+}
+
+function statementErrorCallback(statementType, error)
+{
+    log(statementType + " statement failed: " + error.message);
+    return false;
+}
+
+function executeStatement(tx, statement, operation)
+{
+    tx.executeSql(statement, [],
+                  function(result) { statementSuccessCallback(operation); },
+                  function(tx, error) { return statementErrorCallback(operation, error); });
+}
+
+function createTableCallback(tx)
+{
+    executeStatement(tx, "CREATE TABLE Test (Foo int);", "SQLITE_CREATE_TABLE");
+}
+
+function createStatementsCallback(tx)
+{
+    executeStatement(tx, "CREATE INDEX TestIndex ON Test (Foo);", "SQLITE_CREATE_INDEX");
+
+    // Even though the following query should trigger a SQLITE_CREATE_TEMP_INDEX operation
+    // (according to http://www.sqlite.org/tempfiles.html), it doesn't, and I'm not aware
+    // of any other way to trigger this operation. So we'll skip it for now.
+    //executeStatement(tx, "SELECT * FROM Test WHERE Foo IN (1, 2, 3);", "SQLITE_CREATE_TEMP_INDEX");
+
+    executeStatement(tx, "CREATE TEMP TABLE TestTempTable (Foo int);", "SQLITE_CREATE_TEMP_TABLE");
+    executeStatement(tx, "CREATE TEMP TRIGGER TestTempTrigger INSERT ON Test BEGIN SELECT COUNT(*) FROM Test; END;", "SQLITE_CREATE_TEMP_TRIGGER");
+    executeStatement(tx, "CREATE TEMP VIEW TestTempView AS SELECT COUNT(*) FROM Test;", "SQLITE_CREATE_TEMP_VIEW");
+    executeStatement(tx, "CREATE TRIGGER TestTrigger INSERT ON Test BEGIN SELECT COUNT(*) FROM Test; END;", "SQLITE_CREATE_TRIGGER");
+    executeStatement(tx, "CREATE VIEW TestView AS SELECT COUNT(*) FROM Test;", "SQLITE_CREATE_VIEW");
+    executeStatement(tx, "CREATE VIRTUAL TABLE TestVirtualTable USING MissingModule;", "SQLITE_CREATE_VTABLE");
+}
+
+function otherStatementsCallback(tx)
+{
+    executeStatement(tx, "SELECT COUNT(*) FROM Test;", "SQLITE_READ");
+    executeStatement(tx, "SELECT COUNT(*) FROM Test;", "SQLITE_SELECT");
+    executeStatement(tx, "DELETE FROM Test;", "SQLITE_DELETE");
+    executeStatement(tx, "INSERT INTO Test VALUES (1);", "SQLITE_INSERT");
+    executeStatement(tx, "UPDATE Test SET Foo = 2 WHERE Foo = 1;", "SQLITE_UPDATE");
+    executeStatement(tx, "PRAGMA cache_size;", "SQLITE_PRAGMA");
+
+    executeStatement(tx, "ALTER TABLE Test RENAME TO TestTable;", "SQLITE_ALTER_TABLE");
+    // Rename the table back to its original name
+    executeStatement(tx, "ALTER TABLE TestTable RENAME To Test;", "SQLITE_ALTER_TABLE");
+
+    executeStatement(tx, "BEGIN TRANSACTION;", "SQLITE_TRANSACTION");
+    executeStatement(tx, "ATTACH main AS TestMain;", "SQLITE_ATTACH");
+    executeStatement(tx, "DETACH TestMain;", "SQLITE_DETACH");
+    executeStatement(tx, "REINDEX;", "SQLITE_REINDEX");
+    executeStatement(tx, "ANALYZE;", "SQLITE_ANALYZE");
+
+    // SQLITE_FUNCTION: allowed write mode
+    // There is no SQL/Javascript API to add user-defined functions to SQLite,
+    // so we cannot test this operation
+}
+
+function dropStatementsCallback(tx)
+{
+    executeStatement(tx, "DROP INDEX TestIndex;", "SQLITE_DROP_INDEX");
+
+    // SQLITE_DROP_TEMP_INDEX: allowed in write mode
+    // Not sure how to test this: temp indexes are automatically dropped when
+    // the database is closed, but HTML5 doesn't specify a closeDatabase() call.
+
+    executeStatement(tx, "DROP TABLE TestTempTable;", "SQLITE_DROP_TEMP_TABLE");
+    executeStatement(tx, "DROP TRIGGER TestTempTrigger;", "SQLITE_DROP_TEMP_TRIGGER");
+    executeStatement(tx, "DROP VIEW TestTempView;", "SQLITE_DROP_TEMP_VIEW");
+    executeStatement(tx, "DROP TRIGGER TestTrigger;", "SQLITE_DROP_TRIGGER");
+    executeStatement(tx, "DROP VIEW TestView;", "SQLITE_DROP_VIEW");
+
+    // SQLITE_DROP_VTABLE: allowed in write mode
+    // Not sure how to test this: we cannot create a virtual table because we do not
+    // have SQL/Javascript APIs to register a module that implements a virtual table.
+    // Therefore, trying to drop a virtual table will always fail (no such table)
+    // before even getting to the authorizer.
+
+    executeStatement(tx, "DROP TABLE Test;", "SQLITE_DROP_TABLE");
+}
+
+function testReadWriteMode(db)
+{
+    db.transaction(function(tx) {
+            createTableCallback(tx);
+            createStatementsCallback(tx);
+            otherStatementsCallback(tx);
+            dropStatementsCallback(tx);
+        },
+        function(error) { logAndTerminateTest("Write transaction failed", error); },
+        function() { log("Write transaction succeeded."); });
+}
+
+function testReadOnlyMode(db)
+{
+    // Test the 'CREATE TABLE' operation; it should be disallowed
+    db.readTransaction(createTableCallback,
+        function(error) { logAndTerminateTest("Read 'CREATE TABLE' transaction failed", error); });
+
+    // In order to test all other 'CREATE' operations, we must create the table first
+    db.transaction(createTableCallback,
+        function(error) { logAndTerminateTest("Write 'CREATE TABLE' transaction failed", error); });
+    db.readTransaction(createStatementsCallback,
+        function(error) { logAndTerminateTest("Read 'CREATE' transaction failed", error); });
+
+    // In order to test the 'DROP' and 'other' operations, we need to first create the respective entities
+    db.transaction(createStatementsCallback,
+        function(error) { logAndTerminateTest("Write 'CREATE' transaction failed", error); });
+    db.readTransaction(otherStatementsCallback,
+        function(error) { logAndTerminateTest("Read 'other' transaction failed", error); });
+
+    // Hack: insert an empty write transaction to guaratee that these transactions are executed sequentially
+    db.transaction(function(tx) { });
+    db.readTransaction(dropStatementsCallback,
+        function(error) { logAndTerminateTest("Read 'DROP' transaction failed", error); },
+        function() { log("Read transactions succeeded."); terminateTest(); });
+}
+
+function runTest()
+{
+    var db = openDatabaseWithSuffix("AuthorizerTest", "1.0", "Tests the database authorizer.", 32768);
+    cleanup(db);
+    testReadWriteMode(db);
+    testReadOnlyMode(db);
+}