test_AboutWelcomeTelemetry_glean.js (7472B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ 3 */ 4 5 "use strict"; 6 7 const { AboutWelcomeTelemetry } = ChromeUtils.importESModule( 8 "resource:///modules/aboutwelcome/AboutWelcomeTelemetry.sys.mjs" 9 ); 10 const TELEMETRY_PREF = "browser.newtabpage.activity-stream.telemetry"; 11 12 add_setup(function setup() { 13 do_get_profile(); 14 Services.fog.initializeFOG(); 15 }); 16 17 // We recognize two kinds of unexpected data that might reach 18 // `submitGleanPingForPing`: unknown keys, and keys with unexpectedly-complex 19 // data (ie, non-scalar). 20 // We report the keys in special metrics to aid in system health monitoring. 21 add_task(function test_weird_data() { 22 registerCleanupFunction(() => { 23 Services.prefs.clearUserPref(TELEMETRY_PREF); 24 }); 25 Services.prefs.setBoolPref(TELEMETRY_PREF, true); 26 27 const AWTelemetry = new AboutWelcomeTelemetry(); 28 29 const unknownKey = "some_unknown_key"; 30 const camelUnknownKey = AWTelemetry._snakeToCamelCase(unknownKey); 31 32 let pingSubmitted = false; 33 GleanPings.messagingSystem.testBeforeNextSubmit(() => { 34 pingSubmitted = true; 35 Assert.equal( 36 Glean.messagingSystem.unknownKeys[camelUnknownKey].testGetValue(), 37 1, 38 "caught the unknown key" 39 ); 40 // TODO(bug 1600008): Also check the for-testing overall count. 41 Assert.equal(Glean.messagingSystem.unknownKeyCount.testGetValue(), 1); 42 }); 43 AWTelemetry.submitGleanPingForPing({ 44 [unknownKey]: "value doesn't matter", 45 }); 46 47 Assert.ok(pingSubmitted, "Ping with unknown keys was submitted"); 48 49 const invalidNestedDataKey = "event"; 50 pingSubmitted = false; 51 GleanPings.messagingSystem.testBeforeNextSubmit(() => { 52 pingSubmitted = true; 53 Assert.equal( 54 Glean.messagingSystem.invalidNestedData[ 55 invalidNestedDataKey 56 ].testGetValue("messaging-system"), 57 1, 58 "caught the invalid nested data" 59 ); 60 }); 61 AWTelemetry.submitGleanPingForPing({ 62 [invalidNestedDataKey]: { this_should: "not be", complex: "data" }, 63 }); 64 65 Assert.ok(pingSubmitted, "Ping with invalid nested data submitted"); 66 }); 67 68 // `event_context` is weird. It's an object, but it might have been stringified 69 // before being provided for recording. 70 add_task(function test_event_context() { 71 registerCleanupFunction(() => { 72 Services.prefs.clearUserPref(TELEMETRY_PREF); 73 }); 74 Services.prefs.setBoolPref(TELEMETRY_PREF, true); 75 76 const AWTelemetry = new AboutWelcomeTelemetry(); 77 78 const eventContext = { 79 reason: "reason", 80 page: "page", 81 source: "source", 82 something_else: "not specifically handled", 83 screen_family: "family", 84 screen_id: "screen_id", 85 screen_index: 0, 86 screen_initlals: "screen_initials", 87 }; 88 const stringifiedEC = JSON.stringify(eventContext); 89 90 let pingSubmitted = false; 91 GleanPings.messagingSystem.testBeforeNextSubmit(() => { 92 pingSubmitted = true; 93 Assert.equal( 94 Glean.messagingSystem.eventReason.testGetValue(), 95 eventContext.reason, 96 "event_context.reason also in own metric." 97 ); 98 Assert.equal( 99 Glean.messagingSystem.eventPage.testGetValue(), 100 eventContext.page, 101 "event_context.page also in own metric." 102 ); 103 Assert.equal( 104 Glean.messagingSystem.eventSource.testGetValue(), 105 eventContext.source, 106 "event_context.source also in own metric." 107 ); 108 Assert.equal( 109 Glean.messagingSystem.eventScreenFamily.testGetValue(), 110 eventContext.screen_family, 111 "event_context.screen_family also in own metric." 112 ); 113 Assert.equal( 114 Glean.messagingSystem.eventScreenId.testGetValue(), 115 eventContext.screen_id, 116 "event_context.screen_id also in own metric." 117 ); 118 Assert.equal( 119 Glean.messagingSystem.eventScreenIndex.testGetValue(), 120 eventContext.screen_index, 121 "event_context.screen_index also in own metric." 122 ); 123 Assert.equal( 124 Glean.messagingSystem.eventScreenInitials.testGetValue(), 125 eventContext.screen_initials, 126 "event_context.screen_initials also in own metric." 127 ); 128 129 Assert.equal( 130 Glean.messagingSystem.eventContext.testGetValue(), 131 stringifiedEC, 132 "whole event_context added as text." 133 ); 134 }); 135 AWTelemetry.submitGleanPingForPing({ 136 event_context: eventContext, 137 }); 138 Assert.ok(pingSubmitted, "Ping with object event_context submitted"); 139 140 pingSubmitted = false; 141 GleanPings.messagingSystem.testBeforeNextSubmit(() => { 142 pingSubmitted = true; 143 Assert.equal( 144 Glean.messagingSystem.eventReason.testGetValue(), 145 eventContext.reason, 146 "event_context.reason also in own metric." 147 ); 148 Assert.equal( 149 Glean.messagingSystem.eventPage.testGetValue(), 150 eventContext.page, 151 "event_context.page also in own metric." 152 ); 153 Assert.equal( 154 Glean.messagingSystem.eventSource.testGetValue(), 155 eventContext.source, 156 "event_context.source also in own metric." 157 ); 158 Assert.equal( 159 Glean.messagingSystem.eventScreenFamily.testGetValue(), 160 eventContext.screen_family, 161 "event_context.screen_family also in own metric." 162 ); 163 Assert.equal( 164 Glean.messagingSystem.eventScreenId.testGetValue(), 165 eventContext.screen_id, 166 "event_context.screen_id also in own metric." 167 ); 168 Assert.equal( 169 Glean.messagingSystem.eventScreenIndex.testGetValue(), 170 eventContext.screen_index, 171 "event_context.screen_index also in own metric." 172 ); 173 Assert.equal( 174 Glean.messagingSystem.eventScreenInitials.testGetValue(), 175 eventContext.screen_initials, 176 "event_context.screen_initials also in own metric." 177 ); 178 179 Assert.equal( 180 Glean.messagingSystem.eventContext.testGetValue(), 181 stringifiedEC, 182 "whole event_context added as text." 183 ); 184 }); 185 AWTelemetry.submitGleanPingForPing({ 186 event_context: stringifiedEC, 187 }); 188 Assert.ok(pingSubmitted, "Ping with string event_context submitted"); 189 }); 190 191 // For event_context to be more useful, we want to make sure we don't error 192 // in cases where it doesn't make much sense, such as a plain string that 193 // doesnt attempt to represent a valid object. 194 add_task(function test_context_errors() { 195 registerCleanupFunction(() => { 196 Services.prefs.clearUserPref(TELEMETRY_PREF); 197 }); 198 Services.prefs.setBoolPref(TELEMETRY_PREF, true); 199 200 const AWTelemetry = new AboutWelcomeTelemetry(); 201 202 let weird_context_ping = { 203 event_context: "oops, this string isn't a valid JS object!", 204 }; 205 206 let pingSubmitted = false; 207 GleanPings.messagingSystem.testBeforeNextSubmit(() => { 208 pingSubmitted = true; 209 Assert.equal( 210 Glean.messagingSystem.eventContextParseError.testGetValue(), 211 undefined, 212 "this poorly formed context shouldn't register because it was not an object!" 213 ); 214 }); 215 216 AWTelemetry.submitGleanPingForPing(weird_context_ping); 217 218 Assert.ok(pingSubmitted, "Ping with unknown keys was submitted"); 219 220 weird_context_ping = { 221 event_context: 222 "{oops : {'this string isn't a valid JS object, but it sure looks like one!}}'", 223 }; 224 225 pingSubmitted = false; 226 GleanPings.messagingSystem.testBeforeNextSubmit(() => { 227 pingSubmitted = true; 228 Assert.equal( 229 Glean.messagingSystem.eventContextParseError.testGetValue(), 230 1, 231 "this poorly formed context should register because it was not an object!" 232 ); 233 }); 234 235 AWTelemetry.submitGleanPingForPing(weird_context_ping); 236 237 Assert.ok(pingSubmitted, "Ping with unknown keys was submitted"); 238 });