Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/storage/test/unit/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 11 kB image not shown  

Quelle  test_vacuum.js   Sprache: JAVA

 
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 */


// This file tests the Vacuum Manager and asyncVacuum().

const { VacuumParticipant } = ChromeUtils.importESModule(
  "resource://testing-common/VacuumParticipant.sys.mjs"
);

/**
 * Sends a fake idle-daily notification to the VACUUM Manager.
 */

function synthesize_idle_daily() {
  Cc["@mozilla.org/storage/vacuum;1"]
    .getService(Ci.nsIObserver)
    .observe(null"idle-daily"null);
}

/**
 * Returns a new nsIFile reference for a profile database.
 * @param filename for the database, excluded the .sqlite extension.
 */

function new_db_file(name = "testVacuum") {
  let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
  file.append(name + ".sqlite");
  return file;
}

function reset_vacuum_date(name = "testVacuum") {
  let date = parseInt(Date.now() / 1000 - 31 * 86400);
  // Set last VACUUM to a date in the past.
  Services.prefs.setIntPref(`storage.vacuum.last.${name}.sqlite`, date);
  return date;
}

function get_vacuum_date(name = "testVacuum") {
  return Services.prefs.getIntPref(`storage.vacuum.last.${name}.sqlite`, 0);
}

add_setup(async function () {
  // turn on Cu.isInAutomation
  Services.prefs.setBoolPref(
    "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer",
    true
  );
});

add_task(async function test_common_vacuum() {
  let last_vacuum_date = reset_vacuum_date();
  info("Test that a VACUUM correctly happens and all notifications are fired.");
  let promiseTestVacuumBegin = TestUtils.topicObserved("test-begin-vacuum");
  let promiseTestVacuumEnd = TestUtils.topicObserved("test-end-vacuum-success");
  let promiseVacuumBegin = TestUtils.topicObserved("vacuum-begin");
  let promiseVacuumEnd = TestUtils.topicObserved("vacuum-end");

  let participant = new VacuumParticipant(
    Services.storage.openDatabase(new_db_file())
  );
  await participant.promiseRegistered();
  synthesize_idle_daily();
  // Wait for notifications.
  await Promise.all([
    promiseTestVacuumBegin,
    promiseTestVacuumEnd,
    promiseVacuumBegin,
    promiseVacuumEnd,
  ]);
  Assert.greater(get_vacuum_date(), last_vacuum_date);
  await participant.dispose();
});

add_task(async function test_skipped_if_recent_vacuum() {
  info("Test that a VACUUM is skipped if it was run recently.");
  Services.prefs.setIntPref(
    "storage.vacuum.last.testVacuum.sqlite",
    parseInt(Date.now() / 1000)
  );
  // Wait for VACUUM skipped notification.
  let promiseSkipped = TestUtils.topicObserved("vacuum-skip");

  let participant = new VacuumParticipant(
    Services.storage.openDatabase(new_db_file())
  );
  await participant.promiseRegistered();
  synthesize_idle_daily();

  // Check that VACUUM has been skipped.
  await promiseSkipped;

  await participant.dispose();
});

add_task(async function test_page_size_change() {
  info("Test that a VACUUM changes page_size");
  reset_vacuum_date();

  let conn = Services.storage.openDatabase(new_db_file());
  info("Check initial page size.");
  let stmt = conn.createStatement("PRAGMA page_size");
  Assert.ok(stmt.executeStep());
  Assert.equal(stmt.row.page_size, conn.defaultPageSize);
  stmt.finalize();
  await populateFreeList(conn);

  let participant = new VacuumParticipant(conn, { expectedPageSize: 1024 });
  await participant.promiseRegistered();
  let promiseVacuumEnd = TestUtils.topicObserved("test-end-vacuum-success");
  synthesize_idle_daily();
  await promiseVacuumEnd;

  info("Check that page size was updated.");
  stmt = conn.createStatement("PRAGMA page_size");
  Assert.ok(stmt.executeStep());
  Assert.equal(stmt.row.page_size, 1024);
  stmt.finalize();

  await participant.dispose();
});

