OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 var overallTestStartTime = Date.now(); | 5 var overallTestStartTime = Date.now(); |
6 | 6 |
7 function testCreateKeysInStores( | 7 function testCreateKeysInStores( |
8 numKeys, numStores, payloadLength, onTestComplete) { | 8 numKeys, numStores, payloadLength, onTestComplete) { |
9 var testName = getDisplayName(arguments); | 9 var testName = getDisplayName(arguments); |
10 assert(numKeys >= 0); | 10 assert(numKeys >= 0); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 function onCreated(db) { | 44 function onCreated(db) { |
45 automation.setStatus("Setting up test database."); | 45 automation.setStatus("Setting up test database."); |
46 var transaction = getTransaction(db, objectStoreNames, "readwrite", | 46 var transaction = getTransaction(db, objectStoreNames, "readwrite", |
47 function() { onSetupComplete(db); }); | 47 function() { onSetupComplete(db); }); |
48 putLinearValues(transaction, objectStoreNames, numKeys, null, | 48 putLinearValues(transaction, objectStoreNames, numKeys, null, |
49 function () { return "test value"; }); | 49 function () { return "test value"; }); |
50 } | 50 } |
51 var completionFunc; | 51 var completionFunc; |
52 function onSetupComplete(db) { | 52 function onSetupComplete(db) { |
53 automation.setStatus("Setup complete."); | 53 automation.setStatus("Setup complete."); |
54 completionFunc = getCompletionFunc(testName, Date.now(), onTestComplete); | |
54 runOneBatch(db); | 55 runOneBatch(db); |
55 completionFunc = getCompletionFunc(testName, Date.now(), onTestComplete); | |
56 } | 56 } |
57 | 57 |
58 function runOneBatch(db) { | 58 function runOneBatch(db) { |
59 if (numTransactionsLeft <= 0) { | 59 if (numTransactionsLeft <= 0) { |
60 return; | 60 return; |
61 } | 61 } |
62 --numTransactionsLeft; | 62 --numTransactionsLeft; |
63 ++numTransactionsRunning; | 63 ++numTransactionsRunning; |
64 var mode = "readonly"; | 64 var mode = "readonly"; |
65 if (numWritesPerTransaction) | 65 if (numWritesPerTransaction) |
66 mode = "readwrite"; | 66 mode = "readwrite"; |
67 var transaction = getTransaction(db, objectStoreNames, mode, | 67 var transaction = getTransaction(db, objectStoreNames, mode, |
68 function() { | 68 function() { |
69 assert(!--numTransactionsRunning); | 69 assert(!--numTransactionsRunning); |
70 if (numTransactionsLeft <= 0) { | 70 if (numTransactionsLeft <= 0) { |
71 completionFunc(); | 71 completionFunc(); |
72 } else { | 72 } else { |
73 runOneBatch(db); | 73 runOneBatch(db); |
74 } | 74 } |
75 }); | 75 }); |
76 | 76 |
77 getRandomValues(transaction, objectStoreNames, numReadsPerTransaction, | 77 getRandomValues(transaction, objectStoreNames, numReadsPerTransaction, |
78 numKeys, indexName); | 78 numKeys, indexName); |
79 putRandomValues(transaction, objectStoreNames, numWritesPerTransaction, | 79 putRandomValues(transaction, objectStoreNames, numWritesPerTransaction, |
80 numKeys); | 80 numKeys); |
81 } | 81 } |
82 | 82 |
83 automation.setStatus("Creating database."); | 83 automation.setStatus("Creating database."); |
84 var options = {}; | 84 var options; |
85 if (useIndexForReads) { | 85 if (useIndexForReads) { |
86 options.indexName = indexName; | 86 options = [{ |
87 options.indexKeyPath = ""; | 87 indexName: indexName, |
88 options.indexIsUnique = false; | 88 indexKeyPath: "", |
89 options.indexIsMultiEntry = false; | 89 indexIsUnique: false, |
90 indexIsMultiEntry: false, | |
91 }]; | |
90 } | 92 } |
91 createDatabase(testName, objectStoreNames, onCreated, onError, options); | 93 createDatabase(testName, objectStoreNames, onCreated, onError, options); |
92 } | 94 } |
93 | 95 |
94 function testCreateAndDeleteIndex(numKeys, onTestComplete) { | 96 function testCreateAndDeleteIndex(numKeys, onTestComplete) { |
95 var testName = getDisplayName(arguments); | 97 var testName = getDisplayName(arguments); |
96 var objectStoreNames = ["store"]; | 98 var objectStoreNames = ["store"]; |
97 function getValue(i) { | 99 function getValue(i) { |
98 return { firstName: i + " first name", lastName: i + " last name" }; | 100 return { firstName: i + " first name", lastName: i + " last name" }; |
99 } | 101 } |
(...skipping 28 matching lines...) Expand all Loading... | |
128 objectStore.deleteIndex("index"); | 130 objectStore.deleteIndex("index"); |
129 }; | 131 }; |
130 automation.setStatus("Deleting index."); | 132 automation.setStatus("Deleting index."); |
131 alterObjectStores(testName, objectStoreNames, f, completionFunc, onError); | 133 alterObjectStores(testName, objectStoreNames, f, completionFunc, onError); |
132 } | 134 } |
133 | 135 |
134 automation.setStatus("Creating database."); | 136 automation.setStatus("Creating database."); |
135 createDatabase(testName, objectStoreNames, onCreated, onError); | 137 createDatabase(testName, objectStoreNames, onCreated, onError); |
136 } | 138 } |
137 | 139 |
140 function testCursorReadsAndRandomWrites( | |
141 readKeysOnly, useIndexForReads, writeToAnotherStore, onTestComplete) { | |
142 // There's no key cursor unless you're reading from an index. | |
143 assert(useIndexForReads || !readKeysOnly); | |
144 // If we're writing to another store, having an index would constrain our | |
145 // writes, as we create both object stores with the same configurations. | |
146 // We could do that if needed, but it's simpler not to. | |
147 assert(!useIndexForReads || !writeToAnotherStore); | |
148 var numKeys = 1000; | |
149 var numReadsPerTransaction = 100; | |
150 var testName = getDisplayName(arguments); | |
151 var objectStoreNames = ["input store"]; | |
152 if (writeToAnotherStore) | |
153 objectStoreNames.push("output store"); | |
154 var getKeyForRead = getSimpleKey; | |
155 var indexName; | |
156 if (useIndexForReads) { | |
157 indexName = "index"; | |
158 getKeyForRead = function(i) { | |
159 // This depends on the implementations of getValuesFromCursor and | |
160 // getObjectValue. We reverse the order of the iteration here so that | |
161 // setting up bounds from k to k+n with n>0 works. Without this reversal, | |
162 // the upper bound is below the lower bound. | |
163 return getBackwardIndexKey(numKeys - i); | |
164 } | |
165 } | |
166 | |
167 function onCreated(db) { | |
168 automation.setStatus("Setting up test database."); | |
169 var transaction = getTransaction(db, objectStoreNames, "readwrite", | |
170 function() { onSetupComplete(db); }); | |
171 putLinearValues(transaction, objectStoreNames, numKeys, getSimpleKey, | |
172 getObjectValue); | |
173 } | |
174 function onSetupComplete(db) { | |
175 automation.setStatus("Setup complete."); | |
176 var completionFunc = | |
177 getCompletionFunc(testName, Date.now(), onTestComplete); | |
178 var mode = "readonly"; | |
179 if (writeToAnotherStore) | |
180 mode = "readwrite"; | |
181 var transaction = | |
182 getTransaction(db, objectStoreNames, mode, completionFunc); | |
183 | |
184 getValuesFromCursor( | |
185 transaction, objectStoreNames[0], numReadsPerTransaction, numKeys, | |
186 indexName, getKeyForRead, readKeysOnly, objectStoreNames[1]); | |
187 } | |
188 | |
189 automation.setStatus("Creating database."); | |
190 var options; | |
191 if (useIndexForReads) { | |
192 options = [{ | |
193 indexName: indexName, | |
194 indexKeyPath: "lastName", // depends on getBackwardIndexKey() | |
195 indexIsUnique: true, | |
196 indexIsMultiEntry: false, | |
197 }]; | |
198 } | |
199 createDatabase(testName, objectStoreNames, onCreated, onError, options); | |
200 } | |
201 | |
202 function testSporadicWrites( | |
203 numWritesPerTransaction, numIndices, onTestComplete) { | |
204 var numKeys = 1000; | |
205 // With 30 transactions, spaced 50ms apart, we'll need at least 1.5s. | |
206 var numTransactions = 30; | |
207 var delayBetweenBatches = 50; | |
208 var indexName; | |
209 var testName = getDisplayName(arguments); | |
210 var numTransactionsLeft = numTransactions; | |
211 var objectStoreNames = ["store"]; | |
212 var numTransactionsRunning = 0; | |
213 | |
214 var getValue = getSimpleValue; | |
215 if (numIndices) | |
216 getValue = function (i) { return getNFieldObjectValue(i, numIndices); }; | |
217 | |
218 function onCreated(db) { | |
219 automation.setStatus("Setting up test database."); | |
220 var transaction = getTransaction(db, objectStoreNames, "readwrite", | |
221 function() { onSetupComplete(db); }); | |
222 putLinearValues(transaction, objectStoreNames, numKeys, getSimpleKey, | |
223 getValue); | |
224 } | |
225 var completionFunc; | |
226 function onSetupComplete(db) { | |
227 automation.setStatus("Setup complete."); | |
228 completionFunc = getCompletionFunc(testName, Date.now(), onTestComplete); | |
229 runOneBatch(db); | |
230 } | |
231 | |
232 function runOneBatch(db) { | |
233 assert(numTransactionsLeft); | |
234 if (--numTransactionsLeft) { | |
235 setTimeout(function () { runOneBatch(db); }, delayBetweenBatches); | |
236 } | |
237 ++numTransactionsRunning; | |
238 | |
239 function batchComplete() { | |
240 assert(numTransactionsRunning); | |
241 if (!--numTransactionsRunning && !numTransactionsLeft) | |
242 completionFunc(); | |
243 } | |
244 | |
245 var mode = "readonly"; | |
246 if (numWritesPerTransaction) | |
247 mode = "readwrite"; | |
248 | |
249 var transaction = getTransaction(db, objectStoreNames, mode, batchComplete); | |
250 putRandomValues(transaction, objectStoreNames, numWritesPerTransaction, | |
251 numKeys); | |
252 } | |
253 | |
254 automation.setStatus("Creating database."); | |
255 var options = []; | |
256 for (var i=0; i < numIndices; ++i) { | |
257 var o = {}; | |
258 o.indexName = "index " + i; | |
259 o.indexKeyPath = "field" + i; // depends on getNFieldObjectValue | |
jsbell
2012/07/27 00:25:46
Maybe add function getNFieldName(n) { return "fiel
ericu
2012/07/31 01:00:53
Done.
| |
260 o.indexIsUnique = false; | |
261 o.indexIsMultiEntry = false; | |
262 options.push(o); | |
263 } | |
264 createDatabase(testName, objectStoreNames, onCreated, onError, options); | |
265 } | |
266 | |
138 var kUseIndex = true; | 267 var kUseIndex = true; |
139 var kDontUseIndex = false; | 268 var kDontUseIndex = false; |
269 var kReadKeysOnly = true; | |
270 var kReadDataToo = false; | |
271 var kWriteToo = true; | |
272 var kDontWrite = false; | |
273 | |
140 var tests = [ | 274 var tests = [ |
275 // Create a single small item in a single object store. | |
141 [testCreateKeysInStores, 1, 1, 1], | 276 [testCreateKeysInStores, 1, 1, 1], |
277 // Create many small items in a single object store. | |
142 [testCreateKeysInStores, 100, 1, 1], | 278 [testCreateKeysInStores, 100, 1, 1], |
279 // Create a single small item in many object stores. | |
143 [testCreateKeysInStores, 1, 100, 1], | 280 [testCreateKeysInStores, 1, 100, 1], |
281 // Create many large items in a single object store. | |
144 [testCreateKeysInStores, 100, 1, 10000], | 282 [testCreateKeysInStores, 100, 1, 10000], |
283 // Read a few random items in each of many transactions. | |
145 [testRandomReadsAndWrites, 1000, 5, 0, 50, kDontUseIndex], | 284 [testRandomReadsAndWrites, 1000, 5, 0, 50, kDontUseIndex], |
285 // Read many random items in each of a few transactions. | |
146 [testRandomReadsAndWrites, 1000, 50, 0, 5, kDontUseIndex], | 286 [testRandomReadsAndWrites, 1000, 50, 0, 5, kDontUseIndex], |
287 // Read many random items in each of a few transactions, in a large store. | |
147 [testRandomReadsAndWrites, 5000, 50, 0, 5, kDontUseIndex], | 288 [testRandomReadsAndWrites, 5000, 50, 0, 5, kDontUseIndex], |
289 // Read a few random items from an index, in each of many transactions. | |
148 [testRandomReadsAndWrites, 1000, 5, 0, 50, kUseIndex], | 290 [testRandomReadsAndWrites, 1000, 5, 0, 50, kUseIndex], |
291 // Read many random items from an index, in each of a few transactions. | |
149 [testRandomReadsAndWrites, 1000, 50, 0, 5, kUseIndex], | 292 [testRandomReadsAndWrites, 1000, 50, 0, 5, kUseIndex], |
293 // Read many random items from an index, in each of a few transactions, in a | |
294 // large store. | |
150 [testRandomReadsAndWrites, 5000, 50, 0, 5, kUseIndex], | 295 [testRandomReadsAndWrites, 5000, 50, 0, 5, kUseIndex], |
296 // Read and write a few random items in each of many transactions. | |
151 [testRandomReadsAndWrites, 1000, 5, 5, 50, kDontUseIndex], | 297 [testRandomReadsAndWrites, 1000, 5, 5, 50, kDontUseIndex], |
298 // Read and write a few random items, reading from an index, in each of many | |
299 // transactions. | |
152 [testRandomReadsAndWrites, 1000, 5, 5, 50, kUseIndex], | 300 [testRandomReadsAndWrites, 1000, 5, 5, 50, kUseIndex], |
301 // Read a long, contiguous sequence of an object store via a cursor. | |
302 [testCursorReadsAndRandomWrites, kReadDataToo, kDontUseIndex, kDontWrite], | |
303 // Read a sequence of an object store via a cursor, writing | |
304 // transformed values into another. | |
305 [testCursorReadsAndRandomWrites, kReadDataToo, kDontUseIndex, kWriteToo], | |
306 // Read a sequence of an index into an object store via a cursor. | |
307 [testCursorReadsAndRandomWrites, kReadDataToo, kUseIndex, kDontWrite], | |
308 // Read a sequence of an index into an object store via a key cursor. | |
309 [testCursorReadsAndRandomWrites, kReadKeysOnly, kUseIndex, kDontWrite], | |
310 // Make batches of random writes into a store, triggered by periodic setTimeout | |
311 // calls. | |
312 [testSporadicWrites, 5, 0], | |
313 // Make large batches of random writes into a store, triggered by periodic | |
314 // setTimeout calls. | |
315 [testSporadicWrites, 50, 0], | |
316 // Make batches of random writes into a store with many indices, triggered by | |
317 // periodic setTimeout calls. | |
318 [testSporadicWrites, 5, 10], | |
319 // Make large batches of random writes into a store with many indices, triggered | |
320 // by periodic setTimeout calls. | |
321 [testSporadicWrites, 50, 10], | |
322 // Create and delete an index on a store that already contains data [produces | |
323 // a timing result for each of creation and deletion]. | |
153 [testCreateAndDeleteIndex, 1000] | 324 [testCreateAndDeleteIndex, 1000] |
154 ]; | 325 ]; |
155 | 326 |
156 var currentTest = 0; | 327 var currentTest = 0; |
157 | 328 |
158 function runNextTest() { | 329 function runNextTest() { |
159 if (currentTest < tests.length) { | 330 if (currentTest < tests.length) { |
160 var test = tests[currentTest++].slice(); | 331 var test = tests[currentTest++].slice(); |
161 var f = test.shift(); | 332 var f = test.shift(); |
162 test.push(runNextTest); | 333 test.push(runNextTest); |
163 f.apply(null, test); | 334 f.apply(null, test); |
164 } else { | 335 } else { |
165 onAllTestsComplete(); | 336 onAllTestsComplete(); |
166 } | 337 } |
167 } | 338 } |
168 | 339 |
169 function onAllTestsComplete() { | 340 function onAllTestsComplete() { |
170 var overallDuration = Date.now() - overallTestStartTime; | 341 var overallDuration = Date.now() - overallTestStartTime; |
171 automation.addResult("OverallTestDuration", overallDuration); | 342 automation.addResult("OverallTestDuration", overallDuration); |
172 automation.setDone(); | 343 automation.setDone(); |
173 } | 344 } |
174 | 345 |
175 function test() { | 346 function test() { |
176 runNextTest(); | 347 runNextTest(); |
177 } | 348 } |
OLD | NEW |