Commit add547ad authored by ericu@google.com's avatar ericu@google.com

Add read/write tests, index creation/deletion test.

This is based on https://chromiumcodereview.appspot.com/10790041/, not yet submitted.

BUG=137764
TEST=self

Review URL: https://chromiumcodereview.appspot.com/10803029

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148635 0039d316-1c4b-4281-b951-d872f2087c98
parent bd88268e
...@@ -49,17 +49,18 @@ function onError(e) { ...@@ -49,17 +49,18 @@ function onError(e) {
throw new Error(e); throw new Error(e);
} }
var version = 2; // The version with our object stores. var baseVersion = 2; // The version with our object stores.
var curVersion;
// Valid options fields: // Valid options fields:
// indexName: the name of an index to create on each object store // indexName: the name of an index to create on each object store
// indexKeyPath: likewise // indexKeyPath: the key path for that index
// indexIsUnique: the "unique" option for IDBIndexParameters // indexIsUnique: the "unique" option for IDBIndexParameters
// indexIsMultiEntry: the "multiEntry" option for IDBIndexParameters // indexIsMultiEntry: the "multiEntry" option for IDBIndexParameters
// //
function createDatabase( function createDatabase(
name, objectStoreNames, handler, errorHandler, options) { name, objectStoreNames, handler, errorHandler, options) {
var openRequest = indexedDB.open(name, version); var openRequest = indexedDB.open(name, baseVersion);
openRequest.onblocked = errorHandler; openRequest.onblocked = errorHandler;
function createObjectStores(db) { function createObjectStores(db) {
for (var store in objectStoreNames) { for (var store in objectStoreNames) {
...@@ -87,24 +88,60 @@ function createDatabase( ...@@ -87,24 +88,60 @@ function createDatabase(
db.onerror = function(ev) { db.onerror = function(ev) {
console.log("db error", arguments, openRequest.webkitErrorMessage); console.log("db error", arguments, openRequest.webkitErrorMessage);
errorHandler(); errorHandler();
}; }
if (db.version != version) { if (db.version != baseVersion) {
// This is the current Chrome path. // This is the current Chrome path.
var setVersionRequest = db.setVersion(version); var setVersionRequest = db.setVersion(baseVersion);
setVersionRequest.onfailure = errorHandler; setVersionRequest.onerror = errorHandler;
setVersionRequest.onsuccess = function(e) { setVersionRequest.onsuccess = function(e) {
curVersion = db.version;
assert(setVersionRequest == e.target); assert(setVersionRequest == e.target);
createObjectStores(db); createObjectStores(db);
var versionTransaction = setVersionRequest.result; var versionTransaction = setVersionRequest.result;
versionTransaction.oncomplete = function() {handler(db); }; versionTransaction.oncomplete = function() { handler(db); };
versionTransaction.onerror = onError; versionTransaction.onerror = onError;
}; }
} else { } else {
handler(db); handler(db);
} }
} }
} }
// You must close all database connections before calling this.
function alterObjectStores(
name, objectStoreNames, func, handler, errorHandler) {
var version = curVersion + 1;
var openRequest = indexedDB.open(name, version);
openRequest.onblocked = errorHandler;
// TODO: This won't work in Firefox yet; see above in createDatabase.
openRequest.onsuccess = function(ev) {
assert(openRequest == ev.target);
var db = openRequest.result;
db.onerror = function(ev) {
console.log("error altering db", arguments,
openRequest.webkitErrorMessage);
errorHandler();
}
if (db.version != version) {
var setVersionRequest = db.setVersion(version);
setVersionRequest.onerror = errorHandler;
setVersionRequest.onsuccess =
function(e) {
curVersion = db.version;
assert(setVersionRequest == e.target);
var versionTransaction = setVersionRequest.result;
versionTransaction.oncomplete = function() { handler(db); };
versionTransaction.onerror = onError;
for (var store in objectStoreNames) {
func(versionTransaction.objectStore(objectStoreNames[store]));
}
}
} else {
errorHandler();
}
}
}
function getTransaction(db, objectStoreNames, mode, opt_handler) { function getTransaction(db, objectStoreNames, mode, opt_handler) {
var transaction = db.transaction(objectStoreNames, mode); var transaction = db.transaction(objectStoreNames, mode);
transaction.onerror = onError; transaction.onerror = onError;
...@@ -139,6 +176,68 @@ function getCompletionFunc(testName, startTime, onTestComplete) { ...@@ -139,6 +176,68 @@ function getCompletionFunc(testName, startTime, onTestComplete) {
} }
} }
function getDisplayName(args) {
// The last arg is the completion callback the test runner tacks on.
return getDisplayName.caller.name + "_" +
Array.prototype.slice.call(args, 0, args.length - 1).join("_");
}
function getSimpleKey(i) {
return "key " + i;
}
function getSimpleValue(i) {
return "value " + i;
}
function putLinearValues(
transaction, objectStoreNames, numKeys, getKey, getValue) {
if (!getKey)
getKey = getSimpleKey;
if (!getValue)
getValue = getSimpleValue;
for (var i in objectStoreNames) {
var os = transaction.objectStore(objectStoreNames[i]);
for (var j = 0; j < numKeys; ++j) {
var request = os.put(getValue(j), getKey(j));
request.onerror = onError;
}
}
}
function getRandomValues(
transaction, objectStoreNames, numReads, numKeys, indexName, getKey) {
if (!getKey)
getKey = getSimpleKey;
for (var i in objectStoreNames) {
var os = transaction.objectStore(objectStoreNames[i]);
var source = os;
if (indexName)
source = source.index(indexName);
for (var j = 0; j < numReads; ++j) {
var rand = Math.floor(Math.random() * numKeys);
var request = source.get(getKey(rand));
request.onerror = onError;
}
}
}
function putRandomValues(
transaction, objectStoreNames, numPuts, numKeys, getKey, getValue) {
if (!getKey)
getKey = getSimpleKey;
if (!getValue)
getValue = getSimpleValue;
for (var i in objectStoreNames) {
var os = transaction.objectStore(objectStoreNames[i]);
for (var j = 0; j < numPuts; ++j) {
var rand = Math.floor(Math.random() * numKeys);
var request = os.put(getValue(rand), getKey(rand));
request.onerror = onError;
}
}
}
function stringOfLength(n) { function stringOfLength(n) {
assert(n > 0); assert(n > 0);
assert(n == Math.floor(n)); assert(n == Math.floor(n));
......
...@@ -6,8 +6,7 @@ var overallTestStartTime = Date.now(); ...@@ -6,8 +6,7 @@ var overallTestStartTime = Date.now();
function testCreateKeysInStores( function testCreateKeysInStores(
numKeys, numStores, payloadLength, onTestComplete) { numKeys, numStores, payloadLength, onTestComplete) {
var testName = "testCreateKeysInStores_" + numKeys + "_" + numStores + "_" + var testName = getDisplayName(arguments);
payloadLength;
assert(numKeys >= 0); assert(numKeys >= 0);
assert(numStores >= 1); assert(numStores >= 1);
var objectStoreNames = []; var objectStoreNames = [];
...@@ -15,57 +14,39 @@ function testCreateKeysInStores( ...@@ -15,57 +14,39 @@ function testCreateKeysInStores(
objectStoreNames.push("store " + i); objectStoreNames.push("store " + i);
} }
var value = stringOfLength(payloadLength); var value = stringOfLength(payloadLength);
function getValue() {
return value;
}
function onCreated(db) { function onCreated(db) {
automation.setStatus("Constructing transaction."); automation.setStatus("Constructing transaction.");
var completionFunc = var completionFunc =
getCompletionFunc(testName, Date.now(), onTestComplete); getCompletionFunc(testName, Date.now(), onTestComplete);
var transaction = getTransaction(db, objectStoreNames, "readwrite", var transaction =
function() { completionFunc(); }); getTransaction(db, objectStoreNames, "readwrite", completionFunc);
for (var i in objectStoreNames) { putLinearValues(transaction, objectStoreNames, numKeys, null, getValue);
var os = transaction.objectStore(objectStoreNames[i]);
assert(os);
for (var j = 0; j < numKeys; ++j) {
os.put(value, "key " + j);
}
}
} }
automation.setStatus("Creating database."); automation.setStatus("Creating database.");
createDatabase(testName, objectStoreNames, onCreated, onError); createDatabase(testName, objectStoreNames, onCreated, onError);
} }
function testRandomReads(numKeys, numReadsPerTransaction, numTransactions, function testRandomReadsAndWrites(
useIndex, onTestComplete) { numKeys, numReadsPerTransaction, numWritesPerTransaction, numTransactions,
var indexText = "_bare"; useIndexForReads, onTestComplete) {
var indexName; var indexName;
if (useIndex) { if (useIndexForReads)
indexText = "_index";
indexName = "index"; indexName = "index";
} var testName = getDisplayName(arguments);
var testName = "testRandomReads_" + numKeys + "_" + numReadsPerTransaction +
"_" + numTransactions + indexText;
var numTransactionsLeft = numTransactions; var numTransactionsLeft = numTransactions;
var storeName = "store"; var objectStoreNames = ["store"];
var objectStoreNames = [storeName];
var numTransactionsRunning; var numTransactionsRunning;
function getKey(i) {
return "key " + i;
}
function getValue(i) {
return "value " + i;
}
function onCreated(db) { function onCreated(db) {
automation.setStatus("Setting up test database."); automation.setStatus("Setting up test database.");
var transaction = getTransaction(db, objectStoreNames, "readwrite", var transaction = getTransaction(db, objectStoreNames, "readwrite",
function() { onSetupComplete(db); }); function() { onSetupComplete(db); });
var os = transaction.objectStore(storeName); putLinearValues(transaction, objectStoreNames, numKeys, null,
assert(os); function () { return "test value"; });
for (var j = 0; j < numKeys; ++j) {
os.put(getValue(i), getKey(j));
}
} }
var completionFunc; var completionFunc;
function onSetupComplete(db) { function onSetupComplete(db) {
...@@ -80,11 +61,12 @@ function testRandomReads(numKeys, numReadsPerTransaction, numTransactions, ...@@ -80,11 +61,12 @@ function testRandomReads(numKeys, numReadsPerTransaction, numTransactions,
} }
--numTransactionsLeft; --numTransactionsLeft;
++numTransactionsRunning; ++numTransactionsRunning;
var valuesToRead = numReadsPerTransaction; var mode = "readonly";
var transaction = getTransaction(db, objectStoreNames, "readonly", if (numWritesPerTransaction)
mode = "readwrite";
var transaction = getTransaction(db, objectStoreNames, mode,
function() { function() {
assert(!--numTransactionsRunning); assert(!--numTransactionsRunning);
assert(!valuesToRead);
if (numTransactionsLeft <= 0) { if (numTransactionsLeft <= 0) {
completionFunc(); completionFunc();
} else { } else {
...@@ -92,46 +74,83 @@ function testRandomReads(numKeys, numReadsPerTransaction, numTransactions, ...@@ -92,46 +74,83 @@ function testRandomReads(numKeys, numReadsPerTransaction, numTransactions,
} }
}); });
var queryObject = transaction.objectStore(storeName); getRandomValues(transaction, objectStoreNames, numReadsPerTransaction,
if (useIndex) { numKeys, indexName);
queryObject = queryObject.index(indexName); putRandomValues(transaction, objectStoreNames, numWritesPerTransaction,
} numKeys);
assert(queryObject);
for (var i = 0; i < numReadsPerTransaction; ++i) {
var rand = Math.floor(Math.random() * numKeys);
var request = queryObject.get(getKey(rand));
request.onerror = onError;
request.onsuccess = function () {
assert(valuesToRead--);
}
}
} }
automation.setStatus("Creating database."); automation.setStatus("Creating database.");
var options = {}; var options = {};
if (useIndex) { if (useIndexForReads) {
options.indexName = indexName; options.indexName = indexName;
options.indexKeyPath = ""; options.indexKeyPath = "";
options.indexIsUnique = true; options.indexIsUnique = false;
options.indexIsMultiEntry = false; options.indexIsMultiEntry = false;
} }
createDatabase(testName, objectStoreNames, onCreated, onError, options); createDatabase(testName, objectStoreNames, onCreated, onError, options);
} }
function testCreateAndDeleteIndex(numKeys, onTestComplete) {
var testName = getDisplayName(arguments);
var objectStoreNames = ["store"];
function getValue(i) {
return { firstName: i + " first name", lastName: i + " last name" };
}
var startTime;
function onCreated(db) {
automation.setStatus("Initializing data.");
var transaction = getTransaction(db, objectStoreNames, "readwrite",
function() { onPopulated(db); });
putLinearValues(transaction, objectStoreNames, numKeys, null, getValue);
}
function onPopulated(db) {
db.close();
automation.setStatus("Building index.");
startTime = Date.now();
var f = function(objectStore) {
objectStore.createIndex("index", "firstName", {unique: true});
};
alterObjectStores(testName, objectStoreNames, f, onIndexCreated, onError);
}
var completionFunc;
function onIndexCreated(db) {
db.close();
var indexCreationCompleteTime = Date.now();
automation.addResult("testCreateIndex",
indexCreationCompleteTime - startTime);
completionFunc = getCompletionFunc("testDeleteIndex",
indexCreationCompleteTime, onTestComplete);
var f = function(objectStore) {
objectStore.deleteIndex("index");
};
automation.setStatus("Deleting index.");
alterObjectStores(testName, objectStoreNames, f, completionFunc, onError);
}
automation.setStatus("Creating database.");
createDatabase(testName, objectStoreNames, onCreated, onError);
}
var kUseIndex = true; var kUseIndex = true;
var kDontUseIndex = false; var kDontUseIndex = false;
var tests = [ var tests = [
[testCreateKeysInStores, 1, 1, 1], [testCreateKeysInStores, 1, 1, 1],
[testCreateKeysInStores, 100, 1, 1], [testCreateKeysInStores, 100, 1, 1],
[testCreateKeysInStores, 1, 100, 1], [testCreateKeysInStores, 1, 100, 1],
[testCreateKeysInStores, 100, 1, 10000], [testCreateKeysInStores, 100, 1, 10000],
[testRandomReads, 1000, 5, 50, kDontUseIndex], [testRandomReadsAndWrites, 1000, 5, 0, 50, kDontUseIndex],
[testRandomReads, 1000, 50, 5, kDontUseIndex], [testRandomReadsAndWrites, 1000, 50, 0, 5, kDontUseIndex],
[testRandomReads, 5000, 50, 5, kDontUseIndex], [testRandomReadsAndWrites, 5000, 50, 0, 5, kDontUseIndex],
[testRandomReads, 1000, 5, 50, kUseIndex], [testRandomReadsAndWrites, 1000, 5, 0, 50, kUseIndex],
[testRandomReads, 1000, 50, 5, kUseIndex], [testRandomReadsAndWrites, 1000, 50, 0, 5, kUseIndex],
[testRandomReads, 5000, 50, 5, kUseIndex] [testRandomReadsAndWrites, 5000, 50, 0, 5, kUseIndex],
[testRandomReadsAndWrites, 1000, 5, 5, 50, kDontUseIndex],
[testRandomReadsAndWrites, 1000, 5, 5, 50, kUseIndex],
[testCreateAndDeleteIndex, 1000]
]; ];
var currentTest = 0; var currentTest = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment