diff options
-rw-r--r-- | chrome/test/page_cycler/page_cycler_test.cc | 76 | ||||
-rw-r--r-- | tools/page_cycler/indexed_db/basic_insert/index.html | 73 | ||||
-rw-r--r-- | tools/page_cycler/indexed_db/basic_insert/start.html | 9 | ||||
-rw-r--r-- | tools/page_cycler/indexed_db/common.js | 26 | ||||
-rw-r--r-- | tools/page_cycler/indexed_db/head.js | 120 | ||||
-rw-r--r-- | tools/page_cycler/indexed_db/start.js | 58 |
6 files changed, 355 insertions, 7 deletions
diff --git a/chrome/test/page_cycler/page_cycler_test.cc b/chrome/test/page_cycler/page_cycler_test.cc index 7346489..d6952b4 100644 --- a/chrome/test/page_cycler/page_cycler_test.cc +++ b/chrome/test/page_cycler/page_cycler_test.cc @@ -29,15 +29,16 @@ #endif #ifndef NDEBUG -#define TEST_ITERATIONS 2 -#define DATABASE_TEST_ITERATIONS 2 +static const int kTestIterations = 2; +static const int kDatabaseTestIterations = 2; #else -#define TEST_ITERATIONS 10 +static const int kTestIterations = 10; // For some unknown reason, the DB perf tests are much much slower on the // Vista perf bot, so we have to cut down the number of iterations to 5 // to make sure each test finishes in less than 10 minutes. -#define DATABASE_TEST_ITERATIONS 5 +static const int kDatabaseTestIterations = 5; #endif +static const int kIDBTestIterations = 5; // URL at which data files may be found for HTTP tests. The document root of // this URL's server should point to data/page_cycler/. @@ -164,7 +165,7 @@ class PageCyclerTest : public UIPerfTest { show_window_ = true; const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); - num_test_iterations_ = TEST_ITERATIONS; + num_test_iterations_ = kTestIterations; if (parsed_command_line.HasSwitch(switches::kPageCyclerIterations)) { std::string str = parsed_command_line.GetSwitchValueASCII( @@ -357,6 +358,16 @@ static FilePath GetDatabaseDataPath(const char* name) { return test_path; } +static FilePath GetIndexedDatabaseDataPath(const char* name) { + FilePath test_path; + PathService::Get(base::DIR_SOURCE_ROOT, &test_path); + test_path = test_path.Append(FILE_PATH_LITERAL("tools")); + test_path = test_path.Append(FILE_PATH_LITERAL("page_cycler")); + test_path = test_path.Append(FILE_PATH_LITERAL("indexed_db")); + test_path = test_path.AppendASCII(name); + return test_path; +} + static bool HasDatabaseErrors(const std::string timings) { size_t pos = 0; size_t new_pos = 0; @@ -410,7 +421,7 @@ class PageCyclerDatabaseTest : public PageCyclerTest { } virtual int GetTestIterations() { - return DATABASE_TEST_ITERATIONS; + return kDatabaseTestIterations; } }; @@ -429,7 +440,45 @@ class PageCyclerDatabaseReferenceTest : public PageCyclerReferenceTest { } virtual int GetTestIterations() { - return DATABASE_TEST_ITERATIONS; + return kDatabaseTestIterations; + } +}; + +class PageCyclerIndexedDatabaseTest : public PageCyclerTest { + public: + PageCyclerIndexedDatabaseTest() { + print_times_only_ = true; + } + + virtual FilePath GetDataPath(const char* name) { + return GetIndexedDatabaseDataPath(name); + } + + virtual bool HasErrors(const std::string timings) { + return HasDatabaseErrors(timings); + } + + virtual int GetTestIterations() { + return kIDBTestIterations; + } +}; + +class PageCyclerIndexedDatabaseReferenceTest : public PageCyclerReferenceTest { + public: + PageCyclerIndexedDatabaseReferenceTest() { + print_times_only_ = true; + } + + virtual FilePath GetDataPath(const char* name) { + return GetIndexedDatabaseDataPath(name); + } + + virtual bool HasErrors(const std::string timings) { + return HasDatabaseErrors(timings); + } + + virtual int GetTestIterations() { + return kIDBTestIterations; } }; @@ -452,6 +501,16 @@ TEST_F(PageCyclerDatabaseReferenceTest, Database##name##File) { \ RunTest(test, test, false); \ } +// This macro simplifies setting up regular and reference build tests +// for HTML5 Indexed DB tests. +#define PAGE_CYCLER_IDB_TESTS(test, name) \ +TEST_F(PageCyclerIndexedDatabaseTest, IndexedDB##name##File) { \ + RunTest(test, test, false); \ +} \ +TEST_F(PageCyclerIndexedDatabaseReferenceTest, IndexedDB##name##File) { \ + RunTest(test, test, false); \ +} + // These are shorthand for File vs. Http tests. #define PAGE_CYCLER_FILE_TESTS(test, name) \ PAGE_CYCLER_TESTS(test, name, false) @@ -510,4 +569,7 @@ PAGE_CYCLER_DATABASE_TESTS("pseudo-random-transactions", PseudoRandomTransactions); #endif +// Indexed DB tests. +PAGE_CYCLER_IDB_TESTS("basic_insert", BasicInsert); + } // namespace diff --git a/tools/page_cycler/indexed_db/basic_insert/index.html b/tools/page_cycler/indexed_db/basic_insert/index.html new file mode 100644 index 0000000..5110556 --- /dev/null +++ b/tools/page_cycler/indexed_db/basic_insert/index.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<html> +<title>Basic Insert</title> +<script src="../head.js"></script> +<script src="../common.js"></script> +<script> + var RECORDS = 3000; + + var failed = false; + function error(event) { + log('Error ' + event.code + ': ' + event.message); + + if (!failed) + testComplete(TEST_FAILED); + failed = true; + } + + function start() { + if (!setup()) + testComplete(SETUP_FAILED); + + var request = indexedDB.open('idb_basic_insert', ''); + request.onsuccess = onOpen; + request.onerror = error; + } + + function onOpen() { + window.db = event.result; + + var request = db.setVersion('1'); + request.onerror = error; + request.onsuccess = onSetVersion; + } + + function onSetVersion() { + var transaction = event.result; + transaction.onerror = error; + transaction.oncomplete = storeCreated; + + while (db.objectStores.length) + db.removeObjectStore(db.objectStores[0]); + + db.createObjectStore('store'); + } + + function storeCreated() { + var transaction = db.transaction([], IDBTransaction.READ_WRITE, 0); + transaction.oncomplete = insertsDone; + transaction.onabort = error; + + var objectStore = transaction.objectStore('store'); + log('Inserting ' + RECORDS + ' records with explicit key.'); + startTime = new Date(); + for (var i = 0; i < RECORDS; i++) { + var x = Math.floor(Math.random() * 1000000); + objectStore.put(x, x).onerror = error; + } + } + + function insertsDone() { + var now = Date.now(); + var diff = now - startTime; + log('Inserted ' + RECORDS + ' records in ' + diff + ' ms (' + diff / + RECORDS + ' ms per record)'); + + if (!failed) + testComplete(now - startTime); + } +</script> + +<body onLoad="start()"> +</body> +</html> diff --git a/tools/page_cycler/indexed_db/basic_insert/start.html b/tools/page_cycler/indexed_db/basic_insert/start.html new file mode 100644 index 0000000..ecdc393 --- /dev/null +++ b/tools/page_cycler/indexed_db/basic_insert/start.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<body> +<h3>Note: You must have started chrome with <tt>--enable-file-cookies</tt> for + this test to work manually.</h3> +<script>document.cookie = "__pc_pages=basic_insert; path=/";</script> +<script src="../start.js"></script> +</body> +</html> diff --git a/tools/page_cycler/indexed_db/common.js b/tools/page_cycler/indexed_db/common.js new file mode 100644 index 0000000..d1b4f72 --- /dev/null +++ b/tools/page_cycler/indexed_db/common.js @@ -0,0 +1,26 @@ +// Copyright (c) 2010 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. + +var CANNOT_OPEN_DB = -1; +var SETUP_FAILED = -2; +var TEST_FAILED = -3; + +function setup() { + if ('webkitIndexedDB' in window) { + indexedDB = webkitIndexedDB; + IDBCursor = webkitIDBCursor; + IDBKeyRange = webkitIDBKeyRange; + IDBTransaction = webkitIDBTransaction; + return true; + } + + if ('indexedDB' in window) + return true; + + return false; +} + +function log(msg) { + document.write(msg + '<br>'); +} diff --git a/tools/page_cycler/indexed_db/head.js b/tools/page_cycler/indexed_db/head.js new file mode 100644 index 0000000..a1b3149 --- /dev/null +++ b/tools/page_cycler/indexed_db/head.js @@ -0,0 +1,120 @@ +// Copyright (c) 2010 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. + +var totalTime; +var fudgeTime; +var elapsedTime; +var endTime; +var iterations; +var cycle; +var results = false; +var TIMEOUT = 15; + +/** + * Returns the value of the given property stored in the cookie. + * @param {string} name The property name. + * @return {string} The value of the given property, or empty string + * if the property was not found. + */ +function getPropertyValue(name) { + var cookies = document.cookie.split('; '); + for (var i = 0; i < cookies.length; ++i) { + var t = cookies[i].split('='); + if ((t[0] == name) && t[1]) + return t[1]; + } + return ''; +} + +/** + * Returns the value of the '__pc_timings' property. + * @return {string} The list of all timings we got so far. + */ +function getTimings() { + return getPropertyValue('__pc_timings'); +} + +/** + * Sets the value of the '__pc_timings' property in the cookie. + * @param {string} timings A comma-separated list of timings. + */ +function setTimings(timings) { + document.cookie = '__pc_timings=' + timings + '; path=/'; +} + +/** + * Starts the next test cycle or redirects the browser to the results page. + */ +function nextCycleOrResults() { + // Call GC twice to cleanup JS heap before starting a new test. + if (window.gc) { + window.gc(); + window.gc(); + } + + var tLag = Date.now() - endTime - TIMEOUT; + if (tLag > 0) + fudgeTime += tLag; + + var doc; + if (cycle == iterations) { + document.cookie = '__pc_done=1; path=/'; + doc = '../../common/report.html'; + } else { + doc = 'index.html'; + } + + var timings = elapsedTime; + var oldTimings = getTimings(); + if (oldTimings != '') + timings = oldTimings + ',' + timings; + setTimings(timings); + + var url = doc + '?n=' + iterations + '&i=' + cycle + + '&td=' + totalTime + '&tf=' + fudgeTime; + document.location.href = url; +} + +/** + * Computes various running times and updates the stats reported at the end. + * @param {!number} cycleTime The running time of the test cycle. + */ +function testComplete(cycleTime) { + if (results) + return; + + var oldTotalTime = 0; + var cycleEndTime = Date.now(); + var cycleFudgeTime = 0; + + var s = document.location.search; + if (s) { + var params = s.substring(1).split('&'); + for (var i = 0; i < params.length; i++) { + var f = params[i].split('='); + switch (f[0]) { + case 'skip': + return; // No calculation, just viewing + case 'n': + iterations = f[1]; + break; + case 'i': + cycle = f[1] - 0 + 1; + break; + case 'td': + oldTotalTime = f[1] - 0; + break; + case 'tf': + cycleFudgeTime = f[1] - 0; + break; + } + } + } + elapsedTime = cycleTime; + totalTime = oldTotalTime + elapsedTime; + endTime = cycleEndTime; + fudgeTime = cycleFudgeTime; + + setTimeout(nextCycleOrResults, TIMEOUT); +} diff --git a/tools/page_cycler/indexed_db/start.js b/tools/page_cycler/indexed_db/start.js new file mode 100644 index 0000000..1163ea0 --- /dev/null +++ b/tools/page_cycler/indexed_db/start.js @@ -0,0 +1,58 @@ +// Copyright (c) 2010 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. + +document.title = 'page cycler'; + +document.cookie = '__pc_done=0; path=/'; +document.cookie = '__pc_timings=; path=/'; + +var options = location.search.substring(1).split('&'); + +function getOption(name) { + var r = new RegExp('^' + name + '='); + for (var i = 0; i < options.length; i++) { + if (options[i].match(r)) { + return options[i].substring(name.length + 1); + } + } + return null; +} + +function start() { + var iterations = document.getElementById('iterations').value; + window.resizeTo(800, 800); + var url = 'index.html?n=' + iterations + '&i=0&td=0'; + window.location = url; +} + +function renderForm() { + var form = document.createElement('form'); + form.onsubmit = function(e) { + start(); + e.preventDefault(); + }; + + var label = document.createTextNode('Iterations: '); + form.appendChild(label); + + var input = document.createElement('input'); + input.id = 'iterations'; + input.type = 'number'; + var iterations = getOption('iterations'); + input.value = iterations ? iterations : '5'; + form.appendChild(input); + + input = document.createElement('input'); + input.type = 'submit'; + input.value = 'Start'; + form.appendChild(input); + + document.body.appendChild(form); +} + +renderForm(); + +// should we start automatically? +if (location.search.match('auto=1')) + start(); |