Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 var childProcess = require("child_process"); | |
| 6 var fs = require("fs"); | |
| 7 var path = require("path"); | |
| 8 var shell = require("child_process").execSync; | |
| 9 | |
| 10 var utils = require("./utils"); | |
| 11 | |
| 12 var CONTENT_SHELL_ZIP = "content-shell.zip"; | |
| 13 var DEBUG_DEVTOOLS_FLAG = "--debug-devtools"; | |
| 14 var IS_DEBUG_ENABLED = utils.includes(process.argv, DEBUG_DEVTOOLS_FLAG); | |
| 15 var MAX_CONTENT_SHELLS = 10; | |
| 16 var PLATFORM = getPlatform(); | |
| 17 var PYTHON = process.platform === "win32" ? "python.bat" : "python"; | |
| 18 | |
| 19 var BLINK_TEST_PATH = path.resolve(__dirname, "..", "..", "..", "..", "..", "bli nk", "tools", "run_layout_tests.py"); | |
| 20 var CACHE_PATH = path.resolve(__dirname, "..", ".test_cache"); | |
| 21 var JS_BUILD_PATH = path.resolve(__dirname, "js_build"); | |
| 22 var SOURCE_PATH = path.resolve(__dirname, "..", "front_end"); | |
| 23 var RELEASE_PATH = path.resolve(__dirname, "..", "release"); | |
| 24 | |
| 25 var chromiumCommitPosition = findMostRecentChromiumCommit(); | |
| 26 if (!utils.isDir(CACHE_PATH)) | |
| 27 fs.mkdirSync(CACHE_PATH); | |
| 28 deleteOldContentShells(); | |
| 29 findPreviousUploadedPosition(chromiumCommitPosition) | |
| 30 .then(onUploadedCommitPosition) | |
| 31 .catch(error => console.log("Unable to run tests because of error:", error)) ; | |
| 32 | |
| 33 function onUploadedCommitPosition(commitPosition) | |
| 34 { | |
| 35 var contentShellDirPath = path.resolve(CACHE_PATH, commitPosition, "out", "R elease"); | |
| 36 var hasCachedContentShell = utils.isFile(getContentShellBinaryPath(contentSh ellDirPath)); | |
| 37 if (hasCachedContentShell) { | |
| 38 var contentShellPath = path.resolve(CACHE_PATH, commitPosition, "out"); | |
| 39 console.log(`Using cached content shell at: ${contentShellPath}`); | |
| 40 return buildAndTest(commitPosition, contentShellPath); | |
| 41 } | |
| 42 return prepareContentShellDirectory(commitPosition) | |
| 43 .then(downloadContentShell) | |
| 44 .then(extractContentShell) | |
| 45 .then(buildAndTest.bind(null, commitPosition)); | |
| 46 } | |
| 47 | |
| 48 function getPlatform() | |
| 49 { | |
| 50 if (process.platform === "linux") { | |
| 51 if (process.arch === "x64") | |
| 52 return "Linux_x64"; | |
| 53 throw new Error("Pre-compiled content shells are only available for x64 on Linux"); | |
| 54 } | |
| 55 if (process.platform === "win32") { | |
| 56 if (process.arch === "x64") | |
| 57 return "Win_x64"; | |
| 58 return "Win"; | |
| 59 } | |
| 60 if (process.platform === "darwin") { | |
| 61 return "Mac"; | |
| 62 } | |
| 63 throw new Error(`Unrecognized platform detected: ${process.platform}`); | |
| 64 } | |
| 65 | |
| 66 function findMostRecentChromiumCommit() | |
| 67 { | |
| 68 var commitMessage = shell(`git log --max-count=1 --grep="Cr-Commit-Position" `).toString().trim(); | |
| 69 var commitPosition = commitMessage.match(/Cr-Commit-Position: refs\/heads\/m aster@\{#([0-9]+)\}/)[1]; | |
| 70 return commitPosition; | |
| 71 } | |
| 72 | |
| 73 function deleteOldContentShells() | |
| 74 { | |
| 75 var files = fs.readdirSync(CACHE_PATH); | |
| 76 if (files.length < MAX_CONTENT_SHELLS) | |
| 77 return; | |
| 78 files.sort((a, b) => parseInt(b, 10) - parseInt(a, 10)); | |
| 79 var remainingNumberOfContentShells = MAX_CONTENT_SHELLS / 2; | |
| 80 var oldContentShellDirs = files.slice(remainingNumberOfContentShells); | |
| 81 for (var i = 0; i < oldContentShellDirs.length; i++) | |
| 82 utils.removeRecursive(path.resolve(CACHE_PATH, oldContentShellDirs[i])); | |
| 83 console.log(`Removed old content shells: ${oldContentShellDirs}`) | |
| 84 } | |
| 85 | |
| 86 function findPreviousUploadedPosition(commitPosition) | |
| 87 { | |
| 88 var previousPosition = commitPosition - 100; | |
| 89 var positionsListURL = `http://commondatastorage.googleapis.com/chromium-bro wser-snapshots/?delimiter=/&prefix=${PLATFORM}/&marker=${PLATFORM}/${previousPos ition}/`; | |
| 90 return utils.fetch(positionsListURL) | |
| 91 .then(onPositionsList) | |
| 92 .catch(onError); | |
| 93 | |
| 94 function onPositionsList(buffer) | |
| 95 { | |
| 96 var positions = buffer.toString("binary") | |
| 97 .match(/([^<>]+)(?=<\/Prefix><\/CommonPrefixes>)/g) | |
| 98 .map(prefixedPosition => prefixedPosition.split("/")[1]) | |
| 99 .map(positionString => parseInt(positionString, 10)); | |
| 100 var positionSet = new Set(positions); | |
| 101 var previousUploadedPosition = commitPosition; | |
| 102 while (commitPosition - previousUploadedPosition < 100) { | |
| 103 if (positionSet.has(previousUploadedPosition)) | |
| 104 return previousUploadedPosition.toString(); | |
| 105 previousUploadedPosition--; | |
| 106 } | |
| 107 onError(); | |
| 108 } | |
| 109 | |
| 110 function onError(error) | |
| 111 { | |
| 112 if (error) | |
| 113 console.log(`Received error: ${error} trying to fetch positions list from url: ${positionsListURL}`); | |
| 114 throw new Error(`Unable to find a previous upload position for commit po sition: ${commitPosition}`); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 function prepareContentShellDirectory(contentShellCommitPosition) | |
| 119 { | |
| 120 var contentShellPath = path.join(CACHE_PATH, contentShellCommitPosition); | |
| 121 if (utils.isDir(contentShellPath)) | |
| 122 utils.removeRecursive(contentShellPath); | |
| 123 fs.mkdirSync(contentShellPath); | |
| 124 return Promise.resolve(contentShellCommitPosition); | |
| 125 } | |
| 126 | |
| 127 function downloadContentShell(commitPosition) | |
| 128 { | |
| 129 var url = `http://commondatastorage.googleapis.com/chromium-browser-snapshot s/${PLATFORM}/${commitPosition}/${CONTENT_SHELL_ZIP}`; | |
| 130 console.log("Downloading content shell from:", url); | |
| 131 return utils.fetch(url) | |
| 132 .then(writeZip) | |
| 133 .catch(onError); | |
| 134 | |
| 135 function writeZip(buffer) | |
| 136 { | |
| 137 console.log("Completed download of content shell"); | |
| 138 var contentShellZipPath = path.join(CACHE_PATH, commitPosition, CONTENT_ SHELL_ZIP); | |
| 139 fs.writeFileSync(contentShellZipPath, buffer); | |
| 140 return contentShellZipPath; | |
| 141 } | |
| 142 | |
| 143 function onError(error) | |
| 144 { | |
| 145 console.log(`Received error: ${error} trying to download content shell f rom url: ${url}`); | |
| 146 throw new Error("Unable to download content shell"); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 function extractContentShell(contentShellZipPath) | |
| 151 { | |
| 152 console.log(`Extracting content shell zip: ${contentShellZipPath}`); | |
| 153 var unzipScriptPath = path.resolve(__dirname, "unzip.py"); | |
| 154 var src = contentShellZipPath; | |
| 155 var dest = path.resolve(path.dirname(src), "out"); | |
| 156 shell(`${PYTHON} ${unzipScriptPath} ${src} ${dest}`); | |
| 157 fs.unlinkSync(src); | |
| 158 var originalDirPath = path.resolve(dest, "content-shell"); | |
| 159 var newDirPath = path.resolve(dest, "Release"); | |
| 160 fs.renameSync(originalDirPath, newDirPath); | |
| 161 fs.chmodSync(getContentShellBinaryPath(newDirPath), "755"); | |
| 162 if (process.platform === "darwin") { | |
| 163 var helperPath = path.resolve(newDirPath, "Content Shell.app", "Contents ", "Frameworks", "Content Shell Helper.app", "Contents", "MacOS", "Content Shell Helper"); | |
| 164 fs.chmodSync(helperPath, "755"); | |
| 165 } | |
| 166 return dest; | |
| 167 } | |
| 168 | |
| 169 function getContentShellBinaryPath(dirPath) | |
| 170 { | |
| 171 if (process.platform === "linux") { | |
| 172 return path.resolve(dirPath, "content_shell"); | |
| 173 } | |
| 174 if (process.platform === "win32") { | |
| 175 return path.resolve(dirPath, "content_shell.exe"); | |
| 176 } | |
| 177 if (process.platform === "darwin") { | |
| 178 return path.resolve(dirPath, "Content Shell.app", "Contents", "MacOS", " Content Shell"); | |
| 179 } | |
| 180 } | |
| 181 | |
| 182 function buildAndTest(commitPosition, buildDirectoryPath) | |
| 183 { | |
| 184 var contentShellResourcesPath = path.resolve(buildDirectoryPath, "Release", "resources"); | |
| 185 return buildDevtools(commitPosition, contentShellResourcesPath) | |
| 186 .then(() => runTests(buildDirectoryPath)); | |
| 187 } | |
| 188 | |
| 189 function buildDevtools(commitPosition, contentShellResourcesPath) | |
| 190 { | |
| 191 var chromiumCommitPromise = fetchChromiumCommitFromPosition(commitPosition); | |
| 192 var v8CommitPromise = fetchV8CommitFromChromiumPosition(commitPosition); | |
| 193 var copyDevtoolsFiles = IS_DEBUG_ENABLED ? copyDevtoolsDebugFiles : copyDevt oolsReleaseFiles; | |
| 194 return Promise.all([chromiumCommitPromise, v8CommitPromise]) | |
| 195 .then(build) | |
| 196 .then(() => copyDevtoolsFiles(contentShellResourcesPath)) | |
| 197 .catch(onError); | |
| 198 | |
| 199 function build(commitHashes) { | |
| 200 if (!utils.isDir(path.resolve(JS_BUILD_PATH, "node_modules"))) | |
| 201 shell("npm install", {cwd: JS_BUILD_PATH, stdio: "inherit"}); | |
| 202 var env = { | |
| 203 CHROMIUM_COMMIT: commitHashes[0], | |
| 204 V8_COMMIT: commitHashes[1], | |
| 205 }; | |
| 206 var options = { | |
| 207 cwd: JS_BUILD_PATH, | |
| 208 env: Object.assign({}, process.env, env), | |
| 209 stdio: "inherit", | |
| 210 }; | |
| 211 shell("npm run build", options); | |
| 212 } | |
| 213 | |
| 214 function onError(error) | |
| 215 { | |
| 216 console.log(`Received error: ${error} trying to build devtools`); | |
| 217 throw new Error("Unable to build devtools"); | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 function copyDevtoolsDebugFiles(contentShellResourcesPath) | |
| 222 { | |
| 223 var devtoolsResourcesPath = path.resolve(contentShellResourcesPath, "inspect or"); | |
| 224 var copiedFrontendPath = path.resolve(devtoolsResourcesPath, "front_end"); | |
| 225 var debugPath = path.resolve(devtoolsResourcesPath, "debug"); | |
| 226 utils.removeRecursive(copiedFrontendPath); | |
| 227 utils.removeRecursive(debugPath); | |
| 228 utils.copyRecursive(SOURCE_PATH, devtoolsResourcesPath); | |
| 229 fs.renameSync(copiedFrontendPath, debugPath); | |
| 230 var inspectorBackendCommandsPath = path.resolve(RELEASE_PATH, "InspectorBack endCommands.js"); | |
| 231 var supportedCSSPropertiesPath = path.resolve(RELEASE_PATH, "SupportedCSSPro perties.js"); | |
| 232 utils.copy(inspectorBackendCommandsPath, debugPath); | |
| 233 utils.copy(supportedCSSPropertiesPath, debugPath); | |
| 234 } | |
| 235 | |
| 236 function copyDevtoolsReleaseFiles(contentShellResourcesPath) | |
| 237 { | |
| 238 var devtoolsResourcesPath = path.resolve(contentShellResourcesPath, "inspect or"); | |
| 239 var copiedFrontendPath = path.resolve(contentShellResourcesPath, "release"); | |
| 240 utils.removeRecursive(devtoolsResourcesPath); | |
| 241 utils.removeRecursive(copiedFrontendPath); | |
| 242 utils.copyRecursive(RELEASE_PATH, contentShellResourcesPath); | |
| 243 fs.renameSync(copiedFrontendPath, devtoolsResourcesPath); | |
| 244 } | |
| 245 | |
| 246 function fetchV8CommitFromChromiumPosition(commitPosition) | |
| 247 { | |
| 248 var url = `http://commondatastorage.googleapis.com/chromium-browser-snapshot s/${PLATFORM}/${commitPosition}/REVISIONS`; | |
| 249 return utils.fetch(url).then(onResponse); | |
| 250 | |
| 251 function onResponse(buffer) | |
| 252 { | |
| 253 var commitHash = JSON.parse(buffer.toString("binary")).v8_revision_git; | |
| 254 return commitHash; | |
| 255 } | |
| 256 } | |
| 257 | |
| 258 function fetchChromiumCommitFromPosition(commitPosition) | |
| 259 { | |
| 260 var url = `https://cr-rev.appspot.com/_ah/api/crrev/v1/redirect/${commitPosi tion}`; | |
| 261 return utils.fetch(url).then(onResponse); | |
| 262 | |
| 263 function onResponse(buffer) | |
| 264 { | |
| 265 var commitHash = JSON.parse(buffer.toString("binary")).git_sha; | |
| 266 return commitHash; | |
| 267 } | |
| 268 } | |
| 269 | |
| 270 function runTests(buildDirectoryPath) | |
| 271 { | |
| 272 var testArgs = [ | |
| 273 "--no-pixel-tests", | |
| 274 "--build-directory", | |
| 275 buildDirectoryPath, | |
| 276 ].concat(getInspectorTests()); | |
| 277 if (IS_DEBUG_ENABLED) { | |
| 278 testArgs.push(`--additional-drt-flag=${DEBUG_DEVTOOLS_FLAG}`); | |
| 279 testArgs.push("--additional-drt-flag=--remote-debugging-port=9222"); | |
| 280 testArgs.push("--time-out-ms=6000000"); | |
| 281 console.log("\n============================================="); | |
| 282 console.log("Go to: http://localhost:9222/"); | |
| 283 console.log("Click on link and in console execute: test()"); | |
| 284 console.log("=============================================\n"); | |
| 285 } | |
| 286 var args = [BLINK_TEST_PATH].concat(testArgs).concat(getTestFlags()); | |
| 287 console.log(`Running layout tests with args: ${args}`); | |
| 288 childProcess.spawn(PYTHON, args, {stdio: "inherit"}); | |
| 289 } | |
| 290 | |
| 291 function getTestFlags() | |
| 292 { | |
| 293 return process.argv | |
| 294 .slice(2) | |
| 295 .filter(arg => arg !== DEBUG_DEVTOOLS_FLAG && !utils.includes(arg, "insp ector")); | |
| 296 } | |
| 297 | |
| 298 function getInspectorTests() | |
| 299 { | |
| 300 var specificTests = process.argv.filter(arg => utils.includes(arg, "inspecto r")); | |
| 301 if (specificTests.length) | |
| 302 return specificTests; | |
| 303 return [ | |
| 304 "inspector", | |
|
dgozman
2016/10/14 21:40:31
We can use inspector*, http/tests/inspector* :-)
chenwilliam
2016/10/17 19:01:28
Done.
| |
| 305 "inspector-protocol", | |
| 306 "inspector-enabled", | |
| 307 "http/tests/inspector", | |
| 308 "http/tests/inspector-protocol", | |
| 309 "http/tests/inspector-enabled", | |
| 310 "http/tests/inspector-unit", | |
| 311 ]; | |
| 312 } | |
| OLD | NEW |