forked from firefox-devtools/profiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcpu.test.js
160 lines (138 loc) · 5.72 KB
/
cpu.test.js
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
/* 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/. */
// @flow
import { processThreadCPUDelta } from 'firefox-profiler/profile-logic/cpu';
import { getProfileWithThreadCPUDelta } from '../fixtures/profiles/processed-profile';
import type { ThreadCPUDeltaUnit, Milliseconds } from 'firefox-profiler/types';
const MS_TO_US_MULTIPLIER = 1000;
const MS_TO_NS_MULTIPLIER = 1000000;
describe('processThreadCPUDelta', function () {
function setup(
threadCPUDelta?: Array<number | null>,
unit: ThreadCPUDeltaUnit = 'ns',
interval: Milliseconds = 1
) {
const profile = getProfileWithThreadCPUDelta(
[threadCPUDelta],
unit,
interval
);
const [thread] = profile.threads;
if (!profile.meta.sampleUnits) {
throw new Error('SampleUnits object could not found in the profile.');
}
const processedThread = processThreadCPUDelta(
thread,
profile.meta.sampleUnits,
profile.meta.interval
);
return { profile, thread, processedThread };
}
it('throws if all of its values are null', function () {
expect(() => setup([null, null, null, null, null, null])).toThrow();
});
it('throws if there are no threadCPUDelta values', function () {
expect(() => setup(undefined)).toThrow();
});
it('removes the null values by finding the closest non-null threadCPUDelta value', function () {
// Testing the case where only the values in the middle are null.
const { processedThread: processedThread1 } = setup([
0.1,
null,
null,
null,
null,
0.2,
]);
expect(processedThread1.samples.threadCPUDelta).toEqual([
0.1, 0.1, 0.1, 0.2, 0.2, 0.2,
]);
// Testing the case where the values at the start are null.
const { processedThread: processedThread2 } = setup([null, null, 0.1]);
expect(processedThread2.samples.threadCPUDelta).toEqual([0.1, 0.1, 0.1]);
// Testing the case where the values at the end are null.
const { processedThread: processedThread3 } = setup([0.1, null, null]);
expect(processedThread3.samples.threadCPUDelta).toEqual([0.1, 0.1, 0.1]);
// If there are values in either side of a null sample with the same distance,
// pick the latter one.
const { processedThread: processedThread4 } = setup([0.1, null, 0.2]);
expect(processedThread4.samples.threadCPUDelta).toEqual([0.1, 0.2, 0.2]);
});
it('processes Linux timing values and caps them to 100% if they are more than the interval values', function () {
// Interval is in the ms values and Linux uses ns for threadCPUDelta values.
const intervalMs = 1;
const { processedThread: processedThread1 } = setup(
[
0.5 * MS_TO_NS_MULTIPLIER, // <- Less than the interval
0.7 * MS_TO_NS_MULTIPLIER, // <- Less than the interval
1 * MS_TO_NS_MULTIPLIER, // <- Equal to the interval, should be fine
1.2 * MS_TO_NS_MULTIPLIER, // <- More than the interval, should be capped to 100%
23 * MS_TO_NS_MULTIPLIER, // <- More than the interval, should be capped to 100%
],
'ns',
intervalMs
);
expect(processedThread1.samples.threadCPUDelta).toEqual([
0.5 * MS_TO_NS_MULTIPLIER, // <- not changed
0.7 * MS_TO_NS_MULTIPLIER, // <- not changed
1 * MS_TO_NS_MULTIPLIER, // <- not changed
1 * MS_TO_NS_MULTIPLIER, // <- capped to 100%
1 * MS_TO_NS_MULTIPLIER, // <- capped to 100%
]);
});
it('processes macOS timing values and caps them to 100% if they are more than the interval values', function () {
// Interval is in the ms values and macOS uses µs for threadCPUDelta values.
const intervalMs = 1;
const { processedThread: processedThread1 } = setup(
[
0.5 * MS_TO_US_MULTIPLIER, // <- Less than the interval
0.7 * MS_TO_US_MULTIPLIER, // <- Less than the interval
1 * MS_TO_US_MULTIPLIER, // <- Equal to the interval, should be fine
1.2 * MS_TO_US_MULTIPLIER, // <- More than the interval, should be capped to 100%
23 * MS_TO_US_MULTIPLIER, // <- More than the interval, should be capped to 100%
],
'µs',
intervalMs
);
expect(processedThread1.samples.threadCPUDelta).toEqual([
0.5 * MS_TO_US_MULTIPLIER, // <- not changed
0.7 * MS_TO_US_MULTIPLIER, // <- not changed
1 * MS_TO_US_MULTIPLIER, // <- not changed
1 * MS_TO_US_MULTIPLIER, // <- capped to 100%
1 * MS_TO_US_MULTIPLIER, // <- capped to 100%
]);
});
it('does not process the Windows values for 100% capping because they are not timing values', function () {
// Use the ns conversion multiplier to imitate the worst case.
const intervalMs = 1;
const threadCPUDelta = [
0.5 * MS_TO_NS_MULTIPLIER,
0.7 * MS_TO_NS_MULTIPLIER,
1 * MS_TO_NS_MULTIPLIER,
1.2 * MS_TO_NS_MULTIPLIER,
23 * MS_TO_NS_MULTIPLIER,
123123 * MS_TO_NS_MULTIPLIER,
];
const { processedThread: processedThread1 } = setup(
threadCPUDelta,
'variable CPU cycles',
intervalMs
);
// It shouldn't change the values!
expect(processedThread1.samples.threadCPUDelta).toEqual(threadCPUDelta);
});
it('processes the timing values and caps the first element correctly if it exceeds the interval', function () {
// Testing the case where only the values in the middle are null.
const interval = 1;
const { processedThread: processedThread1 } = setup(
[2 * MS_TO_NS_MULTIPLIER, 0.5 * MS_TO_NS_MULTIPLIER],
'ns',
interval
);
expect(processedThread1.samples.threadCPUDelta).toEqual([
interval * MS_TO_NS_MULTIPLIER,
0.5 * MS_TO_NS_MULTIPLIER,
]);
});
});