1// Copyright (C) 2019 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {dingus} from 'dingusjs';
16
17import {utf8Encode} from '../base/string_utils';
18import {perfetto} from '../gen/protos';
19
20import {AdbStream, MockAdb, MockAdbStream} from './adb_interfaces';
21import {AdbConsumerPort} from './adb_shell_controller';
22import {Consumer} from './record_controller_interfaces';
23
24function generateMockConsumer(): Consumer {
25  return {
26    onConsumerPortResponse: jest.fn(),
27    onError: jest.fn(),
28    onStatus: jest.fn()
29  };
30}
31const mainCallback = generateMockConsumer();
32const adbMock = new MockAdb();
33const adbController = new AdbConsumerPort(adbMock, mainCallback);
34const mockIntArray = new Uint8Array();
35
36const enableTracingRequest = new perfetto.protos.EnableTracingRequest();
37enableTracingRequest.traceConfig = new perfetto.protos.TraceConfig();
38const enableTracingRequestProto =
39    perfetto.protos.EnableTracingRequest.encode(enableTracingRequest).finish();
40
41
42test('handleCommand', async () => {
43  adbController.findDevice = () => {
44    return Promise.resolve(dingus<USBDevice>());
45  };
46
47  const enableTracing = jest.fn();
48  adbController.enableTracing = enableTracing;
49  await adbController.invoke('EnableTracing', mockIntArray);
50  expect(enableTracing).toHaveBeenCalledTimes(1);
51
52  const readBuffers = jest.fn();
53  adbController.readBuffers = readBuffers;
54  adbController.invoke('ReadBuffers', mockIntArray);
55  expect(readBuffers).toHaveBeenCalledTimes(1);
56
57  const sendErrorMessage = jest.fn();
58  adbController.sendErrorMessage = sendErrorMessage;
59  adbController.invoke('unknown', mockIntArray);
60  expect(sendErrorMessage).toBeCalledWith('Method not recognized: unknown');
61});
62
63test('enableTracing', async () => {
64  const mainCallback = generateMockConsumer();
65  const adbMock = new MockAdb();
66  const adbController = new AdbConsumerPort(adbMock, mainCallback);
67
68  adbController.sendErrorMessage =
69      jest.fn().mockImplementation(s => console.error(s));
70
71  const findDevice = jest.fn().mockImplementation(() => {
72    return Promise.resolve({} as unknown as USBDevice);
73  });
74  adbController.findDevice = findDevice;
75
76  const connectToDevice =
77      jest.fn().mockImplementation((_: USBDevice) => Promise.resolve());
78  adbMock.connect = connectToDevice;
79
80  const stream: AdbStream = new MockAdbStream();
81  const adbShell =
82      jest.fn().mockImplementation((_: string) => Promise.resolve(stream));
83  adbMock.shell = adbShell;
84
85
86  const sendMessage = jest.fn();
87  adbController.sendMessage = sendMessage;
88
89  adbController.generateStartTracingCommand = (_) => 'CMD';
90
91  await adbController.enableTracing(enableTracingRequestProto);
92  expect(adbShell).toBeCalledWith('CMD');
93  expect(sendMessage).toHaveBeenCalledTimes(0);
94
95
96  stream.onData(utf8Encode('starting tracing Wrote 123 bytes'));
97  stream.onClose();
98
99  expect(adbController.sendErrorMessage).toHaveBeenCalledTimes(0);
100  expect(sendMessage).toBeCalledWith({type: 'EnableTracingResponse'});
101});
102
103
104test('generateStartTracing', () => {
105  adbController.traceDestFile = 'DEST';
106  const testArray = new Uint8Array(1);
107  testArray[0] = 65;
108  const generatedCmd = adbController.generateStartTracingCommand(testArray);
109  expect(generatedCmd)
110      .toBe(`echo '${btoa('A')}' | base64 -d | perfetto -c - -o DEST`);
111});
112
113test('tracingEndedSuccessfully', () => {
114  expect(adbController.tracingEndedSuccessfully(
115             'Connected to the Perfetto traced service,\ starting tracing for \
11610000 ms\nWrote 564 bytes into /data/misc/perfetto-traces/trace'))
117      .toBe(true);
118  expect(adbController.tracingEndedSuccessfully(
119             'Connected to the Perfetto traced service, starting tracing for \
12010000 ms'))
121      .toBe(false);
122  expect(adbController.tracingEndedSuccessfully(
123             'Connected to the Perfetto traced service, starting tracing for \
1240 ms'))
125      .toBe(false);
126});
127