blob: 0bae84da503a7335ec718bb2fa3308884132143f [file] [log] [blame]
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {assertDefined} from 'common/assert_utils';
import {FunctionUtils} from 'common/function_utils';
import {TimestampConverterUtils} from 'test/unit/timestamp_converter_utils';
import {TracesBuilder} from 'test/unit/traces_builder';
import {TracesUtils} from 'test/unit/traces_utils';
import {TraceBuilder} from 'test/unit/trace_builder';
import {TraceUtils} from 'test/unit/trace_utils';
import {FrameMapBuilder} from './frame_map_builder';
import {AbsoluteFrameIndex} from './index_types';
import {Traces} from './traces';
import {TraceType} from './trace_type';
describe('Traces', () => {
let traces: Traces;
const time1 = TimestampConverterUtils.makeRealTimestamp(1n);
const time2 = TimestampConverterUtils.makeRealTimestamp(2n);
const time3 = TimestampConverterUtils.makeRealTimestamp(3n);
const time4 = TimestampConverterUtils.makeRealTimestamp(4n);
const time5 = TimestampConverterUtils.makeRealTimestamp(5n);
const time6 = TimestampConverterUtils.makeRealTimestamp(6n);
const time7 = TimestampConverterUtils.makeRealTimestamp(7n);
const time8 = TimestampConverterUtils.makeRealTimestamp(8n);
const time9 = TimestampConverterUtils.makeRealTimestamp(9n);
const time10 = TimestampConverterUtils.makeRealTimestamp(10n);
let extractedEntriesEmpty: Map<TraceType, Array<{}>>;
let extractedEntriesFull: Map<TraceType, Array<{}>>;
let extractedFramesEmpty: Map<AbsoluteFrameIndex, Map<TraceType, Array<{}>>>;
let extractedFramesFull: Map<AbsoluteFrameIndex, Map<TraceType, Array<{}>>>;
beforeAll(() => {
// Time: 1 2 3 4 5 6 7 8 9 10
//
// TEST_TRACE_STRING: 0 1--2 3 4
// \ \ \ \
// \ \ \ \
// TEST_TRACE_NUMBER: 0 1 2--3 4
// \ \ \ \
// \ \ \ \
// Frame on screen: 0 1 2 3---4
traces = new Traces();
traces.setTrace(
TraceType.TEST_TRACE_STRING,
new TraceBuilder<string>()
.setType(TraceType.TEST_TRACE_STRING)
.setEntries(['0', '1', '2', '3', '4'])
.setTimestamps([time1, time3, time4, time6, time9])
.setFrame(0, 0)
.setFrame(1, 1)
.setFrame(2, 1)
.setFrame(3, 2)
.setFrame(4, 3)
.setFrame(4, 4)
.build(),
);
traces.setTrace(
TraceType.TEST_TRACE_NUMBER,
new TraceBuilder<number>()
.setType(TraceType.TEST_TRACE_NUMBER)
.setEntries([0, 1, 2, 3, 4])
.setTimestamps([time2, time5, time7, time8, time10])
.setFrame(0, 0)
.setFrame(1, 1)
.setFrame(2, 2)
.setFrame(3, 2)
.setFrame(4, 3)
.setFrame(4, 4)
.build(),
);
extractedEntriesEmpty = new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, []],
[TraceType.TEST_TRACE_NUMBER, []],
]);
extractedEntriesFull = new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['0', '1', '2', '3', '4']],
[TraceType.TEST_TRACE_NUMBER, [0, 1, 2, 3, 4]],
]);
extractedFramesEmpty = new Map<
AbsoluteFrameIndex,
Map<TraceType, Array<{}>>
>();
extractedFramesFull = new Map<
AbsoluteFrameIndex,
Map<TraceType, Array<{}>>
>();
extractedFramesFull.set(
0,
new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['0']],
[TraceType.TEST_TRACE_NUMBER, [0]],
]),
);
extractedFramesFull.set(
1,
new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['1', '2']],
[TraceType.TEST_TRACE_NUMBER, [1]],
]),
);
extractedFramesFull.set(
2,
new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['3']],
[TraceType.TEST_TRACE_NUMBER, [2, 3]],
]),
);
extractedFramesFull.set(
3,
new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['4']],
[TraceType.TEST_TRACE_NUMBER, [4]],
]),
);
extractedFramesFull.set(
4,
new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['4']],
[TraceType.TEST_TRACE_NUMBER, [4]],
]),
);
});
it('getTrace()', async () => {
expect(
await TraceUtils.extractEntries(
assertDefined(traces.getTrace(TraceType.TEST_TRACE_STRING)),
),
).toEqual(
extractedEntriesFull.get(TraceType.TEST_TRACE_STRING) as string[],
);
expect(
await TraceUtils.extractEntries(
assertDefined(traces.getTrace(TraceType.TEST_TRACE_NUMBER)),
),
).toEqual(
extractedEntriesFull.get(TraceType.TEST_TRACE_NUMBER) as number[],
);
expect(traces.getTrace(TraceType.SURFACE_FLINGER)).toBeUndefined();
});
it('sliceTime()', async () => {
// empty
{
const slice = traces.sliceTime(time3, time3);
expect(await TracesUtils.extractEntries(slice)).toEqual(
extractedEntriesEmpty,
);
}
// full
{
const slice = traces.sliceTime();
expect(await TracesUtils.extractEntries(slice)).toEqual(
extractedEntriesFull,
);
}
// middle
{
const slice = traces.sliceTime(time4, time8);
expect(await TracesUtils.extractEntries(slice)).toEqual(
new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['2', '3']],
[TraceType.TEST_TRACE_NUMBER, [1, 2]],
]),
);
}
// slice away front
{
const slice = traces.sliceTime(time8);
expect(await TracesUtils.extractEntries(slice)).toEqual(
new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['4']],
[TraceType.TEST_TRACE_NUMBER, [3, 4]],
]),
);
}
// slice away back
{
const slice = traces.sliceTime(undefined, time8);
expect(await TracesUtils.extractEntries(slice)).toEqual(
new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['0', '1', '2', '3']],
[TraceType.TEST_TRACE_NUMBER, [0, 1, 2]],
]),
);
}
});
it('sliceFrames()', async () => {
// empty
{
const slice = traces.sliceFrames(1, 1);
expect(await TracesUtils.extractFrames(slice)).toEqual(
extractedFramesEmpty,
);
}
// full
{
const slice = traces.sliceFrames();
expect(await TracesUtils.extractFrames(slice)).toEqual(
extractedFramesFull,
);
}
// middle
{
const slice = traces.sliceFrames(1, 4);
const expectedFrames = structuredClone(extractedFramesFull);
expectedFrames.delete(0);
expectedFrames.delete(4);
expect(await TracesUtils.extractFrames(slice)).toEqual(expectedFrames);
}
// slice away front
{
const slice = traces.sliceFrames(2);
const expectedFrames = structuredClone(extractedFramesFull);
expectedFrames.delete(0);
expectedFrames.delete(1);
expect(await TracesUtils.extractFrames(slice)).toEqual(expectedFrames);
}
// slice away back
{
const slice = traces.sliceFrames(undefined, 2);
const expectedFrames = structuredClone(extractedFramesFull);
expectedFrames.delete(2);
expectedFrames.delete(3);
expectedFrames.delete(4);
expect(await TracesUtils.extractFrames(slice)).toEqual(expectedFrames);
}
});
it('mapTrace()', async () => {
const promises = traces.mapTrace(async (trace) => {
const expectedEntries = extractedEntriesFull.get(trace.type) as Array<{}>;
const actualEntries = await TraceUtils.extractEntries(trace);
expect(actualEntries).toEqual(expectedEntries);
});
await Promise.all(promises);
});
it('mapFrame()', async () => {
expect(await TracesUtils.extractFrames(traces)).toEqual(
extractedFramesFull,
);
});
it('it supports empty traces', async () => {
const traces = new TracesBuilder()
.setEntries(TraceType.TEST_TRACE_STRING, [])
.setFrameMap(
TraceType.TEST_TRACE_STRING,
new FrameMapBuilder(0, 0).build(),
)
.setEntries(TraceType.TEST_TRACE_NUMBER, [])
.setFrameMap(
TraceType.TEST_TRACE_NUMBER,
new FrameMapBuilder(0, 0).build(),
)
.build();
expect(await TracesUtils.extractEntries(traces)).toEqual(
extractedEntriesEmpty,
);
expect(await TracesUtils.extractFrames(traces)).toEqual(
extractedFramesEmpty,
);
expect(
await TracesUtils.extractEntries(traces.sliceTime(time1, time10)),
).toEqual(extractedEntriesEmpty);
expect(
await TracesUtils.extractFrames(traces.sliceTime(time1, time10)),
).toEqual(extractedFramesEmpty);
expect(await TracesUtils.extractEntries(traces.sliceFrames(0, 10))).toEqual(
extractedEntriesEmpty,
);
expect(await TracesUtils.extractFrames(traces.sliceFrames(0, 10))).toEqual(
extractedFramesEmpty,
);
});
it('it supports unavailable frame mapping', async () => {
const traces = new TracesBuilder()
.setEntries(TraceType.TEST_TRACE_STRING, ['entry-0'])
.setTimestamps(TraceType.TEST_TRACE_STRING, [time1])
.setFrameMap(TraceType.TEST_TRACE_STRING, undefined)
.setEntries(TraceType.TEST_TRACE_NUMBER, [0])
.setTimestamps(TraceType.TEST_TRACE_NUMBER, [time1])
.setFrameMap(TraceType.TEST_TRACE_NUMBER, undefined)
.build();
const expectedEntries = new Map<TraceType, Array<{}>>([
[TraceType.TEST_TRACE_STRING, ['entry-0']],
[TraceType.TEST_TRACE_NUMBER, [0]],
]);
expect(await TracesUtils.extractEntries(traces)).toEqual(expectedEntries);
expect(await TracesUtils.extractEntries(traces.sliceTime())).toEqual(
expectedEntries,
);
expect(() => {
traces.sliceFrames();
}).toThrow();
expect(() => {
traces.forEachFrame(FunctionUtils.DO_NOTHING);
}).toThrow();
expect(() => {
traces.mapFrame(FunctionUtils.DO_NOTHING);
}).toThrow();
});
});