Source code

Revision control

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
# 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/.

import textwrap

from telemetry_harness.testcase import TelemetryTestCase
from telemetry_harness.ping_filters import (
    MAIN_ENVIRONMENT_CHANGE_PING,
    MAIN_SHUTDOWN_PING,
)


class TestSearchCounts(TelemetryTestCase):
    """Test for SEARCH_COUNTS across sessions."""

    def get_default_search_engine(self):
        """Retrieve the identifier of the default search engine."""

        script = """\
        let searchService = Components.classes[
                "@mozilla.org/browser/search-service;1"]
            .getService(Components.interfaces.nsISearchService);
        return searchService.defaultEngine.identifier;
        """

        with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
            return self.marionette.execute_script(textwrap.dedent(script))

    def setUp(self):
        """Set up the test case and store the identifier of the default
        search engine, which is required for reading SEARCH_COUNTS from
        keyed histograms in pings.
        """
        super(TestSearchCounts, self).setUp()
        self.search_engine = self.get_default_search_engine()

    def test_search_counts(self):
        """Test for SEARCH_COUNTS across sessions."""

        # Session S1, subsession 1:
        # - Open browser
        # - Open new tab
        # - Perform search (awesome bar or search bar)
        # - Restart browser in new session

        self.search_in_new_tab("mozilla firefox")

        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 set
        #     - 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
        #     - reason should be "shutdown"
        # - Other ping contents:
        #     - SEARCH_COUNTS values should match performed search action

        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
        )

        keyed_histograms1 = ping1["payload"]["keyedHistograms"]
        search_counts1 = keyed_histograms1["SEARCH_COUNTS"][
            "{}.urlbar".format(self.search_engine)
        ]
        self.assertEqual(
            search_counts1,
            {
                u"range": [1, 2],
                u"bucket_count": 3,
                u"histogram_type": 4,
                u"values": {u"1": 0, u"0": 1},
                u"sum": 1,
            },
        )

        # - Install addon
        # 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:
        #     - SEARCH_COUNTS values should not be in P2
        # - Verify that there should be no listing for tab scalar as we started a new
        # session

        ping2 = self.wait_for_ping(
            self.install_addon, MAIN_ENVIRONMENT_CHANGE_PING
        )

        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)

        keyed_histograms2 = ping2["payload"]["keyedHistograms"]
        self.assertNotIn("SEARCH_COUNTS", keyed_histograms2)

        # - Perform Search
        # - Restart Browser

        self.search("mozilla telemetry")
        self.search("python unittest")
        self.search("python pytest")

        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 1
        #   - 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:
        #     - SEARCH_COUNTS values should be set per above search

        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)

        keyed_histograms3 = ping3["payload"]["keyedHistograms"]
        search_counts3 = keyed_histograms3["SEARCH_COUNTS"][
            "{}.urlbar".format(self.search_engine)
        ]
        self.assertEqual(
            search_counts3,
            {
                u"range": [1, 2],
                u"bucket_count": 3,
                u"histogram_type": 4,
                u"values": {u"1": 0, u"0": 3},
                u"sum": 3,
            },
        )