Bug 1539874 - Develop an integration test for telemetry subsession management; r=chutten
authorRaphael Pierzina <rpierzina@mozilla.com>
Wed, 24 Apr 2019 20:44:27 +0000
changeset 530062 0c850ce605222bbcc4ff3ef4321fd0e7580f98f4
parent 530061 eaed19c250e9cb398a93c4cd4cbab9981d09d326
child 530063 feb8846c6602b5fb4a2580ee1f9155d2fb509585
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerschutten
bugs1539874
milestone68.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 1539874 - Develop an integration test for telemetry subsession management; r=chutten Differential Revision: https://phabricator.services.mozilla.com/D28726
toolkit/components/telemetry/tests/marionette/harness/telemetry_harness/testcase.py
toolkit/components/telemetry/tests/marionette/tests/client/manifest.ini
toolkit/components/telemetry/tests/marionette/tests/client/test_subsession_management.py
--- a/toolkit/components/telemetry/tests/marionette/harness/telemetry_harness/testcase.py
+++ b/toolkit/components/telemetry/tests/marionette/harness/telemetry_harness/testcase.py
@@ -30,16 +30,19 @@ class TelemetryTestCase(WindowManagerMix
         self.ping_server = PingServer(
             self.testvars["server_root"], self.testvars["server_url"]
         )
 
     def setUp(self, *args, **kwargs):
         """Set up the test case and start the ping server."""
         super(TelemetryTestCase, self).setUp(*args, **kwargs)
 
+        # Store IDs of addons installed via self.install_addon()
+        self.addon_ids = []
+
         with self.marionette.using_context(self.marionette.CONTEXT_CONTENT):
             self.marionette.navigate("about:about")
 
         self.ping_server.start()
 
     @contextlib.contextmanager
     def new_tab(self):
         """Perform operations in a new tab and then close the new tab."""
@@ -127,29 +130,30 @@ class TelemetryTestCase(WindowManagerMix
         [ping] = self.wait_for_pings(action_func, ping_filter, 1)
         return ping
 
     def restart_browser(self):
         """Restarts browser while maintaining the same profile."""
         return self.marionette.restart(clean=False, in_app=True)
 
     def install_addon(self):
-        """Install a minimal addon."""
+        """Install a minimal addon and add its ID to self.addon_ids."""
 
         resources_dir = os.path.join(os.path.dirname(__file__), "resources")
-
         addon_path = os.path.abspath(os.path.join(resources_dir, "helloworld"))
 
         try:
             addons = Addons(self.marionette)
-            addons.install(addon_path, temp=True)
+            addon_id = addons.install(addon_path, temp=True)
         except MarionetteException as e:
             self.fail(
                 "{} - Error installing addon: {} - ".format(e.cause, e.message)
             )
+        else:
+            self.addon_ids.append(addon_id)
 
     @property
     def client_id(self):
         """Return the ID of the current client."""
         with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
             return self.marionette.execute_script(
                 'Cu.import("resource://gre/modules/ClientID.jsm");'
                 "return ClientID.getCachedClientID();"
--- a/toolkit/components/telemetry/tests/marionette/tests/client/manifest.ini
+++ b/toolkit/components/telemetry/tests/marionette/tests/client/manifest.ini
@@ -1,5 +1,6 @@
 [DEFAULT]
 tags = client
 
 [test_main_tab_scalars.py]
-[test_search_counts_across_sessions.py]
\ No newline at end of file
+[test_search_counts_across_sessions.py]
+[test_subsession_management.py]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/tests/client/test_subsession_management.py
@@ -0,0 +1,147 @@
+# 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/.
+
+from telemetry_harness.testcase import TelemetryTestCase
+from telemetry_harness.ping_filters import (
+    MAIN_ENVIRONMENT_CHANGE_PING,
+    MAIN_SHUTDOWN_PING,
+)
+
+
+class TestSubsessionManagement(TelemetryTestCase):
+    """Tests for Firefox Telemetry subsession management."""
+
+    def test_subsession_management(self):
+        """Test for Firefox Telemetry subsession management."""
+
+        # Session S1, subsession 1
+        # Actions:
+        # 1. Open browser
+        # 2. Open a new tab
+        # 3. Restart browser in new session
+
+        with self.new_tab():
+            # If Firefox Telemetry is working correctly, this will
+            # be sufficient to record a tab open event.
+            pass
+
+        ping1 = self.wait_for_ping(self.restart_browser, MAIN_SHUTDOWN_PING)
+
+        # Session S2, subsession 1
+        # Outcome 1:
+        # Received a main ping P1 for previous session
+        # - Ping base contents:
+        #     - clientId should be a valid UUID
+        #     - reason should be "shutdown"
+        #     - sessionId should be set
+        #     - subsessionId should be set
+        #     - previousSessionId should not be set
+        #     - previousSubsessionId should not be set
+        #     - subSessionCounter should be 1
+        #     - profileSubSessionCounter should be 1
+        # - Other ping contents:
+        #     - tab_open_event_count in scalars
+
+        client_id = ping1["clientId"]
+        self.assertIsValidUUID(client_id)
+
+        ping1_info = ping1["payload"]["info"]
+        self.assertEqual(ping1_info["reason"], "shutdown")
+
+        s1_session_id = ping1_info["sessionId"]
+        self.assertNotEqual(s1_session_id, "")
+
+        s1_s1_subsession_id = ping1_info["subsessionId"]
+        self.assertNotEqual(s1_s1_subsession_id, "")
+        self.assertIsNone(ping1_info["previousSessionId"])
+        self.assertIsNone(ping1_info["previousSubsessionId"])
+        self.assertEqual(ping1_info["subsessionCounter"], 1)
+        self.assertEqual(ping1_info["profileSubsessionCounter"], 1)
+
+        scalars1 = ping1["payload"]["processes"]["parent"]["scalars"]
+        self.assertNotIn("browser.engagement.window_open_event_count", scalars1)
+        self.assertEqual(scalars1["browser.engagement.tab_open_event_count"], 1)
+
+        # Actions:
+        # 1. Install addon
+
+        ping2 = self.wait_for_ping(self.install_addon, MAIN_ENVIRONMENT_CHANGE_PING)
+
+        [addon_id] = self.addon_ids  # Store the addon ID for verifying ping3 later
+
+        # Session S2, subsession 2
+        # Outcome 2:
+        # Received a main ping P2 for previous subsession
+        # - Ping base contents:
+        #     - clientId should be set to the same value
+        #     - sessionId should be set to a new value
+        #     - subsessionId should be set to a new value
+        #     - previousSessionId should be set to P1s sessionId value
+        #     - previousSubsessionId should be set to P1s subsessionId value
+        #     - subSessionCounter should be 1
+        #     - profileSubSessionCounter should be 2
+        #     - reason should be "environment-change"
+        # - Other ping contents:
+        #     - tab_open_event_count not in scalars
+
+        self.assertEqual(ping2["clientId"], client_id)
+
+        ping2_info = ping2["payload"]["info"]
+        self.assertEqual(ping2_info["reason"], "environment-change")
+
+        s2_session_id = ping2_info["sessionId"]
+        self.assertNotEqual(s2_session_id, s1_session_id)
+
+        s2_s1_subsession_id = ping2_info["subsessionId"]
+        self.assertNotEqual(s2_s1_subsession_id, s1_s1_subsession_id)
+        self.assertEqual(ping2_info["previousSessionId"], s1_session_id)
+        self.assertEqual(ping2_info["previousSubsessionId"], s1_s1_subsession_id)
+        self.assertEqual(ping2_info["subsessionCounter"], 1)
+        self.assertEqual(ping2_info["profileSubsessionCounter"], 2)
+
+        scalars2 = ping2["payload"]["processes"]["parent"]["scalars"]
+        self.assertNotIn("browser.engagement.window_open_event_count", scalars2)
+        self.assertNotIn("browser.engagement.tab_open_event_count", scalars2)
+
+        # Actions
+        # 1. Restart browser in new session
+
+        ping3 = self.wait_for_ping(self.restart_browser, MAIN_SHUTDOWN_PING)
+
+        # Session S3, subsession 1
+        # Outcome 3:
+        # Received a main ping P3 for session 2, subsession 2
+        # - Ping base contents:
+        #     - clientId should be set to the same value
+        #     - sessionId should be set to P2s sessionId value
+        #     - subsessionId should be set to a new value
+        #     - previousSessionId should be set to P1s sessionId value
+        #     - previousSubsessionId should be set to P2s subsessionId value
+        #     - subSessionCounter should be 2
+        #     - profileSubSessionCounter should be 3
+        #     - reason should be "shutdown"
+        # - Other ping contents:
+        #     - addon ID in activeAddons in environment
+
+        self.assertEqual(ping3["clientId"], client_id)
+
+        ping3_info = ping3["payload"]["info"]
+        self.assertEqual(ping3_info["reason"], "shutdown")
+
+        self.assertEqual(ping3_info["sessionId"], s2_session_id)
+
+        s2_s2_subsession_id = ping3_info["subsessionId"]
+        self.assertNotEqual(s2_s2_subsession_id, s1_s1_subsession_id)
+        self.assertNotEqual(s2_s2_subsession_id, s2_s1_subsession_id)
+        self.assertEqual(ping3_info["previousSessionId"], s1_session_id)
+        self.assertEqual(ping3_info["previousSubsessionId"], s2_s1_subsession_id)
+        self.assertEqual(ping3_info["subsessionCounter"], 2)
+        self.assertEqual(ping3_info["profileSubsessionCounter"], 3)
+
+        scalars3 = ping3["payload"]["processes"]["parent"]["scalars"]
+        self.assertNotIn("browser.engagement.window_open_event_count", scalars3)
+        self.assertNotIn("browser.engagement.tab_open_event_count", scalars3)
+
+        active_addons = ping3["environment"]["addons"]["activeAddons"]
+        self.assertIn(addon_id, active_addons)