Bug 1458020 - 1b. Add forceGarbageCollection; r=me draft
authorJim Chen <nchen@mozilla.com>
Thu, 17 May 2018 19:41:13 -0400
changeset 796616 4ead055646c1ec792b042dc350ef82ef2aabf324
parent 796615 a9ce744c0141e6f174b87d136fa560f5529528f0
child 796617 a78b60c944304e8cfd1cc8b9bd5e0cdcfd2285ab
push id110315
push userbmo:nchen@mozilla.com
push dateThu, 17 May 2018 23:41:44 +0000
reviewersme
bugs1458020
milestone62.0a1
Bug 1458020 - 1b. Add forceGarbageCollection; r=me Add GeckoSessionTestRule.forceGarbageCollection() for improving the stability of resource-intensive tests, by garbage-collecting before running the test. MozReview-Commit-ID: A4ITTPsPNNy
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rdp/Memory.java
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rdp/Tab.java
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoSessionTestRuleTest.kt
@@ -1532,9 +1532,16 @@ class GeckoSessionTestRuleTest : BaseSes
 
         // A rejected Promise throws, but the wait should still count as a wait.
         sessionRule.session.forCallbacksDuringWait(object : Callbacks.ProgressDelegate {
             @AssertCalled(count = 0)
             override fun onPageStop(session: GeckoSession, success: Boolean) {
             }
         })
     }
+
+    @WithDevToolsAPI
+    @Test fun forceGarbageCollection() {
+        sessionRule.forceGarbageCollection()
+        sessionRule.session.reload()
+        sessionRule.session.waitForPageStop()
+    }
 }
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rdp/Memory.java
@@ -0,0 +1,23 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * 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/. */
+
+package org.mozilla.geckoview.test.rdp;
+
+/**
+ * Provide access to the memory API.
+ */
+public final class Memory extends Actor {
+    /* package */ Memory(final RDPConnection connection, final String name) {
+        super(connection, name);
+    }
+
+    public void forceCycleCollection() {
+        sendPacket("{\"type\":\"forceCycleCollection\"}", JSON_PARSER).get();
+    }
+
+    public void forceGarbageCollection() {
+        sendPacket("{\"type\":\"forceGarbageCollection\"}", JSON_PARSER).get();
+    }
+}
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rdp/Tab.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rdp/Tab.java
@@ -70,9 +70,20 @@ public final class Tab extends Actor {
      *
      * @return Promises object.
      */
     public Promises getPromises() {
         final String name = mTab.optString("promisesActor", null);
         final Actor promises = connection.getActor(name);
         return (promises != null) ? (Promises) promises : new Promises(connection, name);
     }
+
+    /**
+     * Get the memory object for access to the memory API.
+     *
+     * @return Memory object.
+     */
+    public Memory getMemory() {
+        final String name = mTab.optString("memoryActor", null);
+        final Actor memory = connection.getActor(name);
+        return (memory != null) ? (Memory) memory : new Memory(connection, name);
+    }
 }
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
@@ -1832,23 +1832,26 @@ public class GeckoSessionTestRule extend
      * @param js JavaScript expression.
      * @return Result of evaluating the expression.
      * @see #evaluateJS
      * @see #waitForChromeJS
      */
     public Object evaluateChromeJS(final @NonNull String js) {
         assertThat("Must enable RDP using @WithDevToolsAPI",
                    mWithDevTools, equalTo(true));
+        ensureChromeProcess();
+        return evaluateJS(mRDPChromeProcess, js);
+    }
 
+    private void ensureChromeProcess() {
         if (mRDPChromeProcess == null) {
             mRDPChromeProcess = sRDPConnection.getChromeProcess();
             assertThat("Should have chrome process object",
                        mRDPChromeProcess, notNullValue());
         }
-        return evaluateJS(mRDPChromeProcess, js);
     }
 
     private Object evaluateJS(final @NonNull Tab tab, final @NonNull String js) {
         final Actor.Reply<Object> reply = tab.getConsole().evaluateJS(js);
         while (!reply.hasResult()) {
             loopUntilIdle(mTimeoutMillis);
         }
 
@@ -1964,9 +1967,21 @@ public class GeckoSessionTestRule extend
      * @param prefs Map of pref names to values.
      * @see #setPrefsUntilTestEnd
      */
     public void setPrefsDuringNextWait(final @NonNull Map<String, ?> prefs) {
         assertThat("Must enable RDP using @WithDevToolsAPI",
                    mWithDevTools, equalTo(true));
         mWaitScopeDelegates.setPrefs(prefs);
     }
+
+    /**
+     * Force cycle/garbage collection in the content to clean up previous resources. RDP must
+     * be enabled first using the {@link WithDevToolsAPI} annotation.
+     */
+    public void forceGarbageCollection() {
+        assertThat("Must enable RDP using @WithDevToolsAPI",
+                   mWithDevTools, equalTo(true));
+        ensureChromeProcess();
+        mRDPChromeProcess.getMemory().forceCycleCollection();
+        mRDPChromeProcess.getMemory().forceGarbageCollection();
+    }
 }