Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/**
 * Any copyright is dedicated to the Public Domain.
 */
/* exported testSteps, disableWorkerTest */
var disableWorkerTest = "Need a way to set temporary prefs from a worker";
async function testSteps() {
  // Setting dom.indexedDB.dataThreshold to 99999 ensures that the first random
  // view (size 100000) is stored as a separate file when
  // dom.indexedDB.preprocessing is true. The second random view (size 10000)
  // is always stored directly in the database. This setup creates a scenario
  // where requests in a transaction are processed in the wrong order if they
  // are not properly queued internally.
  const dataThreshold = 99999;
  const name = this.window
    ? window.location.pathname
    : "test_view_put_get_values.js";
  const objectStoreName = "Views";
  const viewDataArray = [
    { key: 1, view: getRandomView(100000) },
    { key: 2, view: getRandomView(10000) },
  ];
  const tests = [
    {
      external: false,
      preprocessing: false,
    },
    {
      external: true,
      preprocessing: false,
    },
    {
      external: true,
      preprocessing: true,
    },
  ];
  for (let test of tests) {
    if (test.external) {
      info("Setting data threshold pref");
      if (this.window) {
        await SpecialPowers.pushPrefEnv({
          set: [["dom.indexedDB.dataThreshold", dataThreshold]],
        });
      } else {
        setDataThreshold(dataThreshold);
      }
    }
    if (test.preprocessing) {
      info("Setting preprocessing pref");
      if (this.window) {
        await SpecialPowers.pushPrefEnv({
          set: [["dom.indexedDB.preprocessing", true]],
        });
      } else {
        enablePreprocessing();
      }
    }
    info("Opening database");
    const db = await (async function () {
      const request = indexedDB.open(name);
      {
        const event = await expectingUpgrade(request);
        const database = event.target.result;
        database.createObjectStore(objectStoreName);
      }
      const event = await expectingSuccess(request);
      const database = event.target.result;
      return database;
    })();
    {
      const objectStore = db
        .transaction([objectStoreName], "readwrite")
        .objectStore(objectStoreName);
      info("Storing views");
      for (const viewData of viewDataArray) {
        const request = objectStore.add(viewData.view, viewData.key);
        await requestSucceeded(request);
        is(request.result, viewData.key, "Got correct key");
      }
      info("Getting views");
      for (const viewData of viewDataArray) {
        const request = objectStore.get(viewData.key);
        await requestSucceeded(request);
        verifyView(request.result, viewData.view);
      }
    }
    info("Getting views in separate transactions");
    for (const viewData of viewDataArray) {
      const request = db
        .transaction([objectStoreName])
        .objectStore(objectStoreName)
        .get(viewData.key);
      await requestSucceeded(request);
      verifyView(request.result, viewData.view);
    }
    info("Getting file usage");
    {
      const fileUsage = await new Promise(function (resolve) {
        getCurrentUsage(function (request) {
          resolve(request.result.fileUsage);
        });
      });
      if (test.external) {
        ok(fileUsage > 0, "File usage is not zero");
      } else {
        ok(fileUsage == 0, "File usage is zero");
      }
    }
    info("Getting views in parallel");
    {
      const objectStore = db
        .transaction([objectStoreName])
        .objectStore(objectStoreName);
      const promises = [];
      const keys = [];
      for (const viewData of viewDataArray) {
        const request = objectStore.get(viewData.key);
        promises.push(
          requestSucceeded(request, function () {
            keys.push(viewData.key);
          })
        );
      }
      await Promise.all(promises);
      is(keys.length, viewDataArray.length, "Correct number of keys");
      for (let i = 0; i < keys.length; i++) {
        is(keys[i], viewDataArray[i].key, "Correct key");
      }
    }
    info("Deleting database");
    {
      db.close();
      const request = indexedDB.deleteDatabase(name);
      await expectingSuccess(request);
    }
    info("Resetting prefs");
    if (this.window) {
      await SpecialPowers.popPrefEnv();
    } else {
      if (test.external) {
        resetDataThreshold();
      }
      if (test.preprocessing) {
        resetPreprocessing();
      }
    }
  }
}