Source code

Revision control

Other Tools

1
# This Source Code Form is subject to the terms of the Mozilla Public
2
# License, v. 2.0. If a copy of the MPL was not distributed with this
3
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5
import textwrap
6
7
from telemetry_harness.testcase import TelemetryTestCase
8
from telemetry_harness.ping_filters import (
9
MAIN_ENVIRONMENT_CHANGE_PING,
10
MAIN_SHUTDOWN_PING,
11
)
12
13
14
class TestSearchCounts(TelemetryTestCase):
15
"""Test for SEARCH_COUNTS across sessions."""
16
17
def get_default_search_engine(self):
18
"""Retrieve the identifier of the default search engine.
19
20
We found that it's required to initialize the search service before
21
attempting to retrieve the default search engine. Not calling init
22
would result in a JavaScript error (see bug 1543960 for more
23
information).
24
"""
25
26
script = """\
27
let [resolve] = arguments;
28
let searchService = Components.classes[
29
"@mozilla.org/browser/search-service;1"]
30
.getService(Components.interfaces.nsISearchService);
31
return searchService.init().then(function () {
32
resolve(searchService.defaultEngine.identifier);
33
});
34
"""
35
36
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
37
return self.marionette.execute_async_script(textwrap.dedent(script))
38
39
def setUp(self):
40
"""Set up the test case and store the identifier of the default
41
search engine, which is required for reading SEARCH_COUNTS from
42
keyed histograms in pings.
43
"""
44
super(TestSearchCounts, self).setUp()
45
self.search_engine = self.get_default_search_engine()
46
47
def test_search_counts(self):
48
"""Test for SEARCH_COUNTS across sessions."""
49
50
# Session S1, subsession 1:
51
# - Open browser
52
# - Open new tab
53
# - Perform search (awesome bar or search bar)
54
# - Restart browser in new session
55
56
self.search_in_new_tab("mozilla firefox")
57
58
ping1 = self.wait_for_ping(self.restart_browser, MAIN_SHUTDOWN_PING)
59
60
# Session S2, subsession 1:
61
# - Outcome 1
62
# - Received a main ping P1 for previous session
63
# - Ping base contents:
64
# - clientId should be set
65
# - sessionId should be set
66
# - subsessionId should be set
67
# - previousSessionId should not be set
68
# - previousSubsessionId should not be set
69
# - subSessionCounter should be 1
70
# - profileSubSessionCounter should be 1
71
# - reason should be "shutdown"
72
# - Other ping contents:
73
# - SEARCH_COUNTS values should match performed search action
74
75
client_id = ping1["clientId"]
76
self.assertIsValidUUID(client_id)
77
78
ping1_info = ping1["payload"]["info"]
79
self.assertEqual(ping1_info["reason"], "shutdown")
80
81
s1_session_id = ping1_info["sessionId"]
82
self.assertNotEqual(s1_session_id, "")
83
84
s1_s1_subsession_id = ping1_info["subsessionId"]
85
self.assertNotEqual(s1_s1_subsession_id, "")
86
87
self.assertIsNone(ping1_info["previousSessionId"])
88
self.assertIsNone(ping1_info["previousSubsessionId"])
89
self.assertEqual(ping1_info["subsessionCounter"], 1)
90
self.assertEqual(ping1_info["profileSubsessionCounter"], 1)
91
92
scalars1 = ping1["payload"]["processes"]["parent"]["scalars"]
93
self.assertNotIn(
94
"browser.engagement.window_open_event_count", scalars1
95
)
96
self.assertEqual(
97
scalars1["browser.engagement.tab_open_event_count"], 1
98
)
99
100
keyed_histograms1 = ping1["payload"]["keyedHistograms"]
101
search_counts1 = keyed_histograms1["SEARCH_COUNTS"][
102
"{}.urlbar".format(self.search_engine)
103
]
104
self.assertEqual(
105
search_counts1,
106
{
107
u"range": [1, 2],
108
u"bucket_count": 3,
109
u"histogram_type": 4,
110
u"values": {u"1": 0, u"0": 1},
111
u"sum": 1,
112
},
113
)
114
115
# - Install addon
116
# Session S2, subsession 2:
117
# - Outcome 2
118
# - Received a main ping P2 for previous subsession
119
# - Ping base contents:
120
# - clientId should be set to the same value
121
# - sessionId should be set to a new value
122
# - subsessionId should be set to a new value
123
# - previousSessionId should be set to P1s sessionId value
124
# - previousSubsessionId should be set to P1s subsessionId value
125
# - subSessionCounter should be 1
126
# - profileSubSessionCounter should be 2
127
# - reason should be "environment-change"
128
# - Other ping contents:
129
# - SEARCH_COUNTS values should not be in P2
130
# - Verify that there should be no listing for tab scalar as we started a new
131
# session
132
133
ping2 = self.wait_for_ping(
134
self.install_addon, MAIN_ENVIRONMENT_CHANGE_PING
135
)
136
137
self.assertEqual(ping2["clientId"], client_id)
138
139
ping2_info = ping2["payload"]["info"]
140
self.assertEqual(ping2_info["reason"], "environment-change")
141
142
s2_session_id = ping2_info["sessionId"]
143
self.assertNotEqual(s2_session_id, s1_session_id)
144
145
s2_s1_subsession_id = ping2_info["subsessionId"]
146
self.assertNotEqual(s2_s1_subsession_id, s1_s1_subsession_id)
147
148
self.assertEqual(ping2_info["previousSessionId"], s1_session_id)
149
self.assertEqual(
150
ping2_info["previousSubsessionId"], s1_s1_subsession_id
151
)
152
self.assertEqual(ping2_info["subsessionCounter"], 1)
153
self.assertEqual(ping2_info["profileSubsessionCounter"], 2)
154
155
scalars2 = ping2["payload"]["processes"]["parent"]["scalars"]
156
self.assertNotIn(
157
"browser.engagement.window_open_event_count", scalars2
158
)
159
self.assertNotIn("browser.engagement.tab_open_event_count", scalars2)
160
161
keyed_histograms2 = ping2["payload"]["keyedHistograms"]
162
self.assertNotIn("SEARCH_COUNTS", keyed_histograms2)
163
164
# - Perform Search
165
# - Restart Browser
166
167
self.search("mozilla telemetry")
168
self.search("python unittest")
169
self.search("python pytest")
170
171
ping3 = self.wait_for_ping(self.restart_browser, MAIN_SHUTDOWN_PING)
172
173
# Session S3, subsession 1:
174
# - Outcome 3
175
# - Received a main ping P3 for session 2, subsession 1
176
# - Ping base contents:
177
# - clientId should be set to the same value
178
# - sessionId should be set to P2s sessionId value
179
# - subsessionId should be set to a new value
180
# - previousSessionId should be set to P1s sessionId value
181
# - previousSubsessionId should be set to P2s subsessionId value
182
# - subSessionCounter should be 2
183
# - profileSubSessionCounter should be 3
184
# - reason should be "shutdown"
185
# - Other ping contents:
186
# - SEARCH_COUNTS values should be set per above search
187
188
self.assertEqual(ping3["clientId"], client_id)
189
190
ping3_info = ping3["payload"]["info"]
191
192
self.assertEqual(ping3_info["reason"], "shutdown")
193
194
self.assertEqual(ping3_info["sessionId"], s2_session_id)
195
196
s2_s2_subsession_id = ping3_info["subsessionId"]
197
self.assertNotEqual(s2_s2_subsession_id, s1_s1_subsession_id)
198
self.assertNotEqual(s2_s2_subsession_id, s2_s1_subsession_id)
199
200
self.assertEqual(ping3_info["previousSessionId"], s1_session_id)
201
self.assertEqual(
202
ping3_info["previousSubsessionId"], s2_s1_subsession_id
203
)
204
self.assertEqual(ping3_info["subsessionCounter"], 2)
205
self.assertEqual(ping3_info["profileSubsessionCounter"], 3)
206
207
scalars3 = ping3["payload"]["processes"]["parent"]["scalars"]
208
self.assertNotIn(
209
"browser.engagement.window_open_event_count", scalars3
210
)
211
self.assertNotIn("browser.engagement.tab_open_event_count", scalars3)
212
213
keyed_histograms3 = ping3["payload"]["keyedHistograms"]
214
search_counts3 = keyed_histograms3["SEARCH_COUNTS"][
215
"{}.urlbar".format(self.search_engine)
216
]
217
self.assertEqual(
218
search_counts3,
219
{
220
u"range": [1, 2],
221
u"bucket_count": 3,
222
u"histogram_type": 4,
223
u"values": {u"1": 0, u"0": 3},
224
u"sum": 3,
225
},
226
)