@@ -40,6 +40,12 @@ describe('Performance Monitoring > perf_logger', () => {
40
40
const TRACE_NAME = 'testTrace' ;
41
41
const START_TIME = 12345 ;
42
42
const DURATION = 321 ;
43
+ // Perf event header which is constant across tests in this file.
44
+ const WEBAPP_INFO = `"application_info":{"google_app_id":"${ APP_ID } ",\
45
+ "app_instance_id":"${ IID } ","web_app_info":{"sdk_version":"${ SDK_VERSION } ",\
46
+ "page_url":"${ PAGE_URL } ","service_worker_status":${ SERVICE_WORKER_STATUS } ,\
47
+ "visibility_state":${ VISIBILITY_STATE } ,"effective_connection_type":${ EFFECTIVE_CONNECTION_TYPE } },\
48
+ "application_process_state":0}` ;
43
49
44
50
let addToQueueStub : SinonStub <
45
51
Array < { message : string ; eventTime : number } > ,
@@ -69,7 +75,6 @@ describe('Performance Monitoring > perf_logger', () => {
69
75
stub ( Api . prototype , 'getUrl' ) . returns ( PAGE_URL ) ;
70
76
stub ( Api . prototype , 'getTimeOrigin' ) . returns ( TIME_ORIGIN ) ;
71
77
stub ( initializationService , 'isPerfInitialized' ) . returns ( true ) ;
72
- stub ( attributeUtils , 'getVisibilityState' ) . returns ( VISIBILITY_STATE ) ;
73
78
stub ( attributeUtils , 'getEffectiveConnectionType' ) . returns (
74
79
EFFECTIVE_CONNECTION_TYPE
75
80
) ;
@@ -83,17 +88,20 @@ describe('Performance Monitoring > perf_logger', () => {
83
88
} ) ;
84
89
85
90
describe ( 'logTrace' , ( ) => {
86
- it ( 'creates, serializes and sends a trace to cc service' , ( ) => {
87
- const EXPECTED_TRACE_MESSAGE = `{"application_info":{"google_app_id":" ${ APP_ID } ",\
88
- "app_instance_id":" ${ IID } ","web_app_info":{"sdk_version":" ${ SDK_VERSION } ",\
89
- "page_url":" ${ PAGE_URL } ","service_worker_status": ${ SERVICE_WORKER_STATUS } ,\
90
- "visibility_state": ${ VISIBILITY_STATE } ,"effective_connection_type": ${ EFFECTIVE_CONNECTION_TYPE } } ,\
91
- "application_process_state":0 },"trace_metric":{"name":" ${ TRACE_NAME } ","is_auto":false ,\
92
- "client_start_time_us": ${ START_TIME * 1000 } ,"duration_us": ${ DURATION * 1000 } }}` ;
91
+ it ( 'creates, serializes and sends a trace to transport service' , ( ) => {
92
+ const EXPECTED_TRACE_MESSAGE =
93
+ `{` +
94
+ WEBAPP_INFO +
95
+ `,"trace_metric":{"name":" ${ TRACE_NAME } ","is_auto":false ,\
96
+ "client_start_time_us": ${ START_TIME * 1000 } ,"duration_us": ${ DURATION * 1000 } ,\
97
+ "counters":{"counter1":3 },"custom_attributes":{"attr":"val" }}}` ;
93
98
getIidStub . returns ( IID ) ;
99
+ stub ( attributeUtils , 'getVisibilityState' ) . returns ( VISIBILITY_STATE ) ;
94
100
SettingsService . getInstance ( ) . loggingEnabled = true ;
95
101
SettingsService . getInstance ( ) . logTraceAfterSampling = true ;
96
102
const trace = new Trace ( TRACE_NAME ) ;
103
+ trace . putAttribute ( 'attr' , 'val' ) ;
104
+ trace . putMetric ( 'counter1' , 3 ) ;
97
105
trace . record ( START_TIME , DURATION ) ;
98
106
clock . tick ( 1 ) ;
99
107
@@ -105,16 +113,140 @@ describe('Performance Monitoring > perf_logger', () => {
105
113
106
114
it ( 'does not log an event if cookies are disabled in the browser' , ( ) => {
107
115
stub ( Api . prototype , 'requiredApisAvailable' ) . returns ( false ) ;
116
+ stub ( attributeUtils , 'getVisibilityState' ) . returns ( VISIBILITY_STATE ) ;
108
117
const trace = new Trace ( TRACE_NAME ) ;
109
118
trace . record ( START_TIME , DURATION ) ;
110
119
clock . tick ( 1 ) ;
111
120
112
121
expect ( addToQueueStub ) . not . to . be . called ;
113
122
} ) ;
123
+
124
+ it ( 'ascertains that the max number of customMetric allowed is 32' , ( ) => {
125
+ const EXPECTED_TRACE_MESSAGE =
126
+ `{` +
127
+ WEBAPP_INFO +
128
+ `,"trace_metric":{"name":"${ TRACE_NAME } ","is_auto":false,\
129
+ "client_start_time_us":${ START_TIME * 1000 } ,"duration_us":${ DURATION * 1000 } ,\
130
+ "counters":{"counter1":1,"counter2":2,"counter3":3,"counter4":4,"counter5":5,"counter6":6,\
131
+ "counter7":7,"counter8":8,"counter9":9,"counter10":10,"counter11":11,"counter12":12,\
132
+ "counter13":13,"counter14":14,"counter15":15,"counter16":16,"counter17":17,"counter18":18,\
133
+ "counter19":19,"counter20":20,"counter21":21,"counter22":22,"counter23":23,"counter24":24,\
134
+ "counter25":25,"counter26":26,"counter27":27,"counter28":28,"counter29":29,"counter30":30,\
135
+ "counter31":31,"counter32":32}}}` ;
136
+ getIidStub . returns ( IID ) ;
137
+ stub ( attributeUtils , 'getVisibilityState' ) . returns ( VISIBILITY_STATE ) ;
138
+ SettingsService . getInstance ( ) . loggingEnabled = true ;
139
+ SettingsService . getInstance ( ) . logTraceAfterSampling = true ;
140
+ const trace = new Trace ( TRACE_NAME ) ;
141
+ for ( let i = 1 ; i <= 32 ; i ++ ) {
142
+ trace . putMetric ( 'counter' + i , i ) ;
143
+ }
144
+ trace . record ( START_TIME , DURATION ) ;
145
+ clock . tick ( 1 ) ;
146
+
147
+ expect ( addToQueueStub ) . to . be . called ;
148
+ expect ( addToQueueStub . getCall ( 0 ) . args [ 0 ] . message ) . to . be . equal (
149
+ EXPECTED_TRACE_MESSAGE
150
+ ) ;
151
+ } ) ;
152
+
153
+ it ( 'ascertains that the max number of custom attributes allowed is 5' , ( ) => {
154
+ const EXPECTED_TRACE_MESSAGE =
155
+ `{` +
156
+ WEBAPP_INFO +
157
+ `,"trace_metric":{"name":"${ TRACE_NAME } ","is_auto":false,\
158
+ "client_start_time_us":${ START_TIME * 1000 } ,"duration_us":${ DURATION * 1000 } ,\
159
+ "custom_attributes":{"attr1":"val1","attr2":"val2","attr3":"val3","attr4":"val4","attr5":"val5"}}}` ;
160
+ getIidStub . returns ( IID ) ;
161
+ stub ( attributeUtils , 'getVisibilityState' ) . returns ( VISIBILITY_STATE ) ;
162
+ SettingsService . getInstance ( ) . loggingEnabled = true ;
163
+ SettingsService . getInstance ( ) . logTraceAfterSampling = true ;
164
+ const trace = new Trace ( TRACE_NAME ) ;
165
+ for ( let i = 1 ; i <= 5 ; i ++ ) {
166
+ trace . putAttribute ( 'attr' + i , 'val' + i ) ;
167
+ }
168
+ trace . record ( START_TIME , DURATION ) ;
169
+ clock . tick ( 1 ) ;
170
+
171
+ expect ( addToQueueStub ) . to . be . called ;
172
+ expect ( addToQueueStub . getCall ( 0 ) . args [ 0 ] . message ) . to . be . equal (
173
+ EXPECTED_TRACE_MESSAGE
174
+ ) ;
175
+ } ) ;
176
+ } ) ;
177
+
178
+ describe ( 'logPageLoadTrace' , ( ) => {
179
+ it ( 'creates, serializes and sends a page load trace to cc service' , ( ) => {
180
+ const flooredStartTime = Math . floor ( TIME_ORIGIN * 1000 ) ;
181
+ const EXPECTED_TRACE_MESSAGE = `{"application_info":{"google_app_id":"${ APP_ID } ",\
182
+ "app_instance_id":"${ IID } ","web_app_info":{"sdk_version":"${ SDK_VERSION } ",\
183
+ "page_url":"${ PAGE_URL } ","service_worker_status":${ SERVICE_WORKER_STATUS } ,\
184
+ "visibility_state":${
185
+ attributeUtils . VisibilityState . VISIBLE
186
+ } ,"effective_connection_type":${ EFFECTIVE_CONNECTION_TYPE } },\
187
+ "application_process_state":0},"trace_metric":{"name":"_wt_${ PAGE_URL } ","is_auto":true,\
188
+ "client_start_time_us":${ flooredStartTime } ,"duration_us":${ DURATION * 1000 } ,\
189
+ "counters":{"domInteractive":10000,"domContentLoadedEventEnd":20000,"loadEventEnd":10000,\
190
+ "_fp":40000,"_fcp":50000,"_fid":90000}}}` ;
191
+ getIidStub . returns ( IID ) ;
192
+ SettingsService . getInstance ( ) . loggingEnabled = true ;
193
+ SettingsService . getInstance ( ) . logTraceAfterSampling = true ;
194
+
195
+ stub ( attributeUtils , 'getVisibilityState' ) . returns (
196
+ attributeUtils . VisibilityState . VISIBLE
197
+ ) ;
198
+
199
+ const navigationTiming : PerformanceNavigationTiming = {
200
+ domComplete : 100 ,
201
+ domContentLoadedEventEnd : 20 ,
202
+ domContentLoadedEventStart : 10 ,
203
+ domInteractive : 10 ,
204
+ loadEventEnd : 10 ,
205
+ loadEventStart : 10 ,
206
+ redirectCount : 10 ,
207
+ type : 'navigate' ,
208
+ unloadEventEnd : 10 ,
209
+ unloadEventStart : 10 ,
210
+ duration : DURATION
211
+ } as PerformanceNavigationTiming ;
212
+
213
+ const navigationTimings : PerformanceNavigationTiming [ ] = [
214
+ navigationTiming
215
+ ] ;
216
+
217
+ const firstPaint : PerformanceEntry = {
218
+ name : 'first-paint' ,
219
+ startTime : 40 ,
220
+ duration : 100 ,
221
+ entryType : 'url' ,
222
+ toJSON ( ) { }
223
+ } ;
224
+
225
+ const firstContentfulPaint : PerformanceEntry = {
226
+ name : 'first-contentful-paint' ,
227
+ startTime : 50 ,
228
+ duration : 100 ,
229
+ entryType : 'url' ,
230
+ toJSON ( ) { }
231
+ } ;
232
+
233
+ const paintTimings : PerformanceEntry [ ] = [
234
+ firstPaint ,
235
+ firstContentfulPaint
236
+ ] ;
237
+
238
+ Trace . createOobTrace ( navigationTimings , paintTimings , 90 ) ;
239
+ clock . tick ( 1 ) ;
240
+
241
+ expect ( addToQueueStub ) . to . be . called ;
242
+ expect ( addToQueueStub . getCall ( 0 ) . args [ 0 ] . message ) . to . be . equal (
243
+ EXPECTED_TRACE_MESSAGE
244
+ ) ;
245
+ } ) ;
114
246
} ) ;
115
247
116
248
describe ( 'logNetworkRequest' , ( ) => {
117
- it ( 'creates, serializes and sends a network request to cc service' , ( ) => {
249
+ it ( 'creates, serializes and sends a network request to transport service' , ( ) => {
118
250
const RESOURCE_PERFORMANCE_ENTRY : PerformanceResourceTiming = {
119
251
connectEnd : 0 ,
120
252
connectStart : 0 ,
@@ -147,17 +279,17 @@ describe('Performance Monitoring > perf_logger', () => {
147
279
RESOURCE_PERFORMANCE_ENTRY . startTime ) *
148
280
1000
149
281
) ;
150
- const EXPECTED_NETWORK_MESSAGE = `{"application_info":{"google_app_id":"${ APP_ID } ",\
151
- "app_instance_id":"${ IID } ","web_app_info":{"sdk_version":"${ SDK_VERSION } ",\
152
- "page_url":"${ PAGE_URL } ","service_worker_status":${ SERVICE_WORKER_STATUS } ,\
153
- "visibility_state":${ VISIBILITY_STATE } ,"effective_connection_type":${ EFFECTIVE_CONNECTION_TYPE } },\
154
- "application_process_state":0},\
282
+ const EXPECTED_NETWORK_MESSAGE =
283
+ `{` +
284
+ WEBAPP_INFO +
285
+ `,\
155
286
"network_request_metric":{"url":"${ RESOURCE_PERFORMANCE_ENTRY . name } ",\
156
287
"http_method":0,"http_response_code":200,\
157
288
"response_payload_bytes":${ RESOURCE_PERFORMANCE_ENTRY . transferSize } ,\
158
289
"client_start_time_us":${ START_TIME } ,\
159
290
"time_to_response_completed_us":${ TIME_TO_RESPONSE_COMPLETED } }}` ;
160
291
getIidStub . returns ( IID ) ;
292
+ stub ( attributeUtils , 'getVisibilityState' ) . returns ( VISIBILITY_STATE ) ;
161
293
SettingsService . getInstance ( ) . loggingEnabled = true ;
162
294
SettingsService . getInstance ( ) . logNetworkAfterSampling = true ;
163
295
// Calls logNetworkRequest under the hood.
0 commit comments