Skip to content

Commit ae8f39b

Browse files
chore: measure API tweaks (#1488)
1 parent 531f8d4 commit ae8f39b

File tree

6 files changed

+286
-140
lines changed

6 files changed

+286
-140
lines changed

src/features/generic_events/aggregate/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,12 @@ export class Aggregate extends AggregateBase {
224224
const { start, duration, customAttributes } = args
225225

226226
const event = {
227-
...(agentRef.info.jsAttributes || {}),
228227
...customAttributes,
229228
eventType: 'BrowserPerformance',
230229
timestamp: Math.floor(agentRef.runtime.timeKeeper.correctRelativeTimestamp(start)),
231230
entryName: n,
232-
entryDuration: duration
231+
entryDuration: duration,
232+
entryType: 'measure'
233233
}
234234

235235
this.addEvent(event)

src/loaders/api/measure.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,16 @@ export function setupMeasureAPI (agent) {
2020
return
2121
}
2222

23+
/**
24+
* getValueFromTiming - Helper function to extract a numeric value from a supplied option.
25+
* @param {Number|PerformanceMark} [timing] The timing value
26+
* @param {Number} [d] The default value to return if timing is invalid
27+
* @returns {Number} The timing value or the default value
28+
*/
2329
const getValueFromTiming = (timing, d) => {
2430
if (timing == null) return d
2531
if (typeof timing === 'number') return timing
26-
if (typeof PerformanceMark === 'function' && timing instanceof PerformanceMark) return timing.startTime
32+
if (timing instanceof PerformanceMark) return timing.startTime
2733
return Number.NaN
2834
}
2935

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!DOCTYPE html>
2+
<!--
3+
Copyright 2020 New Relic Corporation.
4+
PDX-License-Identifier: Apache-2.0
5+
-->
6+
<html>
7+
<head>
8+
<title>RUM Unit Test</title>
9+
{init} {config} {loader}
10+
</head>
11+
<body>
12+
Instrumented
13+
<script>
14+
window.addEventListener("load", () => {
15+
const start = performance.mark("start");
16+
window.unexpectedErrors = [];
17+
18+
/** valid measures should return an object */
19+
if (!newrelic.measure("no-args")) window.unexpectedErrors.push("no-args");
20+
if (!newrelic.measure("start-only-number", { start: 0 })) window.unexpectedErrors.push("start-only-number");
21+
if (!newrelic.measure("end-only-number", { end: 2000 })) window.unexpectedErrors.push("end-only-number");
22+
if (!newrelic.measure("start-end-number", { start: 1000, end: 2000 })) window.unexpectedErrors.push("start-end-number");
23+
24+
if (!newrelic.measure("custom-attributes", { customAttributes: { foo: "bar" } }).customAttributes) window.unexpectedErrors.push("custom-attributes");
25+
26+
/** invalid measures should return undefined */
27+
if (!!newrelic.measure("invalid-start", { start: "invalid" })) window.unexpectedErrors.push("invalid-start");
28+
if (!!newrelic.measure("invalid-end", { end: "invalid" })) window.unexpectedErrors.push("invalid-end");
29+
if (!!newrelic.measure("invalid-duration-number", { start: 2000, end: 1000 })) window.unexpectedErrors.push("invalid-duration-number");
30+
31+
// performance marks
32+
setTimeout(() => {
33+
const end = performance.mark("end");
34+
35+
/** valid measures should return an object */
36+
if (!newrelic.measure("start-only-mark", { start })) window.unexpectedErrors.push("start-only-mark");
37+
if (!newrelic.measure("end-only-mark", { end })) window.unexpectedErrors.push("end-only-mark");
38+
if (!newrelic.measure("start-end-performance-marks", { start, end })) window.unexpectedErrors.push("start-end-performance-marks");
39+
if (!newrelic.measure("start-end-mixed", { start, end: 2000 })) window.unexpectedErrors.push("start-end-mixed");
40+
if (!newrelic.measure("start-end-mixed-2", { start: 1000, end })) window.unexpectedErrors.push("start-end-mixed-2");
41+
42+
/** invalid measures should return undefined */
43+
if (!!newrelic.measure("invalid-duration-marks", { start: end, end: start })) window.unexpectedErrors.push("invalid-duration-marks");
44+
}, 1000);
45+
});
46+
</script>
47+
</body>
48+
</html>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!DOCTYPE html>
2+
<!--
3+
Copyright 2020 New Relic Corporation.
4+
PDX-License-Identifier: Apache-2.0
5+
-->
6+
<html>
7+
<head>
8+
<title>RUM Unit Test</title>
9+
{init} {config} {loader}
10+
<script>
11+
const start = performance.mark("start");
12+
window.unexpectedErrors = [];
13+
14+
/** valid measures should return an object */
15+
if (!newrelic.measure("no-args")) window.unexpectedErrors.push("no-args");
16+
if (!newrelic.measure("start-only-number", { start: 1 })) window.unexpectedErrors.push("start-only-number");
17+
if (!newrelic.measure("end-only-number", { end: 2000 })) window.unexpectedErrors.push("end-only-number");
18+
if (!newrelic.measure("start-end-number", { start: 1000, end: 2000 })) window.unexpectedErrors.push("start-end-number");
19+
20+
if (!newrelic.measure("custom-attributes", { customAttributes: { foo: "bar" } }).customAttributes) window.unexpectedErrors.push("custom-attributes");
21+
22+
/** invalid measures should return undefined */
23+
if (!!newrelic.measure("invalid-start", { start: "invalid" })) window.unexpectedErrors.push("invalid-start");
24+
if (!!newrelic.measure("invalid-end", { end: "invalid" })) window.unexpectedErrors.push("invalid-end");
25+
if (!!newrelic.measure("invalid-duration-number", { start: 2000, end: 1000 })) window.unexpectedErrors.push("invalid-duration-number");
26+
27+
// performance marks
28+
setTimeout(() => {
29+
const end = performance.mark("end");
30+
31+
/** valid measures should return an object */
32+
if (!newrelic.measure("start-only-mark", { start })) window.unexpectedErrors.push("start-only-mark");
33+
if (!newrelic.measure("end-only-mark", { end })) window.unexpectedErrors.push("end-only-mark");
34+
if (!newrelic.measure("start-end-performance-marks", { start, end })) window.unexpectedErrors.push("start-end-performance-marks");
35+
if (!newrelic.measure("start-end-mixed", { start, end: 2000 })) window.unexpectedErrors.push("start-end-mixed");
36+
if (!newrelic.measure("start-end-mixed-2", { start: 1000, end })) window.unexpectedErrors.push("start-end-mixed-2");
37+
38+
/** invalid measures should return undefined */
39+
if (!!newrelic.measure("invalid-duration-marks", { start: end, end: start })) window.unexpectedErrors.push("invalid-duration-marks");
40+
}, 1000);
41+
42+
</script>
43+
</head>
44+
<body>Instrumented</body>
45+
</html>

tests/components/api.test.js

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,12 @@ describe('API tests', () => {
918918
})
919919

920920
describe('measure', () => {
921+
beforeAll(() => {
922+
global.PerformanceMark = function (name, options) {
923+
this.name = name
924+
this.startTime = options.startTime
925+
}
926+
})
921927
test('should create event emitter event for calls to API', () => {
922928
agent.measure('testMeasure')
923929

@@ -963,6 +969,134 @@ describe('API tests', () => {
963969
expect(console.debug).toHaveBeenCalledTimes(1)
964970
expect(console.debug).toHaveBeenCalledWith(expect.stringContaining('New Relic Warning: https://github.com/newrelic/newrelic-browser-agent/blob/main/docs/warning-codes.md#58'), undefined)
965971
})
972+
973+
describe('should create correct output', () => {
974+
let dummyMark
975+
beforeAll(() => {
976+
dummyMark = (name, startTime) => new PerformanceMark(name, { startTime })
977+
})
978+
test('no arguments', () => {
979+
jest.spyOn(global.performance, 'now').mockReturnValue(12345)
980+
981+
const measurements = agent.measure('testMeasure')
982+
expect(measurements).toEqual({
983+
start: 0,
984+
end: 12345,
985+
duration: 12345 - 0,
986+
customAttributes: {}
987+
})
988+
})
989+
990+
test('start - number, end undefined', () => {
991+
jest.spyOn(global.performance, 'now').mockReturnValue(12345)
992+
const measurements = agent.measure('testMeasure', { start: 1000 })
993+
expect(measurements).toEqual({
994+
start: 1000,
995+
end: 12345,
996+
duration: 12345 - 1000,
997+
customAttributes: {}
998+
})
999+
})
1000+
1001+
test('start - number, end - null', () => {
1002+
jest.spyOn(global.performance, 'now').mockReturnValue(12345)
1003+
const measurements = agent.measure('testMeasure', { start: 1000, end: null })
1004+
expect(measurements).toEqual({
1005+
start: 1000,
1006+
end: 12345,
1007+
duration: 12345 - 1000,
1008+
customAttributes: {}
1009+
})
1010+
})
1011+
1012+
test('start - PerformanceMark, end - undefined', () => {
1013+
jest.spyOn(global.performance, 'now').mockReturnValue(12345)
1014+
1015+
const measurements = agent.measure('testMeasure', { start: dummyMark('startMark', 1000) })
1016+
expect(measurements).toEqual({
1017+
start: 1000,
1018+
end: 12345,
1019+
duration: 12345 - 1000,
1020+
customAttributes: {}
1021+
})
1022+
})
1023+
1024+
test('start - undefined, end - number', () => {
1025+
const measurements = agent.measure('testMeasure', { end: 1000 })
1026+
expect(measurements).toEqual({
1027+
start: 0,
1028+
end: 1000,
1029+
duration: 1000 - 0,
1030+
customAttributes: {}
1031+
})
1032+
})
1033+
1034+
test('start - null, end - number', () => {
1035+
const measurements = agent.measure('testMeasure', { start: null, end: 1000 })
1036+
expect(measurements).toEqual({
1037+
start: 0,
1038+
end: 1000,
1039+
duration: 1000 - 0,
1040+
customAttributes: {}
1041+
})
1042+
})
1043+
1044+
test('start - undefined, end - PerformanceMark', () => {
1045+
const measurements = agent.measure('testMeasure', { end: dummyMark('endMark', 1000) })
1046+
expect(measurements).toEqual({
1047+
start: 0,
1048+
end: 1000,
1049+
duration: 1000 - 0,
1050+
customAttributes: {}
1051+
})
1052+
})
1053+
1054+
test('start - undefined, end - number', () => {
1055+
const measurements = agent.measure('testMeasure', { end: 1000 })
1056+
expect(measurements).toEqual({
1057+
start: 0,
1058+
end: 1000,
1059+
duration: 1000 - 0,
1060+
customAttributes: {}
1061+
})
1062+
})
1063+
1064+
test('start - PerformanceMark, end - PerformanceMark', () => {
1065+
const measurements = agent.measure('testMeasure', { start: dummyMark('startMark', 1000), end: dummyMark('endMark', 2000) })
1066+
expect(measurements).toEqual({
1067+
start: 1000,
1068+
end: 2000,
1069+
duration: 2000 - 1000,
1070+
customAttributes: {}
1071+
})
1072+
})
1073+
1074+
test('start - number, end - PerformanceMark', () => {
1075+
const measurements = agent.measure('testMeasure', { start: 1000, end: dummyMark('endMark', 2000) })
1076+
expect(measurements).toEqual({
1077+
start: 1000,
1078+
end: 2000,
1079+
duration: 2000 - 1000,
1080+
customAttributes: {}
1081+
})
1082+
})
1083+
1084+
test('start - PerformanceMark, end - number', () => {
1085+
const measurements = agent.measure('testMeasure', { start: dummyMark('startMark', 1000), end: 2000 })
1086+
expect(measurements).toEqual({
1087+
start: 1000,
1088+
end: 2000,
1089+
duration: 2000 - 1000,
1090+
customAttributes: {}
1091+
})
1092+
})
1093+
1094+
test('custom attributes', () => {
1095+
const measurements = agent.measure('testMeasure', { customAttributes: { foo: 'bar' } })
1096+
expect(measurements.customAttributes).toEqual({ foo: 'bar' }
1097+
)
1098+
})
1099+
})
9661100
})
9671101
})
9681102

0 commit comments

Comments
 (0)