Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Unified Diff: third_party/WebKit/Source/devtools/scripts/npm_test.js

Issue 2413563002: DevTools: add "npm test" to run tests by fetching content shells (Closed)
Patch Set: nits Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/scripts/npm_test.js
diff --git a/third_party/WebKit/Source/devtools/scripts/npm_test.js b/third_party/WebKit/Source/devtools/scripts/npm_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..dc14020ce579554163b4242a725751546e6e976d
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/scripts/npm_test.js
@@ -0,0 +1,263 @@
+// Copyright 2016 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 childProcess = require("child_process");
+var fs = require("fs");
+var path = require("path");
+var shell = require("child_process").execSync;
+
+var utils = require("./utils");
+
+var Flags = {
+ BUILD_ONLY: "--build-only",
+ DEBUG_DEVTOOLS: "--debug-devtools",
+ TEST_ONLY: "--test-only",
+};
+
+var IS_DEBUG_ENABLED = utils.includes(process.argv, Flags.DEBUG_DEVTOOLS);
+var IS_BUILD_ONLY = utils.includes(process.argv, Flags.BUILD_ONLY);
+var IS_TEST_ONLY = utils.includes(process.argv, Flags.TEST_ONLY);
+
+var CONTENT_SHELL_ZIP = "content-shell.zip";
+var MAX_CONTENT_SHELLS = 10;
+var PLATFORM = getPlatform();
+var PYTHON = process.platform === "win32" ? "python.bat" : "python";
+
+var BLINK_TEST_PATH = path.resolve(__dirname, "..", "..", "..", "..", "..", "blink", "tools", "run_layout_tests.py");
+var CACHE_PATH = path.resolve(__dirname, "..", ".test_cache");
+var SOURCE_PATH = path.resolve(__dirname, "..", "front_end");
+
+function main(){
+ if (IS_TEST_ONLY) {
+ findPreviousUploadedPosition(findMostRecentChromiumCommit())
+ .then(commitPosition => runTests(path.resolve(CACHE_PATH, commitPosition, "out")));
+ return;
+ }
+ if (!utils.isDir(CACHE_PATH))
+ fs.mkdirSync(CACHE_PATH);
+ deleteOldContentShells();
+ findPreviousUploadedPosition(findMostRecentChromiumCommit())
+ .then(onUploadedCommitPosition)
+ .catch(onError);
+
+ function onError(error) {
+ console.log("Unable to run tests because of error:", error);
+ console.log(`Try removing the .test_cache folder [${CACHE_PATH}] and retrying`);
+ }
+}
+main();
+
+function onUploadedCommitPosition(commitPosition)
+{
+ var contentShellDirPath = path.resolve(CACHE_PATH, commitPosition, "out", "Release");
+ var hasCachedContentShell = utils.isFile(getContentShellBinaryPath(contentShellDirPath));
+ if (hasCachedContentShell) {
+ var contentShellPath = path.resolve(CACHE_PATH, commitPosition, "out");
+ console.log(`Using cached content shell at: ${contentShellPath}`);
+ return buildAndTest(contentShellPath);
+ }
+ return prepareContentShellDirectory(commitPosition)
+ .then(downloadContentShell)
+ .then(extractContentShell)
+ .then(buildAndTest);
+}
+
+function getPlatform()
+{
+ if (process.platform === "linux") {
+ if (process.arch === "x64")
+ return "Linux_x64";
+ throw new Error("Pre-compiled content shells are only available for x64 on Linux");
+ }
+ if (process.platform === "win32") {
+ if (process.arch === "x64")
+ return "Win_x64";
+ return "Win";
+ }
+ if (process.platform === "darwin") {
+ return "Mac";
+ }
+ throw new Error(`Unrecognized platform detected: ${process.platform}`);
+}
+
+function findMostRecentChromiumCommit()
+{
+ var commitMessage = shell(`git log --max-count=1 --grep="Cr-Commit-Position"`).toString().trim();
+ var commitPosition = commitMessage.match(/Cr-Commit-Position: refs\/heads\/master@\{#([0-9]+)\}/)[1];
+ return commitPosition;
+}
+
+function deleteOldContentShells()
+{
+ var files = fs.readdirSync(CACHE_PATH);
+ if (files.length < MAX_CONTENT_SHELLS)
+ return;
+ files.sort((a, b) => parseInt(b, 10) - parseInt(a, 10));
+ var remainingNumberOfContentShells = MAX_CONTENT_SHELLS / 2;
+ var oldContentShellDirs = files.slice(remainingNumberOfContentShells);
+ for (var i = 0; i < oldContentShellDirs.length; i++)
+ utils.removeRecursive(path.resolve(CACHE_PATH, oldContentShellDirs[i]));
+ console.log(`Removed old content shells: ${oldContentShellDirs}`)
+}
+
+function findPreviousUploadedPosition(commitPosition)
+{
+ var previousPosition = commitPosition - 100;
+ var positionsListURL = `http://commondatastorage.googleapis.com/chromium-browser-snapshots/?delimiter=/&prefix=${PLATFORM}/&marker=${PLATFORM}/${previousPosition}/`;
dgozman 2016/10/17 19:13:51 Does one need any permissions for this url?
chenwilliam 2016/10/18 18:13:18 Nope, I was able to download it at home w/ my pers
+ return utils.fetch(positionsListURL)
+ .then(onPositionsList)
+ .catch(onError);
+
+ function onPositionsList(buffer)
+ {
+ var positions = buffer.toString("binary")
+ .match(/([^<>]+)(?=<\/Prefix><\/CommonPrefixes>)/g)
+ .map(prefixedPosition => prefixedPosition.split("/")[1])
+ .map(positionString => parseInt(positionString, 10));
+ var positionSet = new Set(positions);
+ var previousUploadedPosition = commitPosition;
+ while (commitPosition - previousUploadedPosition < 100) {
+ if (positionSet.has(previousUploadedPosition))
+ return previousUploadedPosition.toString();
+ previousUploadedPosition--;
+ }
+ onError();
+ }
+
+ function onError(error)
+ {
+ if (error)
+ console.log(`Received error: ${error} trying to fetch positions list from url: ${positionsListURL}`);
+ throw new Error(`Unable to find a previous upload position for commit position: ${commitPosition}`);
+ }
+}
+
+function prepareContentShellDirectory(contentShellCommitPosition)
+{
+ var contentShellPath = path.join(CACHE_PATH, contentShellCommitPosition);
+ if (utils.isDir(contentShellPath))
+ utils.removeRecursive(contentShellPath);
+ fs.mkdirSync(contentShellPath);
+ return Promise.resolve(contentShellCommitPosition);
+}
+
+function downloadContentShell(commitPosition)
+{
+ var url = `http://commondatastorage.googleapis.com/chromium-browser-snapshots/${PLATFORM}/${commitPosition}/${CONTENT_SHELL_ZIP}`;
+ console.log("Downloading content shell from:", url);
+ console.log("NOTE: Download is ~35-65 MB depending on OS");
+ return utils.fetch(url)
+ .then(writeZip)
+ .catch(onError);
+
+ function writeZip(buffer)
+ {
+ console.log("Completed download of content shell");
+ var contentShellZipPath = path.join(CACHE_PATH, commitPosition, CONTENT_SHELL_ZIP);
+ fs.writeFileSync(contentShellZipPath, buffer);
+ return contentShellZipPath;
+ }
+
+ function onError(error)
+ {
+ console.log(`Received error: ${error} trying to download content shell from url: ${url}`);
+ throw new Error("Unable to download content shell");
+ }
+}
+
+function extractContentShell(contentShellZipPath)
+{
+ console.log(`Extracting content shell zip: ${contentShellZipPath}`);
+ var unzipScriptPath = path.resolve(__dirname, "unzip.py");
+ var src = contentShellZipPath;
+ var dest = path.resolve(path.dirname(src), "out");
+ shell(`${PYTHON} ${unzipScriptPath} ${src} ${dest}`);
+ fs.unlinkSync(src);
+ var originalDirPath = path.resolve(dest, "content-shell");
+ var newDirPath = path.resolve(dest, "Release");
+ fs.renameSync(originalDirPath, newDirPath);
+ fs.chmodSync(getContentShellBinaryPath(newDirPath), "755");
+ if (process.platform === "darwin") {
+ var helperPath = path.resolve(newDirPath, "Content Shell.app", "Contents", "Frameworks", "Content Shell Helper.app", "Contents", "MacOS", "Content Shell Helper");
+ fs.chmodSync(helperPath, "755");
+ }
+ return dest;
+}
+
+function getContentShellBinaryPath(dirPath)
+{
+ if (process.platform === "linux") {
+ return path.resolve(dirPath, "content_shell");
+ }
+ if (process.platform === "win32") {
+ return path.resolve(dirPath, "content_shell.exe");
+ }
+ if (process.platform === "darwin") {
+ return path.resolve(dirPath, "Content Shell.app", "Contents", "MacOS", "Content Shell");
+ }
+}
+
+function buildAndTest(buildDirectoryPath)
+{
+ var contentShellResourcesPath = path.resolve(buildDirectoryPath, "Release", "resources");
+ build(contentShellResourcesPath);
+ if (IS_BUILD_ONLY)
+ return;
+ runTests(buildDirectoryPath);
+}
+
+function build(contentShellResourcesPath)
+{
+ var devtoolsResourcesPath = path.resolve(contentShellResourcesPath, "inspector");
+ var copiedFrontendPath = path.resolve(devtoolsResourcesPath, "front_end");
+ var debugPath = path.resolve(devtoolsResourcesPath, "debug");
+ utils.removeRecursive(copiedFrontendPath);
+ utils.removeRecursive(debugPath);
+ utils.copyRecursive(SOURCE_PATH, devtoolsResourcesPath);
+ fs.renameSync(copiedFrontendPath, debugPath);
+ var inspectorBackendCommandsPath = path.resolve(devtoolsResourcesPath, "InspectorBackendCommands.js");
+ var supportedCSSPropertiesPath = path.resolve(devtoolsResourcesPath, "SupportedCSSProperties.js");
+ utils.copy(inspectorBackendCommandsPath, debugPath);
+ utils.copy(supportedCSSPropertiesPath, debugPath);
+}
+
+function runTests(buildDirectoryPath)
+{
+ var testArgs = [
+ "--additional-drt-flag=--debug-devtools",
+ "--no-pixel-tests",
+ "--build-directory",
+ buildDirectoryPath,
+ ].concat(getInspectorTests());
+ if (IS_DEBUG_ENABLED) {
+ testArgs.push("--additional-drt-flag=--remote-debugging-port=9222");
+ testArgs.push("--time-out-ms=6000000");
+ console.log("\n=============================================");
+ console.log("Go to: http://localhost:9222/");
+ console.log("Click on link and in console execute: test()");
+ console.log("=============================================\n");
+ }
+ var args = [BLINK_TEST_PATH].concat(testArgs).concat(getTestFlags());
+ console.log(`Running layout tests with args: ${args}`);
+ childProcess.spawn(PYTHON, args, {stdio: "inherit"});
+}
+
+function getTestFlags()
+{
+ var flagValues = Object.keys(Flags).map(key => Flags[key]);
+ return process.argv
+ .slice(2)
+ .filter(arg => !utils.includes(flagValues, arg) && !utils.includes(arg, "inspector"));
+}
+
+function getInspectorTests()
+{
+ var specificTests = process.argv.filter(arg => utils.includes(arg, "inspector"));
+ if (specificTests.length)
+ return specificTests;
+ return [
+ "inspector*",
+ "http/tests/inspector*",
+ ];
+}

Powered by Google App Engine
This is Rietveld 408576698