Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/testing/raptor/browsertime/utils/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  profiling.js   Sprache: JAVA

 
/* 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 */
/* eslint-disable mozilla/avoid-Date-timing */
/* eslint-disable no-unsanitized/method */

const fs = require("fs");
const os = require("os");
const path = require("path");
const { exec } = require("node:child_process");

async function getBrowsertimeResultsPath(context, commands, createDirectories) {
  // Import needs to be done here because importing at the top-level
  // requires a wrapped async function call, but that import can then
  // only be used within the wrapped async call. Outside of it, the imported
  // variable is undefined.
  let pathToFolder;
  if (os.type() == "Windows_NT") {
    pathToFolder = await import(
      `file://${process.env.BROWSERTIME_ROOT.replace(
        "\\",
        "/"
      )}/node_modules/browsertime/lib/support/pathToFolder.js`
    );
  } else {
    pathToFolder = await import(
      path.join(
        process.env.BROWSERTIME_ROOT,
        "node_modules",
        "browsertime",
        "lib",
        "support",
        "pathToFolder.js"
      )
    );
  }

  const browsertimeResultsPath = path.join(
    context.options.resultDir,
    await pathToFolder.pathToFolder(
      commands.measure.result[0].browserScripts.pageinfo.url,
      context.options
    )
  );

  if (createDirectories) {
    try {
      await fs.promises.mkdir(browsertimeResultsPath, { recursive: true });
    } catch (err) {
      context.log.info(
        `Failed to create browsertime results path directories: ${err}`
      );
    }
  }

  return browsertimeResultsPath;
}

async function moveToBrowsertimeResultsPath(
  destFilename,
  srcFilepath,
  context,
  commands
) {
  const browsertimeResultsPath = await getBrowsertimeResultsPath(
    context,
    commands,
    true
  );
  const destFilepath = path.join(browsertimeResultsPath, destFilename);

  try {
    await fs.promises.rename(srcFilepath, destFilepath);
  } catch (err) {
    context.log.info(
      `Failed to rename/copy file into browsertime results: ${err}`
    );
  }

  return destFilepath;
}

function logCommands(commands, logger, command, printFirstArg) {
  let object = commands;
  let path = command.split(".");
  while (path.length > 1) {
    object = object[path.shift()];
  }
  let methodName = path[0];
  let originalFun = object[methodName];
  object[methodName] = async function () {
    let logString = ": " + command;
    if (printFirstArg && arguments.length) {
      logString += ": " + arguments[0];
    }
    logger.info("BEGIN" + logString);
    let rv = await originalFun.apply(object, arguments);
    logger.info("END" + logString);
    return rv;
  };
}

async function logTask(context, logString, task) {
  context.log.info("BEGIN: " + logString);
  let rv = await task();
  context.log.info("END: " + logString);

  return rv;
}

let startedProfiling = false;
let childPromise, child, profilePath, profileFilename;
async function startWindowsPowerProfiling(iterationIndex) {
  let canPowerProfile =
    os.type() == "Windows_NT" &&
    /10.0.2[2-9]/.test(os.release()) &&
    process.env.XPCSHELL_PATH;

  if (canPowerProfile && !startedProfiling) {
    startedProfiling = true;

    profileFilename = `profile_power_${iterationIndex}.json`;
    profilePath = process.env.MOZ_UPLOAD_DIR + "\\" + profileFilename;
    childPromise = new Promise(resolve => {
      child = exec(
        process.env.XPCSHELL_PATH,
        {
          env: {
            MOZ_PROFILER_STARTUP: "1",
            MOZ_PROFILER_STARTUP_FEATURES:
              "power,nostacksampling,notimerresolutionchange",
            MOZ_PROFILER_SHUTDOWN: profilePath,
          },
        },
        (error, stdout, stderr) => {
          if (error) {
            console.log("DEBUG ERROR", error);
          }
          if (stderr) {
            console.log("DEBUG stderr", error);
          }
          resolve(stdout);
        }
      );
    });
  }
}

async function stopWindowsPowerProfiling() {
  if (startedProfiling) {
    startedProfiling = false;
    child.stdin.end("quit()");
    await childPromise;
  }
}

