1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /* exported PerTestCoverageUtils */
9 var EXPORTED_SYMBOLS = ["PerTestCoverageUtils"];
11 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
13 const env = Cc["@mozilla.org/process/environment;1"].getService(
16 // This is the directory where gcov is emitting the gcda files.
17 const gcovPrefixPath = env.get("GCOV_PREFIX");
18 // This is the directory where codecoverage.py is expecting to see the gcda files.
19 const gcovResultsPath = env.get("GCOV_RESULTS_DIR");
20 // This is the directory where the JS engine is emitting the lcov files.
21 const jsvmPrefixPath = env.get("JS_CODE_COVERAGE_OUTPUT_DIR");
22 // This is the directory where codecoverage.py is expecting to see the lcov files.
23 const jsvmResultsPath = env.get("JSVM_RESULTS_DIR");
25 const gcovPrefixDir = Cc["@mozilla.org/file/local;1"].createInstance(
29 gcovPrefixDir.initWithPath(gcovPrefixPath);
32 let gcovResultsDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
33 if (gcovResultsPath) {
34 gcovResultsDir.initWithPath(gcovResultsPath);
37 const jsvmPrefixDir = Cc["@mozilla.org/file/local;1"].createInstance(
41 jsvmPrefixDir.initWithPath(jsvmPrefixPath);
44 let jsvmResultsDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
45 if (jsvmResultsPath) {
46 jsvmResultsDir.initWithPath(jsvmResultsPath);
49 function awaitPromise(promise) {
54 .catch(e => (error = e))
59 Services.tm.spinEventLoopUntil(() => complete);
61 throw new Error(error);
66 function removeDirectoryContents(dir) {
67 let entries = dir.directoryEntries;
68 while (entries.hasMoreElements()) {
69 entries.nextFile.remove(true);
73 function moveDirectoryContents(src, dst) {
74 let entries = src.directoryEntries;
75 while (entries.hasMoreElements()) {
76 entries.nextFile.moveTo(dst, null);
80 var PerTestCoverageUtils = class PerTestCoverageUtilsClass {
81 // Resets the counters to 0.
82 static async beforeTest() {
83 if (!PerTestCoverageUtils.enabled) {
87 // Flush the counters.
88 let codeCoverageService = Cc[
89 "@mozilla.org/tools/code-coverage;1"
90 ].getService(Ci.nsICodeCoverage);
91 await codeCoverageService.flushCounters();
93 // Remove coverage files created by the flush, and those that might have been created between the end of a previous test and the beginning of the next one (e.g. some tests can create a new content process for every sub-test).
94 removeDirectoryContents(gcovPrefixDir);
95 removeDirectoryContents(jsvmPrefixDir);
97 // Move coverage files from the GCOV_RESULTS_DIR and JSVM_RESULTS_DIR directories, so we can accumulate the counters.
98 moveDirectoryContents(gcovResultsDir, gcovPrefixDir);
99 moveDirectoryContents(jsvmResultsDir, jsvmPrefixDir);
102 static beforeTestSync() {
103 awaitPromise(this.beforeTest());
106 // Dumps counters and moves the gcda files in the directory expected by codecoverage.py.
107 static async afterTest() {
108 if (!PerTestCoverageUtils.enabled) {
112 // Flush the counters.
113 let codeCoverageService = Cc[
114 "@mozilla.org/tools/code-coverage;1"
115 ].getService(Ci.nsICodeCoverage);
116 await codeCoverageService.flushCounters();
118 // Move the coverage files in GCOV_RESULTS_DIR and JSVM_RESULTS_DIR, so that the execution from now to shutdown (or next test) is not counted.
119 moveDirectoryContents(gcovPrefixDir, gcovResultsDir);
120 moveDirectoryContents(jsvmPrefixDir, jsvmResultsDir);
123 static afterTestSync() {
124 awaitPromise(this.afterTest());
128 PerTestCoverageUtils.enabled = !!gcovResultsPath;