diff options
Diffstat (limited to 'testing/raptor/browsertime/indexeddb_write.js')
-rw-r--r-- | testing/raptor/browsertime/indexeddb_write.js | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/testing/raptor/browsertime/indexeddb_write.js b/testing/raptor/browsertime/indexeddb_write.js new file mode 100644 index 0000000000..30c5c84f8e --- /dev/null +++ b/testing/raptor/browsertime/indexeddb_write.js @@ -0,0 +1,153 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* eslint-env node */ + +module.exports = async function (context, commands) { + context.log.info("Starting a indexedDB write"); + const post_startup_delay = context.options.browsertime.post_startup_delay; + console.log("context options", context.options); + + const test_url = context.options.browsertime.url; + const chunk_size = context.options.browsertime.chunk_size; + const iterations = context.options.browsertime.iterations; + const buffer_type = context.options.browsertime.buffer_type; + const atomic_value = context.options.browsertime.atomic; + if (atomic_value * atomic_value != atomic_value) { + throw Error("Value of atomic shall be 0 for falsehood, 1 for truth."); + } + const atomic = 0 != atomic_value; + + const accepted_buffers = ["Array", "ArrayBuffer", "Blob"]; + if (!accepted_buffers.includes(buffer_type)) { + throw Error("Buffer type " + buffer_type + " is unknown."); + } + + context.log.info("IndexedDB write URL = " + test_url); + context.log.info("IndexedDB write chunk size = " + chunk_size); + context.log.info("IndexedDB write iterations = " + iterations); + context.log.info( + "IndexedDB writes " + + (atomic ? "all in one big transaction" : "in separate transactions") + ); + context.log.info("IndexedDB write data format " + buffer_type); + + context.log.info( + "Waiting for %d ms (post_startup_delay)", + post_startup_delay + ); + + await commands.navigate(test_url); + + const seleniumDriver = context.selenium.driver; + + await commands.wait.byTime(post_startup_delay); + + await commands.measure.start(); + const time_duration = await seleniumDriver.executeAsyncScript(` + const notifyDone = arguments[arguments.length - 1]; + + const iterations = ${iterations}; + const sizeInBytes = ${chunk_size}; + const bufferType = "${buffer_type}"; + const atomic = ${atomic}; + + const makeData = (() => { + if (bufferType === "ArrayBuffer") { + return () => { + const valueBuffer = new ArrayBuffer(sizeInBytes); + + const charCodeView = new Uint16Array(valueBuffer); + const sizeInUint16 = sizeInBytes / 2; + for (let i=0; i < sizeInUint16; ++i) { + charCodeView[i] = "qwerty".charCodeAt(i % 6); + } + + return valueBuffer; + }; + } + + if (bufferType === "Array") { + return () => { + return Array.from({length: sizeInBytes}, (_, i) => "qwerty"[i % 6]); + }; + } + + if (bufferType !== "Blob") { + throw Error("Unknown buffer type " + bufferType); + } + + return () => { + return new Blob([Array.from({length: sizeInBytes}, (_, i) => "qwerty"[i % 6])]); + }; + })(); + + function addData(txSource, txProvider, i) { + try { + const keyName = "doc_" + i; + const valueData = makeData(); + const record = { key: keyName, property: valueData }; + + const rq = txProvider(txSource).add(record); + + return new Promise((res_ad, rej_ad) => { + rq.onsuccess = () => { res_ad(); }; + rq.onerror = e => { rej_ad(e); }; + }); + } catch (e) { + return new Promise((_, rej_ad) => rej_ad(e)); + } + } + + function waitForData(txSource) { + try { + if (!atomic) { + const txProvider = src => src.transaction("store", "readwrite").objectStore("store"); + return Promise.all( + Array.from({ length: iterations }, (_, i) => { + return addData(txSource, txProvider, i); + })); + } + + const currentTx = txSource.transaction("store", "readwrite").objectStore("store"); + return Promise.all( + Array.from({ length: iterations }, (_, i) => { + return addData(currentTx, src => src, i); + })); + } catch (e) { + return new Promise((_, rej_tx) => rej_tx(e)); + } + } + + function upgradePromise() { + try { + const open_db = indexedDB.open("rootsdb"); + return new Promise((res_upgrade, rej_upgrade) => { + open_db.onupgradeneeded = e => { + e.target.result.createObjectStore("store", { keyPath: "key" }); + }; + open_db.onsuccess = e => { res_upgrade(e.target.result); }; + open_db.onerror = e => { rej_upgrade(e); }; + }); + } catch (e) { + return new Promise((_, rej_upgrade) => rej_upgrade(e)); + } + } + + const startTime = performance.now(); + upgradePromise().then(waitForData).then(() => { + notifyDone(performance.now() - startTime); + }); + `); + await commands.measure.stop(); + + console.log("Time duration was ", time_duration); + + await commands.measure.addObject({ + custom_data: { time_duration }, + }); + + context.log.info("IndexedDB write ended."); + return true; +}; |