1# Copyright 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#
15
16"""Unit tests for the AppRunner."""
17import os
18import sys
19from pathlib import Path
20
21from app_runner import AppRunner, AppRunnerListener
22from mock import Mock, call, patch
23
24# The path is "frameworks/base/startop/scripts/"
25sys.path.append(Path(os.path.realpath(__file__)).parents[2])
26import lib.cmd_utils as cmd_utils
27
28class AppRunnerTestListener(AppRunnerListener):
29  def preprocess(self) -> None:
30    cmd_utils.run_shell_command('pre'),
31
32  def postprocess(self, pre_launch_timestamp: str) -> None:
33    cmd_utils.run_shell_command('post'),
34
35  def metrics_selector(self, am_start_output: str,
36                       pre_launch_timestamp: str) -> None:
37    return 'TotalTime=123\n'
38
39RUNNER = AppRunner(package='music',
40                   activity='MainActivity',
41                   compiler_filter='speed',
42                   timeout=None,
43                   simulate=False)
44
45
46
47def test_configure_compiler_filter():
48  with patch('lib.cmd_utils.run_shell_command',
49             new_callable=Mock) as mock_run_shell_command:
50    mock_run_shell_command.return_value = (True, 'speed arm64 kUpToDate')
51
52    RUNNER.configure_compiler_filter()
53
54    calls = [call(os.path.realpath(
55        os.path.join(RUNNER.DIR,
56                     '../query_compiler_filter.py')) + ' --package music')]
57    mock_run_shell_command.assert_has_calls(calls)
58
59def test_parse_metrics_output():
60  input = 'a1=b1\nc1=d1\ne1=f1'
61  ret = RUNNER.parse_metrics_output(input)
62
63  assert ret == [('a1', 'b1'), ('c1', 'd1'), ('e1', 'f1')]
64
65def _mocked_run_shell_command(*args, **kwargs):
66  if args[0] == 'adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"':
67    return (True, "2019-07-02 23:20:06.972674825")
68  elif args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'':
69    return (True, '9999')
70  else:
71    return (True, 'a1=b1\nc1=d1=d2\ne1=f1')
72
73@patch('app_startup.lib.adb_utils.blocking_wait_for_logcat_displayed_time')
74@patch('lib.cmd_utils.run_shell_command')
75def test_run(mock_run_shell_command,
76             mock_blocking_wait_for_logcat_displayed_time):
77  mock_run_shell_command.side_effect = _mocked_run_shell_command
78  mock_blocking_wait_for_logcat_displayed_time.return_value = 123
79
80  test_listener = AppRunnerTestListener()
81  RUNNER.add_callbacks(test_listener)
82
83  result = RUNNER.run()
84
85  RUNNER.remove_callbacks(test_listener)
86
87  calls = [call('pre'),
88           call(os.path.realpath(
89               os.path.join(RUNNER.DIR,
90                            '../query_compiler_filter.py')) +
91                ' --package music'),
92           call('adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"'),
93           call(
94               'timeout {timeout} "{DIR}/launch_application" "{package}" "{activity}"'
95                 .format(timeout=30,
96                         DIR=os.path.realpath(os.path.dirname(RUNNER.DIR)),
97                         package='music',
98                         activity='MainActivity',
99                         timestamp='2019-07-02 23:20:06.972674825')),
100           call('post')
101           ]
102  mock_run_shell_command.assert_has_calls(calls)
103  assert result == [('TotalTime', '123')]
104  assert len(RUNNER.listeners) == 0