add_task(async function test_skipped_optout_vacuum() {
  info("Test that a VACUUM is skipped if the participant wants to opt-out.");
  reset_vacuum_date();

  let participant = new VacuumParticipant(
    Services.storage.openDatabase(new_db_file()),
    { grant: false }
  );
  await participant.promiseRegistered();
  // Wait for VACUUM skipped notification.
  let promiseSkipped = TestUtils.topicObserved("vacuum-skip");

  synthesize_idle_daily();

  // Check that VACUUM has been skipped.
  await promiseSkipped;

  await participant.dispose();
});

add_task(async function test_memory_database_crash() {
  info("Test that we don't crash trying to vacuum a memory database");
  reset_vacuum_date();

  let participant = new VacuumParticipant(
    Services.storage.openSpecialDatabase("memory")
  );
  await participant.promiseRegistered();
  // Wait for VACUUM skipped notification.
  let promiseSkipped = TestUtils.topicObserved("vacuum-skip");

  synthesize_idle_daily();

  // Check that VACUUM has been skipped.
  await promiseSkipped;

  await participant.dispose();
});

add_task(async function test_async_connection() {
  info("Test we can vacuum an async connection");
  reset_vacuum_date();

  let conn = await openAsyncDatabase(new_db_file());
  await populateFreeList(conn);
  let participant = new VacuumParticipant(conn);
  await participant.promiseRegistered();

  let promiseVacuumEnd = TestUtils.topicObserved("test-end-vacuum-success");
  synthesize_idle_daily();
  await promiseVacuumEnd;

  await participant.dispose();
});

add_task(async function test_change_to_incremental_vacuum() {
  info("Test we can change to incremental vacuum");
  reset_vacuum_date();

  let conn = Services.storage.openDatabase(new_db_file());
  info("Check initial vacuum.");
  let stmt = conn.createStatement("PRAGMA auto_vacuum");
  Assert.ok(stmt.executeStep());
  Assert.equal(stmt.row.auto_vacuum, 0);
  stmt.finalize();
  await populateFreeList(conn);

  let participant = new VacuumParticipant(conn, { useIncrementalVacuum: true });
  await participant.promiseRegistered();
  let promiseVacuumEnd = TestUtils.topicObserved("test-end-vacuum-success");
  synthesize_idle_daily();
  await promiseVacuumEnd;

  info("Check that auto_vacuum was updated.");
  stmt = conn.createStatement("PRAGMA auto_vacuum");
  Assert.ok(stmt.executeStep());
  Assert.equal(stmt.row.auto_vacuum, 2);
  stmt.finalize();

  await participant.dispose();
});

add_task(async function test_change_from_incremental_vacuum() {
  info("Test we can change from incremental vacuum");
  reset_vacuum_date();

  let conn = Services.storage.openDatabase(new_db_file());
  conn.executeSimpleSQL("PRAGMA auto_vacuum = 2");
  info("Check initial vacuum.");
  let stmt = conn.createStatement("PRAGMA auto_vacuum");
  Assert.ok(stmt.executeStep());
  Assert.equal(stmt.row.auto_vacuum, 2);
  stmt.finalize();
  await populateFreeList(conn);

  let participant = new VacuumParticipant(conn, {
    useIncrementalVacuum: false,
  });
  await participant.promiseRegistered();
  let promiseVacuumEnd = TestUtils.topicObserved("test-end-vacuum-success");
  synthesize_idle_daily();
  await promiseVacuumEnd;

  info("Check that auto_vacuum was updated.");
  stmt = conn.createStatement("PRAGMA auto_vacuum");
  Assert.ok(stmt.executeStep());
  Assert.equal(stmt.row.auto_vacuum, 0);
  stmt.finalize();

  await participant.dispose();
});

