blob: 12021fb8e81a35d662677c9880a6869710b70614 [file] [log] [blame]
<!DOCTYPE html>
<html>
<!--
Copyright 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<head>
<title>IDB test that db's corrupted while open are properly handled Part 1 / 2</title>
<script type="text/javascript" src="common.js"></script>
<script>
var testType = 'get';
function test() {
testType = location.hash.substring(1);
if (testType == 'testCommon') {
fail('"testCommon" is a reserved test name');
return;
}
indexedDBTest(upgradeCallback, openCallback);
}
var numObjectsWrittenToDb = 5;
var numTransactions = 0;
var numTransactionErrors = 0;
var numTransactionAborts = 0;
var numKeys = 0;
var transaction;
var request;
var db;
var objectStore;
function upgradeCallback() {
db = event.target.result;
deleteAllObjectStores(db);
objectStore = db.createObjectStore('storeName', { autoIncrement : true });
var i;
var len = 80;
var data = Array(len);
for (i = 0; i < len; ++i) {
data[i] = i;
}
for (i = 0; i < numObjectsWrittenToDb; ++i) {
var key = 'key-' + i;
request = objectStore.add(data, key);
request.onerror = unexpectedErrorCallback;
request.onsuccess = upgradeTransactionComplete;
}
}
function upgradeTransactionComplete() {
++numTransactions;
if (numTransactions === numObjectsWrittenToDb) {
debug("All transactions written");
}
}
function transactionError(event) {
if (event.target.error) {
numTransactionErrors += 1;
} else {
fail("Transaction onerror had no error");
}
}
function transactionAbort(event) {
if (event.target.error) {
numTransactionAborts += 1;
} else {
fail("Transaction onabort had no error");
}
}
function requestError(event) {
if (!event.target.error) {
fail("get request had no/invalid error");
}
}
function databaseClosed(event) {
shouldBe("numTransactionErrors", "1");
shouldBe("numTransactionAborts", "1");
done("Closed as expected");
}
function testXhr(url, onSuccess) {
var xmlhttp = new window.XMLHttpRequest();
xmlhttp.open("GET", url, /*async=*/false);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4) {
if (xmlhttp.status === 200) {
onSuccess()
}
}
};
xmlhttp.send();
}
var tests = {
// Common setup tasks for the other tests in this object
testCommon: function(mode) {
transaction = db.transaction('storeName', mode);
db.onclose = databaseClosed;
transaction.onabort = transactionAbort;
transaction.onerror = transactionError;
objectStore = transaction.objectStore('storeName');
},
get: function() {
testXhr("/corrupt/test/fail?class=LevelDBTransaction&method=Get&instNum=1",
function() {
tests.testCommon('readonly');
request = objectStore.get('key-0');
request.onsuccess = unexpectedSuccessCallback;
request.onerror = requestError;
});
},
failTransactionCommit: function() {
tests.testCommon('readwrite');
db.onclose = function(event) {
shouldBe("numTransactionErrors", "0");
shouldBe("numTransactionAborts", "1");
done("Closed as expected");
};
testXhr("/corrupt/test/fail?class=LevelDBTransaction&method=Commit", function() {
request = objectStore.put("Any Value", 'key-0');
request.onerror = requestError;
});
},
failWebkitGetDatabaseNames: function() {
tests.testCommon('readonly');
gotRequestError = 0;
db.onclose = function(event) {
shouldBe("numTransactionErrors", "0");
shouldBe("numTransactionAborts", "1");
shouldBe("gotRequestError", "1");
done("Closed as expected");
};
testXhr("/corrupt/test/fail?class=LevelDBIterator&method=Seek", function() {
request = window.indexedDB.webkitGetDatabaseNames();
request.onsuccess = unexpectedSuccessCallback;
request.onerror = function(evt) {
gotRequestError += 1;
};
});
},
iterate: function() {
testXhr("/corrupt/test/corruptdb?storeName", function() {
tests.testCommon('readonly');
request = objectStore.openCursor();
request.onerror = requestError;
request.onsuccess = function (event){
var cursor = request.result;
if (cursor) {
// Get an object. Probably shouldn't get this far, but won't call this an error.
cursor.continue();
} else {
// Got the last object. We shouldn't get this far.
fail("Should *not* have been able to iterate over database.");
}
};
});
},
failGetBlobJournal: function() {
// Get() #1 is the put (GetNewVersionNumber)
// Get() #2 is the blob key generator (GetBlobKeyGeneratorCurrentNumber)
// Get() #3 is the journal (GetPrimaryBlobJournal)
testXhr("/corrupt/test/fail?class=LevelDBTransaction&method=Get&instNum=3", function() {
tests.testCommon('readwrite');
request = objectStore.put({blob: new Blob(['abc'])}, 'key-0');
request.onerror = requestError;
db.onclose = function databaseClosed(event) {
shouldBe("numTransactionErrors", "0");
shouldBe("numTransactionAborts", "1");
done("Closed as expected");
};
});
},
clearObjectStore: function() {
testXhr("/corrupt/test/corruptdb?storeName", function() {
tests.testCommon('readwrite');
request = objectStore.clear();
request.onerror = requestError;
request.onsuccess = unexpectedSuccessCallback
});
}
};
function openCallback() {
if (testType in tests)
tests[testType]();
else
fail('Unknown test: "' + testType + '"');
}
</script>
</head>
<body onLoad="test()">
<div id="status">Starting...</div>
</body>
</html>