async function gatherWindowsPowerUsage(testTimes) {
  let powerDataEntries = [];

  if (profilePath) {
    let profile;

    try {
      profile = JSON.parse(await fs.readFileSync(profilePath, "utf8"));
    } catch (err) {
      throw Error(`Failed to read the profile file: ${err}`);
    }

    for (let [start, end] of testTimes) {
      start -= profile.meta.startTime;
      end -= profile.meta.startTime;
      let powerData = {
        cpu_cores: [],
        cpu_package: [],
        gpu: [],
      };

      for (let counter of profile.counters) {
        let field = "";
        if (counter.name == "Power: iGPU") {
          field = "gpu";
        } else if (counter.name == "Power: CPU package") {
          field = "cpu_package";
        } else if (counter.name == "Power: CPU cores") {
          field = "cpu_cores";
        } else {
          continue;
        }

        let accumulatedPower = 0;
        for (let i = 0; i < counter.samples.data.length; ++i) {
          let time = counter.samples.data[i][counter.samples.schema.time];
          if (time < start) {
            continue;
          }
          if (time > end) {
            break;
          }
          accumulatedPower +=
            counter.samples.data[i][counter.samples.schema.count];
        }
        powerData[field].push(accumulatedPower);
      }

      powerDataEntries.push(powerData);
    }

    return powerDataEntries;
  }
  return null;
}

function logTest(name, test) {
  return async function wrappedTest(context, commands) {
    let testTimes = [];

    let start;
    let originalStart = commands.measure.start;
    commands.measure.start = function () {
      start = Date.now();
      return originalStart.apply(commands.measure, arguments);
    };
    let originalStop = commands.measure.stop;
    commands.measure.stop = function () {
      testTimes.push([start, Date.now()]);
      return originalStop.apply(commands.measure, arguments);
    };

    for (let [commandName, printFirstArg] of [
      ["addText.bySelector"true],
      ["android.shell"true],
      ["click.byXpath"true],
      ["click.byXpathAndWait"true],
      ["js.run"false],
      ["js.runAndWait"false],
      ["js.runPrivileged"false],
      ["measure.add"true],
      ["measure.addObject"false],
      ["measure.start"true],
      ["measure.stop"false],
      ["mouse.doubleClick.bySelector"true],
      ["mouse.doubleClick.byXpath"true],
      ["mouse.singleClick.bySelector"true],
      ["navigate"true],
      ["profiler.start"false],
      ["profiler.stop"false],
      ["trace.start"false],
      ["trace.stop"false],
      ["wait.byTime"true],
    ]) {
      logCommands(commands, context.log, commandName, printFirstArg);
    }

    if (context.options.browsertime.support_class) {
      await startWindowsPowerProfiling(context.index);
    }

    let iterationName = "iteration";
    if (
      context.options.firefox.geckoProfiler ||
      context.options.browsertime.expose_profiler === "true"
    ) {
      iterationName = "profiling iteration";
    }
    let logString = `: ${iterationName} ${context.index}: ${name}`;
    context.log.info("BEGIN" + logString);
    let rv = await test(context, commands);
    context.log.info("END" + logString);

    if (context.options.browsertime.support_class) {
      await stopWindowsPowerProfiling();
      let powerData = await gatherWindowsPowerUsage(testTimes);

      if (powerData?.length) {
        // Move the profile to the appropriate location in the browsertime results folder
        await moveToBrowsertimeResultsPath(
          profileFilename,
          profilePath,
          context,
          commands
        );

        powerData.forEach((powerUsage, ind) => {
          if (!commands.measure.result[ind].extras.powerUsage) {
            commands.measure.result[ind].extras.powerUsagePageload = [];
          }
          commands.measure.result[ind].extras.powerUsagePageload.push({
            powerUsagePageload: powerUsage,
          });
        });
      }
    }

    return rv;
  };
}

module.exports = {
  logTest,
  logTask,
  gatherWindowsPowerUsage,
  getBrowsertimeResultsPath,
  moveToBrowsertimeResultsPath,
  startWindowsPowerProfiling,
  stopWindowsPowerProfiling,
};

Messung V0.5
C=92 H=99 G=95

¤ Dauer der Verarbeitung: 0.13 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.