xref: /aosp_15_r20/system/extras/torq/tests/validate_simpleperf_unit_test.py (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1#
2# Copyright (C) 2024 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 builtins
18import unittest
19import sys
20import os
21import subprocess
22from unittest import mock
23from torq import create_parser, verify_args
24
25TORQ_TEMP_DIR = "/tmp/.torq"
26ANDROID_BUILD_TOP = "/folder"
27ANDROID_PRODUCT_OUT = "/folder/out/product/seahawk"
28SYMBOLS_PATH = "/folder/symbols"
29
30
31class ValidateSimpleperfUnitTest(unittest.TestCase):
32
33  def set_up_parser(self, command_string):
34    parser = create_parser()
35    sys.argv = command_string.split()
36    return parser
37
38  @mock.patch.object(os.path, "exists", autospec=True)
39  @mock.patch.object(os.path, "isdir", autospec=True)
40  @mock.patch.dict(os.environ, {"ANDROID_BUILD_TOP": ANDROID_BUILD_TOP,
41                                "ANDROID_PRODUCT_OUT": ANDROID_PRODUCT_OUT},
42                   clear=True)
43  def test_create_parser_valid_symbols(self, mock_isdir, mock_exists):
44    mock_isdir.return_value = True
45    mock_exists.return_value = True
46    parser = self.set_up_parser("torq.py -p simpleperf "
47                                "--symbols %s" % SYMBOLS_PATH)
48
49    args = parser.parse_args()
50    args, error = verify_args(args)
51
52    self.assertEqual(error, None)
53    self.assertEqual(args.symbols, SYMBOLS_PATH)
54    self.assertEqual(args.scripts_path, "%s/system/extras/simpleperf/scripts"
55                     % ANDROID_BUILD_TOP)
56
57  @mock.patch.object(os.path, "exists", autospec=True)
58  @mock.patch.object(os.path, "isdir", autospec=True)
59  @mock.patch.dict(os.environ, {"ANDROID_BUILD_TOP": ANDROID_BUILD_TOP,
60                                "ANDROID_PRODUCT_OUT": ANDROID_PRODUCT_OUT},
61                   clear=True)
62  def test_create_parser_valid_android_product_out_no_symbols(self,
63      mock_isdir, mock_exists):
64    mock_isdir.return_value = True
65    mock_exists.return_value = True
66    parser = self.set_up_parser("torq.py -p simpleperf")
67
68    args = parser.parse_args()
69    args, error = verify_args(args)
70
71    self.assertEqual(error, None)
72    self.assertEqual(args.symbols, ANDROID_PRODUCT_OUT)
73    self.assertEqual(args.scripts_path, "%s/system/extras/simpleperf/scripts"
74                     % ANDROID_BUILD_TOP)
75
76  @mock.patch.dict(os.environ, {"ANDROID_PRODUCT_OUT": ANDROID_PRODUCT_OUT},
77                   clear=True)
78  @mock.patch.object(os.path, "exists", autospec=True)
79  @mock.patch.object(os.path, "isdir", autospec=True)
80  def test_create_parser_invalid_android_product_no_symbols(self,
81      mock_isdir, mock_exists):
82    mock_isdir.return_value = False
83    mock_exists.return_value = False
84    parser = self.set_up_parser("torq.py -p simpleperf")
85
86    args = parser.parse_args()
87    args, error = verify_args(args)
88
89    self.assertEqual(error.message, ("%s is not a valid $ANDROID_PRODUCT_OUT."
90                                     % ANDROID_PRODUCT_OUT))
91    self.assertEqual(error.suggestion, "Set --symbols to a valid symbols lib "
92                                       "path or set $ANDROID_PRODUCT_OUT to "
93                                       "your android product out directory "
94                                       "(<ANDROID_BUILD_TOP>/out/target/product"
95                                       "/<TARGET>).")
96
97  @mock.patch.dict(os.environ, {},
98                   clear=True)
99  @mock.patch.object(os.path, "exists", autospec=True)
100  @mock.patch.object(os.path, "isdir", autospec=True)
101  def test_create_parser_invalid_symbols_no_android_product_out(self,
102      mock_isdir, mock_exists):
103    mock_isdir.return_value = False
104    mock_exists.return_value = False
105    parser = self.set_up_parser("torq.py -p simpleperf "
106                                "--symbols %s" % SYMBOLS_PATH)
107
108    args = parser.parse_args()
109    args, error = verify_args(args)
110
111    self.assertEqual(error.message, ("%s is not a valid path." % SYMBOLS_PATH))
112    self.assertEqual(error.suggestion, "Set --symbols to a valid symbols lib "
113                                       "path or set $ANDROID_PRODUCT_OUT to "
114                                       "your android product out directory "
115                                       "(<ANDROID_BUILD_TOP>/out/target/product"
116                                       "/<TARGET>).")
117
118  @mock.patch.dict(os.environ, {}, clear=True)
119  @mock.patch.object(os.path, "exists", autospec=True)
120  @mock.patch.object(os.path, "isdir", autospec=True)
121  def test_create_parser_no_android_product_out_no_symbols(self, mock_isdir,
122      mock_exists):
123    mock_isdir.return_value = False
124    mock_exists.return_value = False
125    parser = self.set_up_parser("torq.py -p simpleperf")
126
127    args = parser.parse_args()
128    args, error = verify_args(args)
129
130    self.assertEqual(error.message, "ANDROID_PRODUCT_OUT is not set.")
131    self.assertEqual(error.suggestion, "Set --symbols to a valid symbols lib "
132                                       "path or set $ANDROID_PRODUCT_OUT to "
133                                       "your android product out directory "
134                                       "(<ANDROID_BUILD_TOP>/out/target/"
135                                       "product/<TARGET>).")
136
137  @mock.patch.dict(os.environ, {"ANDROID_PRODUCT_OUT": ANDROID_PRODUCT_OUT},
138                   clear=True)
139  @mock.patch.object(os.path, "exists", autospec=True)
140  @mock.patch.object(os.path, "isdir", autospec=True)
141  @mock.patch.object(subprocess, "run", autospec=True)
142  @mock.patch.object(builtins, "input")
143  def test_create_parser_successfully_download_scripts(self, mock_input,
144      mock_subprocess_run, mock_isdir, mock_exists):
145    mock_isdir.return_value = True
146    mock_input.return_value = "y"
147    mock_exists.side_effect = [False, True]
148    mock_subprocess_run.return_value = None
149    parser = self.set_up_parser("torq.py -p simpleperf")
150
151    args = parser.parse_args()
152    args, error = verify_args(args)
153
154    self.assertEqual(error, None)
155    self.assertEqual(args.symbols, ANDROID_PRODUCT_OUT)
156    self.assertEqual(args.scripts_path, TORQ_TEMP_DIR)
157
158  @mock.patch.dict(os.environ, {"ANDROID_BUILD_TOP": ANDROID_BUILD_TOP},
159                   clear=True)
160  @mock.patch.object(os.path, "exists", autospec=True)
161  @mock.patch.object(os.path, "isdir", autospec=True)
162  @mock.patch.object(subprocess, "run", autospec=True)
163  @mock.patch.object(builtins, "input")
164  def test_create_parser_failed_to_download_scripts(self, mock_input,
165      mock_subprocess_run, mock_isdir, mock_exists):
166    mock_isdir.return_value = True
167    mock_input.return_value = "y"
168    mock_exists.side_effect = [False, False, False]
169    mock_subprocess_run.return_value = None
170    parser = self.set_up_parser("torq.py -p simpleperf --symbols %s"
171                                % SYMBOLS_PATH)
172
173    args = parser.parse_args()
174    with self.assertRaises(Exception) as e:
175      args, error = verify_args(args)
176
177    self.assertEqual(str(e.exception),
178                     "Error while downloading simpleperf scripts. Try "
179                     "again or set $ANDROID_BUILD_TOP to your android root "
180                     "path and make sure you have $ANDROID_BUILD_TOP/system"
181                     "/extras/simpleperf/scripts downloaded.")
182
183  @mock.patch.dict(os.environ, {"ANDROID_BUILD_TOP": ANDROID_BUILD_TOP},
184                   clear=True)
185  @mock.patch.object(os.path, "exists", autospec=True)
186  @mock.patch.object(os.path, "isdir", autospec=True)
187  @mock.patch.object(builtins, "input")
188  def test_create_parser_download_scripts_wrong_input(self, mock_input,
189      mock_isdir, mock_exists):
190    mock_isdir.return_value = True
191    mock_input.return_value = "bad-input"
192    mock_exists.side_effect = [False, False]
193    parser = self.set_up_parser("torq.py -p simpleperf --symbols %s"
194                                % SYMBOLS_PATH)
195
196    args = parser.parse_args()
197    args, error = verify_args(args)
198
199    self.assertEqual(error.message, "Invalid inputs.")
200    self.assertEqual(error.suggestion, "Set $ANDROID_BUILD_TOP to your android "
201                                       "root path and make sure you have "
202                                       "$ANDROID_BUILD_TOP/system/extras/"
203                                       "simpleperf/scripts downloaded.")
204
205  @mock.patch.dict(os.environ, {"ANDROID_BUILD_TOP": ANDROID_BUILD_TOP},
206                   clear=True)
207  @mock.patch.object(os.path, "exists", autospec=True)
208  @mock.patch.object(os.path, "isdir", autospec=True)
209  @mock.patch.object(builtins, "input")
210  def test_create_parser_download_scripts_refuse_download(self, mock_input,
211      mock_isdir, mock_exists):
212    mock_isdir.return_value = True
213    mock_input.return_value = "n"
214    mock_exists.side_effect = [False, False]
215    parser = self.set_up_parser("torq.py -p simpleperf --symbols %s"
216                                % SYMBOLS_PATH)
217
218    args = parser.parse_args()
219    args, error = verify_args(args)
220
221    self.assertEqual(error.message, "Did not download simpleperf scripts.")
222    self.assertEqual(error.suggestion, "Set $ANDROID_BUILD_TOP to your android "
223                                       "root path and make sure you have "
224                                       "$ANDROID_BUILD_TOP/system/extras/"
225                                       "simpleperf/scripts downloaded.")
226
227
228if __name__ == '__main__':
229  unittest.main()
230