Merge inbound to mozilla-central. a=merge
authorshindli <shindli@mozilla.com>
Tue, 29 May 2018 12:52:25 +0300
changeset 420197 f01bb6245db1ea2a87e5360104a4110571265137
parent 420182 4342f8a6634514e16171afda492623e6b3e8340e (current diff)
parent 420196 4d7efa2ca9e2aae089754cd85558a048c9121512 (diff)
child 420203 bbc9b2b50815f2d48492c0b5434804605438b9a0
child 420262 25dfb377f644f48469566055a514e182998be4fa
push id34067
push usershindli@mozilla.com
push dateTue, 29 May 2018 09:52:49 +0000
treeherdermozilla-central@f01bb6245db1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone62.0a1
first release with
nightly linux32
f01bb6245db1 / 62.0a1 / 20180529100118 / files
nightly linux64
f01bb6245db1 / 62.0a1 / 20180529100118 / files
nightly mac
f01bb6245db1 / 62.0a1 / 20180529100118 / files
nightly win32
f01bb6245db1 / 62.0a1 / 20180529100118 / files
nightly win64
f01bb6245db1 / 62.0a1 / 20180529100118 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
--- a/accessible/aom/AccessibleNode.cpp
+++ b/accessible/aom/AccessibleNode.cpp
@@ -13,17 +13,31 @@
 #include "Accessible-inl.h"
 #include "nsAccessibilityService.h"
 #include "DocAccessible.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 using namespace mozilla::dom;
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(AccessibleNode)
+bool
+AccessibleNode::IsAOMEnabled(JSContext* aCx, JSObject* /*unused*/)
+{
+  static bool sPrefCached = false;
+  static bool sPrefCacheValue = false;
+
+  if (!sPrefCached) {
+    sPrefCached = true;
+    Preferences::AddBoolVarCache(&sPrefCacheValue, "accessibility.AOM.enabled");
+  }
+
+  return nsContentUtils::IsSystemCaller(aCx) || sPrefCacheValue;
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AccessibleNode, mIntl, mDOMNode, mStates)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AccessibleNode)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(AccessibleNode)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode)
--- a/accessible/aom/AccessibleNode.h
+++ b/accessible/aom/AccessibleNode.h
@@ -42,17 +42,17 @@ public:
   nsINode* GetDOMNode();
 
   bool Is(const Sequence<nsString>& aFlavors);
   bool Has(const Sequence<nsString>& aAttributes);
   void Get(JSContext* cx, const nsAString& aAttribute,
            JS::MutableHandle<JS::Value> aValue,
            ErrorResult& aRv);
 