add_task(async function test_attached_vacuum() {
  info("Test attached database is not a problem");
  reset_vacuum_date();

  let conn = Services.storage.openDatabase(new_db_file());
  let conn2 = Services.storage.openDatabase(new_db_file("attached"));

  info("Attach " + conn2.databaseFile.path);
  conn.executeSimpleSQL(
    `ATTACH DATABASE '${conn2.databaseFile.path}' AS attached`
  );
  await asyncClose(conn2);
  let stmt = conn.createStatement("PRAGMA database_list");
  let schemas = [];
  while (stmt.executeStep()) {
    schemas.push(stmt.row.name);
  }
  Assert.deepEqual(schemas, ["main""attached"]);
  stmt.finalize();

  await populateFreeList(conn);
  await populateFreeList(conn, "attached");

  let participant = new VacuumParticipant(conn);
  await participant.promiseRegistered();
  let promiseVacuumEnd = TestUtils.topicObserved("test-end-vacuum-success");
  synthesize_idle_daily();
  await promiseVacuumEnd;

  await participant.dispose();
});

add_task(async function test_vacuum_fail() {
  info("Test a failed vacuum");
  reset_vacuum_date();

  let conn = Services.storage.openDatabase(new_db_file());
  // Cannot vacuum in a transaction.
  conn.beginTransaction();
  await populateFreeList(conn);

  let participant = new VacuumParticipant(conn);
  await participant.promiseRegistered();
  let promiseVacuumEnd = TestUtils.topicObserved("test-end-vacuum-failure");
  synthesize_idle_daily();
  await promiseVacuumEnd;

  conn.commitTransaction();
  await participant.dispose();
});

add_task(async function test_async_vacuum() {
  // Since previous tests already go through most cases, this only checks
  // the basics of directly calling asyncVacuum().
  info("Test synchronous connection");
  let conn = Services.storage.openDatabase(new_db_file());
  await populateFreeList(conn);
  let rv = await new Promise(resolve => {
    conn.asyncVacuum(status => {
      resolve(status);
    });
  });
  Assert.ok(Components.isSuccessCode(rv));
  await asyncClose(conn);

  info("Test asynchronous connection");
  conn = await openAsyncDatabase(new_db_file());
  await populateFreeList(conn);
  rv = await new Promise(resolve => {
    conn.asyncVacuum(status => {
      resolve(status);
    });
  });
  Assert.ok(Components.isSuccessCode(rv));
  await asyncClose(conn);
});

// Chunked growth is disabled on Android, so this test is pointless there.
add_task(
  { skip_if: () => AppConstants.platform == "android" },
  async function test_vacuum_growth() {
    // Tests vacuum doesn't nullify chunked growth.
    let conn = Services.storage.openDatabase(new_db_file("incremental"));
    conn.executeSimpleSQL("PRAGMA auto_vacuum = INCREMENTAL");
    conn.setGrowthIncrement(2 * conn.defaultPageSize, "");
    await populateFreeList(conn);
    let stmt = conn.createStatement("PRAGMA freelist_count");
    let count = 0;
    Assert.ok(stmt.executeStep());
    count = stmt.row.freelist_count;
    stmt.reset();
    Assert.greater(count, 2, "There's more than 2 page in freelist");

    let rv = await new Promise(resolve => {
      conn.asyncVacuum(status => {
        resolve(status);
      }, true);
    });
    Assert.ok(Components.isSuccessCode(rv));

    Assert.ok(stmt.executeStep());
    Assert.equal(
      stmt.row.freelist_count,
      2,
      "chunked growth space was preserved"
    );
    stmt.reset();

    // A full vacuuum should not be executed if there's less free pages than
    // chunked growth.
    rv = await new Promise(resolve => {
      conn.asyncVacuum(status => {
        resolve(status);
      });
    });
    Assert.ok(Components.isSuccessCode(rv));

    Assert.ok(stmt.executeStep());
    Assert.equal(
      stmt.row.freelist_count,
      2,
      "chunked growth space was preserved"
    );
    stmt.finalize();

    await asyncClose(conn);
  }
);

async function populateFreeList(conn, schema = "main") {
  await executeSimpleSQLAsync(conn, `CREATE TABLE ${schema}.test (id TEXT)`);
  await executeSimpleSQLAsync(
    conn,
    `INSERT INTO ${schema}.test
     VALUES ${Array.from({ length: 3000 }, () => Math.random()).map(
       v => "('" + v + "')"
     )}`
  );
  await executeSimpleSQLAsync(conn, `DROP TABLE ${schema}.test`);
}

Messung V0.5
C=88 H=96 G=91

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.