Bug 1470151 - Support resetting/dumping coverage counters in per-test mode for xpcshell on Linux. r=jmaher
authorMarco Castelluccio <mcastelluccio@mozilla.com>
Thu, 21 Jun 2018 14:41:32 +0100
changeset 479036 ad943a10a01d0af3fc657b0672a67e1b5925a1c8
parent 479035 a84d5258fce5ef60d233cfc73c520e0509a0cd87
child 479037 0ca9cade77252f5b7a11c1cb8d00d792ee25c78a
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs1470151
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1470151 - Support resetting/dumping coverage counters in per-test mode for xpcshell on Linux. r=jmaher
testing/mozharness/scripts/desktop_unittest.py
testing/xpcshell/head.js
--- a/testing/mozharness/scripts/desktop_unittest.py
+++ b/testing/mozharness/scripts/desktop_unittest.py
@@ -10,16 +10,17 @@
 author: Jordan Lund
 """
 
 import os
 import re
 import sys
 import copy
 import shutil
+import tempfile
 import glob
 import imp
 
 from datetime import datetime, timedelta
 
 # load modules from parent dir
 sys.path.insert(1, os.path.dirname(sys.path[0]))
 
@@ -885,16 +886,20 @@ class DesktopUnittest(TestingMixin, Merc
 
                         executed_tests = executed_tests + 1
 
                     final_cmd = copy.copy(cmd)
                     final_cmd.extend(per_test_args)
 
                     if self.per_test_coverage:
                         gcov_dir, jsvm_dir = self.set_coverage_env(env)
+                        # Per-test reset/dump is only supported for xpcshell and
+                        # Linux for the time being.
+                        if not is_baseline_test and suite == 'xpcshell' and self._is_linux():
+                            env['GCOV_RESULTS_DIR'] = gcov_dir = tempfile.mkdtemp()
 
                     return_code = self.run_command(final_cmd, cwd=dirs['abs_work_dir'],
                                                    output_timeout=cmd_timeout,
                                                    output_parser=parser,
                                                    env=env)
 
                     if self.per_test_coverage:
                         self.add_per_test_coverage_report(
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -506,16 +506,32 @@ function _execute_test() {
   _load_files(_TEST_FILE);
 
   // Tack Assert.jsm methods to the current scope.
   this.Assert = Assert;
   for (let func in Assert) {
     this[func] = Assert[func].bind(Assert);
   }
 
+  let perTestCoverageEnabled = false;
+  try {
+    ChromeUtils.import("resource://testing-common/PerTestCoverageUtils.jsm");
+    perTestCoverageEnabled = true;
+  } catch (e) {
+    // If the module doesn't exist, code coverage is disabled.
+    // Otherwise, rethrow the exception.
+    if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
+      throw e;
+    }
+  }
+
+  if (perTestCoverageEnabled) {
+    PerTestCoverageUtils.beforeTest();
+  }
+
   try {
     do_test_pending("MAIN run_test");
     // Check if run_test() is defined. If defined, run it.
     // Else, call run_next_test() directly to invoke tests
     // added by add_test() and add_task().
     if (typeof run_test === "function") {
       run_test();
     } else {
@@ -524,16 +540,20 @@ function _execute_test() {
 
     do_test_finished("MAIN run_test");
     _do_main();
     _PromiseTestUtils.assertNoUncaughtRejections();
 
     if (coverageCollector != null) {
       coverageCollector.recordTestCoverage(_TEST_FILE[0]);
     }
+
+    if (perTestCoverageEnabled) {
+      PerTestCoverageUtils.afterTest();
+    }
   } catch (e) {
     _passed = false;
     // do_check failures are already logged and set _quit to true and throw
     // NS_ERROR_ABORT. If both of those are true it is likely this exception
     // has already been logged so there is no need to log it again. It's
     // possible that this will mask an NS_ERROR_ABORT that happens after a
     // do_check failure though.