• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2025 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import {
18  AdbDeviceConnectionListener,
19  AdbDeviceState,
20} from 'trace_collection/adb/adb_device_connection';
21import {MockAdbDeviceConnection} from 'trace_collection/mock/mock_adb_device_connection';
22import {AdbFileIdentifier, TraceTarget} from 'trace_collection/trace_target';
23import {TracingSession} from './tracing_session';
24import {WINSCOPE_BACKUP_DIR} from './winscope_backup_dir';
25
26describe('TracingSession', () => {
27  const listener: AdbDeviceConnectionListener = {
28    onError: jasmine.createSpy(),
29    onConnectionStateChange: jasmine.createSpy(),
30    onAvailableTracesChange: jasmine.createSpy(),
31  };
32  const mockDevice = new MockAdbDeviceConnection(
33    '35562',
34    'Pixel 6',
35    AdbDeviceState.AVAILABLE,
36    listener,
37  );
38  const fileIdentifiers = [
39    new AdbFileIdentifier('test path 1', ['matcher'], 'saved file 1'),
40    new AdbFileIdentifier('test path 2', ['matcher'], 'saved file 2'),
41  ];
42  const sessionName = 'TestSession';
43  const stopCmd = 'test stop cmd';
44  const startCmd = 'test start cmd';
45  const setupCmds = ['setup1', 'setup2'];
46  let session: TracingSession;
47  let target: TraceTarget;
48  let startTraceSpy: jasmine.Spy;
49  let endTraceSpy: jasmine.Spy;
50  let moveFilesSpy: jasmine.Spy;
51  let runShellCmdSpy: jasmine.Spy;
52  let findFilesSpy: jasmine.Spy;
53
54  beforeEach(() => {
55    target = new TraceTarget(
56      sessionName,
57      setupCmds,
58      startCmd,
59      stopCmd,
60      fileIdentifiers,
61    );
62    session = new TracingSession(target);
63    startTraceSpy = spyOn(mockDevice, 'startTrace');
64    endTraceSpy = spyOn(mockDevice, 'endTrace');
65    runShellCmdSpy = spyOn(mockDevice, 'runShellCommand');
66    findFilesSpy = spyOn(mockDevice, 'findFiles').and.returnValue(
67      Promise.resolve(['file']),
68    );
69    moveFilesSpy = spyOn(session, 'moveFiles').and.callThrough();
70  });
71
72  it('starts traces', async () => {
73    await session.start(mockDevice);
74    expect(runShellCmdSpy.calls.allArgs()).toEqual([['setup1'], ['setup2']]);
75    expect(startTraceSpy).toHaveBeenCalledOnceWith(target);
76  });
77
78  it('stops traces and moves files', async () => {
79    await session.stop(mockDevice);
80    checkTraceStopSpies(0);
81    await session.start(mockDevice);
82    await session.stop(mockDevice);
83    checkTraceStopSpies(1, [target]);
84  });
85
86  it('stops traces on destroy', async () => {
87    await session.onDestroy(mockDevice);
88    checkTraceStopSpies(0);
89    await session.start(mockDevice);
90    checkTraceStopSpies(0);
91    await session.onDestroy(mockDevice);
92    checkTraceStopSpies(1);
93  });
94
95  it('dumps states', async () => {
96    await session.dump(mockDevice);
97    expect(runShellCmdSpy.calls.allArgs()).toEqual([
98      ['setup1'],
99      ['setup2'],
100      [startCmd],
101    ]);
102  });
103
104  it('moves files', async () => {
105    await session.moveFiles(mockDevice);
106    expect(findFilesSpy.calls.allArgs()).toEqual([
107      ['test path 1', ['matcher']],
108      ['test path 2', ['matcher']],
109    ]);
110    expect(runShellCmdSpy.calls.allArgs()).toEqual([
111      [
112        `su root [ ! -f file ] || su root mv file ${WINSCOPE_BACKUP_DIR}saved file 1`,
113      ],
114      [
115        `su root [ ! -f file ] || su root mv file ${WINSCOPE_BACKUP_DIR}saved file 2`,
116      ],
117    ]);
118  });
119
120  it('handles error in move command', async () => {
121    runShellCmdSpy
122      .withArgs(
123        `su root [ ! -f file ] || su root mv file ${WINSCOPE_BACKUP_DIR}saved file 1`,
124      )
125      .and.throwError(new Error());
126    await expectAsync(session.moveFiles(mockDevice)).toBeResolved();
127  });
128
129  function checkTraceStopSpies(times: number, endArgs?: TraceTarget[]) {
130    expect(endTraceSpy).toHaveBeenCalledTimes(times);
131    expect(moveFilesSpy).toHaveBeenCalledTimes(times);
132    if (endArgs) {
133      expect(endTraceSpy).toHaveBeenCalledWith(...endArgs);
134    }
135  }
136});
137