-  a11y::Accessible* Internal() const { return mIntl; }
+  static bool IsAOMEnabled(JSContext*, JSObject*);
 
 protected:
   AccessibleNode(const AccessibleNode& aCopy) = delete;
   AccessibleNode& operator=(const AccessibleNode& aCopy) = delete;
   virtual ~AccessibleNode();
 
   RefPtr<a11y::Accessible> mIntl;
   RefPtr<nsINode> mDOMNode;
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -400,18 +400,19 @@ NS_IMPL_ISUPPORTS_INHERITED(nsAccessibil
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIObserver
 
 NS_IMETHODIMP
 nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
                          const char16_t *aData)
 {
-  if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
+  if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
     Shutdown();
+  }
 
   return NS_OK;
 }
 
 void
 nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent* aTargetNode)
 {
   nsIDocument* documentNode = aTargetNode->GetUncomposedDoc();
--- a/devtools/client/shared/components/VirtualizedTree.js
+++ b/devtools/client/shared/components/VirtualizedTree.js
@@ -254,25 +254,26 @@ class Tree extends Component {
     this._focusParentNode = oncePerAnimationFrame(this._focusParentNode).bind(this);
     this._focusFirstNode = oncePerAnimationFrame(this._focusFirstNode).bind(this);
     this._focusLastNode = oncePerAnimationFrame(this._focusLastNode).bind(this);
     this._activateNode = oncePerAnimationFrame(this._activateNode).bind(this);
 
     this._autoExpand = this._autoExpand.bind(this);
     this._preventArrowKeyScrolling = this._preventArrowKeyScrolling.bind(this);
     this._updateHeight = this._updateHeight.bind(this);
+    this._onResize = this._onResize.bind(this);
     this._dfs = this._dfs.bind(this);
     this._dfsFromRoots = this._dfsFromRoots.bind(this);
     this._focus = this._focus.bind(this);
     this._onBlur = this._onBlur.bind(this);
     this._onKeyDown = this._onKeyDown.bind(this);
   }
 
   componentDidMount() {
-    window.addEventListener("resize", this._updateHeight);
+    window.addEventListener("resize", this._onResize);
     this._autoExpand();
     this._updateHeight();
   }
 
   componentWillReceiveProps(nextProps) {
     this._autoExpand();
     this._updateHeight();
   }
@@ -282,17 +283,17 @@ class Tree extends Component {
 
     return scroll !== nextState.scroll ||
            height !== nextState.height ||
            seen !== nextState.seen ||
            mouseDown === nextState.mouseDown;
   }
 
   componentWillUnmount() {
-    window.removeEventListener("resize", this._updateHeight);
+    window.removeEventListener("resize", this._onResize);
   }
 
   _autoExpand() {
     if (!this.props.autoExpandDepth) {
       return;
     }
 
     // Automatically expand the first autoExpandDepth levels for new items. Do
@@ -447,16 +448,30 @@ class Tree extends Component {
     }
 
     if (this.props.onFocus) {
       this.props.onFocus(item);
     }
   }
 
   /**
+   * Update state height and tree's scrollTop if necessary.
+   */
+  _onResize() {
+    // When tree size changes without direct user action, scroll top cat get re-set to 0
+    // (for example, when tree height changes via CSS rule change). We need to ensure that
+    // the tree's scrollTop is in sync with the scroll state.
+    if (this.state.scroll !== this.refs.tree.scrollTop) {
+      this.refs.tree.scrollTo({ left: 0, top: this.state.scroll });
+    }
+
+    this._updateHeight();
+  }
+
+  /**
    * Sets the state to have no focused item.
    */
   _onBlur() {
     this._focus(0, undefined);
   }
 
   /**
    * Fired on a scroll within the tree's container, updates
--- a/devtools/client/shared/components/test/mochitest/chrome.ini
+++ b/devtools/client/shared/components/test/mochitest/chrome.ini
@@ -22,8 +22,9 @@ support-files =
 [test_tree_05.html]
 [test_tree_06.html]
 [test_tree_07.html]
 [test_tree_08.html]
 [test_tree_09.html]
 [test_tree_10.html]
 [test_tree_11.html]
 [test_tree_12.html]
+[test_tree_13.html]
new file mode 100644
--- /dev/null
+++ b/devtools/client/shared/components/test/mochitest/test_tree_13.html
@@ -0,0 +1,83 @@
+<!-- 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/. -->
+<!DOCTYPE HTML>
+<html>
+<!--
+Test trees have the correct scroll position when they are resized.
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Tree component test</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+  <style>
+   .tree {
+       height: 50px;
+       overflow: auto;
+       display: block;
+   }
+  </style>
+</head>
+<body>
+<pre id="test">
+<script src="head.js" type="application/javascript"></script>
+<script type="application/javascript">
+
+"use strict";
+
+window.onload = async function() {
+  try {
+    const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
+    const { createFactory } = browserRequire("devtools/client/shared/vendor/react");
+    const { Simulate } =
+      browserRequire("devtools/client/shared/vendor/react-dom-test-utils");
+    const Tree = createFactory(
+      browserRequire("devtools/client/shared/components/VirtualizedTree"));
+    const ITEM_HEIGHT = 10;
+
+    TEST_TREE.expanded = new Set("ABCDEFGHIJKLMNO".split(""));
+
+    function renderTree(props) {
+      const treeProps = {
+        ...TEST_TREE_INTERFACE,
+        itemHeight: ITEM_HEIGHT,
+        onFocus: item => renderTree({ focused: item }),
+        ...props
+      };
+      return ReactDOM.render(Tree(treeProps), document.body);
+    }
+
+    const tree = renderTree({ focused: "L" });
+    const treeEl = tree.refs.tree;
+
+    is(tree.state.scroll, 0, "Scroll position should be 0 by default");
+    is(treeEl.scrollTop, 0, "Tree scrollTop should be 0 by default");
+
+    info(`Focus on the next node and scroll by ${ITEM_HEIGHT}`);
+    Simulate.keyDown(treeEl, { key: "ArrowDown" });
+    await forceRender(tree);
+
+    is(tree.state.scroll, ITEM_HEIGHT, `Scroll position should now be ${ITEM_HEIGHT}`);
+    is(treeEl.scrollTop, ITEM_HEIGHT,
+      `Tree scrollTop should now be ${ITEM_HEIGHT}`);
+
+    info("Simulate window resize along with scroll back to top");
+    treeEl.scrollTo({ left: 0, top: 0 });
+    window.dispatchEvent(new Event("resize"));
+    await forceRender(tree);
+
+    is(tree.state.scroll, ITEM_HEIGHT,
+      `Scroll position should remain at ${ITEM_HEIGHT}`);
+    is(treeEl.scrollTop, ITEM_HEIGHT,
+      `Tree scrollTop should remain at ${ITEM_HEIGHT}`);
+  } catch (e) {
+    ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
+  } finally {
+    SimpleTest.finish();
+  }
+};
+</script>
+</pre>
+</body>
+</html>
--- a/dom/webidl/AccessibleNode.webidl
+++ b/dom/webidl/AccessibleNode.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  */
 
-[Pref="accessibility.AOM.enabled"]
+[Func="mozilla::dom::AccessibleNode::IsAOMEnabled"]
 interface AccessibleNode {
   readonly attribute DOMString role;
   [Frozen, Cached, Pure]
   readonly attribute sequence<DOMString> states;
   [Frozen, Cached, Pure]
   readonly attribute sequence<DOMString> attributes;
   readonly attribute Node? DOMNode;
 
--- a/dom/webidl/Node.webidl
+++ b/dom/webidl/Node.webidl
@@ -203,16 +203,16 @@ interface Node : EventTarget {
    *     ]
    *
    * For exact dictionary structures, see `L10nUtils.webidl`.
    */
   [ChromeOnly, Throws]
   Promise<void> localize(L10nCallback l10nCallback);
 
 #ifdef ACCESSIBILITY
-  [Pref="accessibility.AOM.enabled"]
+  [Func="mozilla::dom::AccessibleNode::IsAOMEnabled"]
   readonly attribute AccessibleNode? accessibleNode;
 #endif
 };
 
 dictionary GetRootNodeOptions {
   boolean composed = false;
 };
--- a/gfx/2d/ssse3-scaler.c
+++ b/gfx/2d/ssse3-scaler.c
@@ -32,23 +32,26 @@
 
 #include <stdlib.h>
 #include <mmintrin.h>
 #include <xmmintrin.h>
 #include <emmintrin.h>
 #include <tmmintrin.h>
 #include <stdint.h>
 #include <assert.h>
+#include "ssse3-scaler.h"
 
 typedef int32_t                 pixman_fixed_16_16_t;
 typedef pixman_fixed_16_16_t    pixman_fixed_t;
 #define pixman_fixed_1                  (pixman_int_to_fixed(1))
 #define pixman_fixed_to_int(f)          ((int) ((f) >> 16))
 #define pixman_int_to_fixed(i)          ((pixman_fixed_t) ((i) << 16))
 #define pixman_double_to_fixed(d)       ((pixman_fixed_t) ((d) * 65536.0))
+#define PIXMAN_FIXED_INT_MAX 32767
+#define PIXMAN_FIXED_INT_MIN -32768
 typedef struct pixman_vector pixman_vector_t;
 
 typedef int pixman_bool_t;
 typedef int64_t                 pixman_fixed_32_32_t;
 typedef pixman_fixed_32_32_t    pixman_fixed_48_16_t;
 typedef struct { pixman_fixed_48_16_t v[3]; } pixman_vector_48_16_t;
 
 struct pixman_vector
@@ -458,16 +461,22 @@ ssse3_bilinear_cover_iter_fini (pixman_i
 
 static void
 ssse3_bilinear_cover_iter_init (pixman_iter_t *iter)
 {
     int width = iter->width;
     bilinear_info_t *info;
     pixman_vector_t v;
 
+    if (iter->x > PIXMAN_FIXED_INT_MAX ||
+        iter->x < PIXMAN_FIXED_INT_MIN ||
+        iter->y > PIXMAN_FIXED_INT_MAX ||
+        iter->y < PIXMAN_FIXED_INT_MIN)
+      goto fail;
+
     /* Reference point is the center of the pixel */
     v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2;
     v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2;
     v.vector[2] = pixman_fixed_1;
 
     if (!pixman_transform_point_3d (iter->image->transform, &v))
 	goto fail;
 
@@ -500,17 +509,17 @@ fail:
      * we don't guarantee any particular rendering.
      */
     iter->fini = NULL;
 }
 
 /* scale the src from src_width/height to dest_width/height drawn
  * into the rectangle x,y width,height
  * src_stride and dst_stride are 4 byte units */
-void ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stride,
+bool ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stride,
                       uint32_t *dest, int dest_width, int dest_height,
                       int dest_stride,
                       int x, int y,
                       int width, int height)
 {
     //XXX: assert(src_width > 1)
     pixman_transform_t transform = {
         { { pixman_fixed_1, 0, 0 },
@@ -546,16 +555,21 @@ void ssse3_scale_data(uint32_t *src, int
     iter.x = x;
     iter.y = y;
     iter.width = width;
     iter.height = src_height;
     iter.buffer = dest;
     iter.data = NULL;
 
     ssse3_bilinear_cover_iter_init(&iter);
+
+    if (!iter.fini)
+      return false;
+
     if (iter.data) {
         for (int iy = 0; iy < height; iy++) {
             ssse3_fetch_bilinear_cover(&iter, NULL);
             iter.buffer += dest_stride;
         }
         ssse3_bilinear_cover_iter_fini(&iter);
     }
+    return true;
 }
--- a/gfx/2d/ssse3-scaler.h
+++ b/gfx/2d/ssse3-scaler.h
@@ -2,20 +2,22 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef MOZILLA_GFX_2D_SSSE3_SCALER_H_
 #define MOZILLA_GFX_2D_SSSE3_SCALER_H_
 
+#include <stdbool.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
-void ssse3_scale_data(uint32_t *src, int src_width, int src_height,
+bool ssse3_scale_data(uint32_t *src, int src_width, int src_height,
                 int src_stride,
                 uint32_t *dest, int dest_width, int dest_height,
                 int dest_rowstride,
                 int x, int y,
                 int width, int height);
 #ifdef __cplusplus
 }
 #endif
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -552,25 +552,25 @@ AttemptVideoScale(TextureSourceBasic* aS
     }
 
     fillRect = fillRect.Intersect(IntRect(IntPoint(0, 0), aDest->GetSize()));
     IntPoint offset = fillRect.TopLeft() - dstRect.TopLeft();
 
     RefPtr<DataSourceSurface> srcSource = aSource->GetSurface(aDest)->GetDataSurface();
     DataSourceSurface::ScopedMap mapSrc(srcSource, DataSourceSurface::READ);
 
-    ssse3_scale_data((uint32_t*)mapSrc.GetData(), srcSource->GetSize().width, srcSource->GetSize().height,
-                     mapSrc.GetStride()/4,
-                     ((uint32_t*)dstData) + fillRect.X() + (dstStride / 4) * fillRect.Y(), dstRect.Width(), dstRect.Height(),
-                     dstStride / 4,
-                     offset.x, offset.y,
-                     fillRect.Width(), fillRect.Height());
+    bool success = ssse3_scale_data((uint32_t*)mapSrc.GetData(), srcSource->GetSize().width, srcSource->GetSize().height,
+                                    mapSrc.GetStride()/4,
+                                    ((uint32_t*)dstData) + fillRect.X() + (dstStride / 4) * fillRect.Y(), dstRect.Width(), dstRect.Height(),
+                                    dstStride / 4,
+                                    offset.x, offset.y,
+                                    fillRect.Width(), fillRect.Height());
 
     aDest->ReleaseBits(dstData);
-    return true;
+    return success;
   } else
 #endif // MOZILLA_SSE_HAVE_CPUID_DETECTION
     return false;
 }
 
 static bool
 AttemptVideoConvertAndScale(TextureSource* aSource, const SourceSurface* aSourceMask,
                             gfx::Float aOpacity, CompositionOp aBlendMode,
--- a/js/src/builtin/JSON.cpp
+++ b/js/src/builtin/JSON.cpp
@@ -291,17 +291,18 @@ PreprocessValue(JSContext* cx, HandleObj
                 return false;
             vp.setString(str);
         } else if (cls == ESClass::Boolean) {
             if (!Unbox(cx, obj, vp))
                 return false;
         }
 #ifdef ENABLE_BIGINT
         else if (cls == ESClass::BigInt) {
-            vp.setBigInt(obj->as<BigIntObject>().unbox());
+            if (!Unbox(cx, obj, vp))
+                return false;
         }
 #endif
     }
 
     return true;
 }
 
 /*
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -4132,16 +4132,20 @@ js::Unbox(JSContext* cx, HandleObject ob
     else if (obj->is<NumberObject>())
         vp.setNumber(obj->as<NumberObject>().unbox());
     else if (obj->is<StringObject>())
         vp.setString(obj->as<StringObject>().unbox());
     else if (obj->is<DateObject>())
         vp.set(obj->as<DateObject>().UTCTime());
     else if (obj->is<SymbolObject>())
         vp.setSymbol(obj->as<SymbolObject>().unbox());
+#ifdef ENABLE_BIGINT
+    else if (obj->is<BigIntObject>())
+        vp.setBigInt(obj->as<BigIntObject>().unbox());
+#endif
     else
         vp.setUndefined();
 
     return true;
 }
 
 #ifdef DEBUG
 /* static */ void
--- a/js/src/wasm/WasmSignalHandlers.cpp
+++ b/js/src/wasm/WasmSignalHandlers.cpp
@@ -1388,16 +1388,21 @@ static bool sHaveSignalHandlers = false;
 static bool
 ProcessHasSignalHandlers()
 {
     // We assume that there are no races creating the first JSRuntime of the process.
     if (sTriedInstallSignalHandlers)
         return sHaveSignalHandlers;
     sTriedInstallSignalHandlers = true;
 
+#if defined (JS_CODEGEN_NONE)
+    // If there is no JIT, then there should be no Wasm signal handlers.
+    return false;
+#endif
+
 #if defined(ANDROID) && defined(MOZ_LINKER)
     // Signal handling is broken on some android systems.
     if (IsSignalHandlingBroken())
         return false;
 #endif
 
     // Initalize ThreadLocal flag used by WasmFaultHandler
     sAlreadyInSignalHandler.infallibleInit();
--- a/servo/components/style/stylesheets/stylesheet.rs
+++ b/servo/components/style/stylesheets/stylesheet.rs
@@ -358,23 +358,23 @@ impl Stylesheet {
         let mut input = Parser::new(&mut input);
 
         let context = ParserContext::new(origin, url_data, None, ParsingMode::DEFAULT, quirks_mode);
 
         let error_context = ParserErrorContext { error_reporter };
 
         let rule_parser = TopLevelRuleParser {
             stylesheet_origin: origin,
-            shared_lock: shared_lock,
+            shared_lock,
             loader: stylesheet_loader,
-            context: context,
-            error_context: error_context,
+            context,
+            error_context,
             state: State::Start,
             had_hierarchy_error: false,
-            namespaces: namespaces,
+            namespaces,
         };
 
         {
             let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
 
             while let Some(result) = iter.next() {
                 match result {
                     Ok(rule) => {
--- a/testing/mozharness/mozharness/base/script.py
+++ b/testing/mozharness/mozharness/base/script.py
@@ -1378,17 +1378,21 @@ class ScriptMixin(PlatformMixin):
         shell = True
         if isinstance(command, list) or isinstance(command, tuple):
             shell = False
         if env is None:
             if partial_env:
                 self.info("Using partial env: %s" % pprint.pformat(partial_env))
                 env = self.query_env(partial_env=partial_env)
         else:
-            self.info("Using env: %s" % pprint.pformat(env))
+            if hasattr(self, 'previous_env') and env == self.previous_env:
+                self.info("Using env: (same as previous command)")
+            else:
+                self.info("Using env: %s" % pprint.pformat(env))
+                self.previous_env = env
 
         if output_parser is None:
             parser = OutputParser(config=self.config, log_obj=self.log_obj,
                                   error_list=error_list)
         else:
             parser = output_parser
 
         try:
@@ -2127,17 +2131,17 @@ class BaseScript(ScriptMixin, LogMixin, 
         dirs['base_work_dir'] = c['base_work_dir']
         dirs['abs_work_dir'] = os.path.join(c['base_work_dir'], c['work_dir'])
         dirs['abs_upload_dir'] = os.path.join(dirs['abs_work_dir'], 'upload')
         dirs['abs_log_dir'] = os.path.join(c['base_work_dir'], c.get('log_dir', 'logs'))
         self.abs_dirs = dirs
         return self.abs_dirs
 
     def dump_config(self, file_path=None, config=None,
-                    console_output=True, exit_on_finish=False):
+                    console_output=False, exit_on_finish=False):
         """Dump self.config to localconfig.json
         """
         config = config or self.config
         dirs = self.query_abs_dirs()
         if not file_path:
             file_path = os.path.join(dirs['abs_log_dir'], "localconfig.json")
         self.info("Dumping config to %s." % file_path)
         self.mkdir_p(os.path.dirname(file_path))
--- a/testing/mozharness/mozharness/mozilla/testing/testbase.py
+++ b/testing/mozharness/mozharness/mozilla/testing/testbase.py
@@ -296,18 +296,16 @@ You can set this by specifying --test-ur
 
         with self.opened(os.path.realpath(source)) as (fh, err):
             package_requirements = json.load(fh)
             if not package_requirements or err:
                 self.fatal("There was an error reading test package requirements from %s "
                            "requirements: `%s` - error: `%s`" % (source,
                                                                  package_requirements or 'None',
                                                                  err or 'No error'))
-        self.info("Using the following test package requirements:\n%s" %
-                  pprint.pformat(package_requirements))
         return package_requirements
 
     def _download_test_packages(self, suite_categories, extract_dirs):
         # Some platforms define more suite categories/names than others.
         # This is a difference in the convention of the configs more than
         # to how these tests are run, so we pave over these differences here.
         aliases = {
             'robocop': 'mochitest',