1#!/usr/bin/env python3 2# 3# Copyright 2018, The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17"""Unittests for atest_tf_test_runner.""" 18 19# pylint: disable=line-too-long 20# pylint: disable=missing-function-docstring 21# pylint: disable=too-many-lines 22# pylint: disable=unused-argument 23 24import os 25import shlex 26import sys 27import tempfile 28import unittest 29import json 30 31from argparse import Namespace 32from io import StringIO 33from pathlib import Path 34from unittest import mock 35 36from atest import atest_configs 37from atest import atest_utils 38from atest import constants 39from atest import unittest_constants as uc 40from atest import unittest_utils 41 42from atest.test_finders import test_finder_utils 43from atest.test_finders import test_info 44from atest.test_runners import event_handler 45from atest.test_runners import atest_tf_test_runner as atf_tr 46 47#pylint: disable=protected-access 48#pylint: disable=invalid-name 49METRICS_DIR = '%s/baseline-metrics' % uc.TEST_INFO_DIR 50METRICS_DIR_ARG = '--metrics-folder %s ' % METRICS_DIR 51# TODO(147567606): Replace {serial} with {extra_args} for general extra 52# arguments testing. 53RUN_CMD_ARGS = ('{metrics}--log-level-display VERBOSE --log-level VERBOSE ' 54 '--skip-all-system-status-check=true' 55 '{device_early_release}{serial}') 56LOG_ARGS = atf_tr.AtestTradefedTestRunner._LOG_ARGS.format( 57 log_root_option_name=constants.LOG_ROOT_OPTION_NAME, 58 log_ext_option=constants.LOG_SAVER_EXT_OPTION, 59 log_path=os.path.join(uc.TEST_INFO_DIR, atf_tr.LOG_FOLDER_NAME), 60 proto_path=os.path.join(uc.TEST_INFO_DIR, constants.ATEST_TEST_RECORD_PROTO)) 61RUN_ENV_STR = '' 62RUN_CMD = atf_tr.AtestTradefedTestRunner._RUN_CMD.format( 63 env=RUN_ENV_STR, 64 exe=atf_tr.AtestTradefedTestRunner.EXECUTABLE, 65 template=atf_tr.AtestTradefedTestRunner._TF_TEMPLATE, 66 log_saver=constants.ATEST_TF_LOG_SAVER, 67 tf_customize_template='{tf_customize_template}', 68 args=RUN_CMD_ARGS, 69 log_args=LOG_ARGS) 70FULL_CLASS2_NAME = 'android.jank.cts.ui.SomeOtherClass' 71CLASS2_FILTER = test_info.TestFilter(FULL_CLASS2_NAME, frozenset()) 72METHOD2_FILTER = test_info.TestFilter(uc.FULL_CLASS_NAME, frozenset([uc.METHOD2_NAME])) 73MODULE_ARG1 = [(constants.TF_INCLUDE_FILTER_OPTION, "A"), 74 (constants.TF_INCLUDE_FILTER_OPTION, "B")] 75MODULE_ARG2 = [] 76CLASS2_METHOD_FILTER = test_info.TestFilter(FULL_CLASS2_NAME, 77 frozenset([uc.METHOD_NAME, uc.METHOD2_NAME])) 78MODULE2_INFO = test_info.TestInfo(uc.MODULE2_NAME, 79 atf_tr.AtestTradefedTestRunner.NAME, 80 set(), 81 data={constants.TI_REL_CONFIG: uc.CONFIG2_FILE, 82 constants.TI_FILTER: frozenset()}) 83CLASS1_BUILD_TARGETS = {'class_1_build_target'} 84CLASS1_INFO = test_info.TestInfo(uc.MODULE_NAME, 85 atf_tr.AtestTradefedTestRunner.NAME, 86 CLASS1_BUILD_TARGETS, 87 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 88 constants.TI_FILTER: frozenset([uc.CLASS_FILTER])}) 89CLASS2_BUILD_TARGETS = {'class_2_build_target'} 90CLASS2_INFO = test_info.TestInfo(uc.MODULE_NAME, 91 atf_tr.AtestTradefedTestRunner.NAME, 92 CLASS2_BUILD_TARGETS, 93 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 94 constants.TI_FILTER: frozenset([CLASS2_FILTER])}) 95CLASS3_BUILD_TARGETS = {'class_3_build_target'} 96CLASS3_INFO = test_info.TestInfo(uc.MODULE_NAME, 97 atf_tr.AtestTradefedTestRunner.NAME, 98 CLASS3_BUILD_TARGETS, 99 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 100 constants.TI_FILTER: frozenset(), 101 constants.TI_MODULE_ARG: MODULE_ARG1}) 102CLASS4_BUILD_TARGETS = {'class_4_build_target'} 103CLASS4_INFO = test_info.TestInfo(uc.MODULE_NAME, 104 atf_tr.AtestTradefedTestRunner.NAME, 105 CLASS4_BUILD_TARGETS, 106 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 107 constants.TI_FILTER: frozenset(), 108 constants.TI_MODULE_ARG: MODULE_ARG2}) 109CLASS1_CLASS2_MODULE_INFO = test_info.TestInfo( 110 uc.MODULE_NAME, 111 atf_tr.AtestTradefedTestRunner.NAME, 112 uc.MODULE_BUILD_TARGETS | CLASS1_BUILD_TARGETS | CLASS2_BUILD_TARGETS, 113 uc.MODULE_DATA) 114FLAT_CLASS_INFO = test_info.TestInfo( 115 uc.MODULE_NAME, 116 atf_tr.AtestTradefedTestRunner.NAME, 117 CLASS1_BUILD_TARGETS | CLASS2_BUILD_TARGETS, 118 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 119 constants.TI_FILTER: frozenset([uc.CLASS_FILTER, CLASS2_FILTER])}) 120FLAT2_CLASS_INFO = test_info.TestInfo( 121 uc.MODULE_NAME, 122 atf_tr.AtestTradefedTestRunner.NAME, 123 CLASS3_BUILD_TARGETS | CLASS4_BUILD_TARGETS, 124 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 125 constants.TI_FILTER: frozenset(), 126 constants.TI_MODULE_ARG: MODULE_ARG1 + MODULE_ARG2}) 127GTF_INT_CONFIG = os.path.join(uc.GTF_INT_DIR, uc.GTF_INT_NAME + '.xml') 128CLASS2_METHOD_INFO = test_info.TestInfo( 129 uc.MODULE_NAME, 130 atf_tr.AtestTradefedTestRunner.NAME, 131 set(), 132 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 133 constants.TI_FILTER: 134 frozenset([test_info.TestFilter( 135 FULL_CLASS2_NAME, frozenset([uc.METHOD_NAME, uc.METHOD2_NAME]))])}) 136METHOD_AND_CLASS2_METHOD = test_info.TestInfo( 137 uc.MODULE_NAME, 138 atf_tr.AtestTradefedTestRunner.NAME, 139 uc.MODULE_BUILD_TARGETS, 140 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 141 constants.TI_FILTER: frozenset([uc.METHOD_FILTER, CLASS2_METHOD_FILTER])}) 142METHOD_METHOD2_AND_CLASS2_METHOD = test_info.TestInfo( 143 uc.MODULE_NAME, 144 atf_tr.AtestTradefedTestRunner.NAME, 145 uc.MODULE_BUILD_TARGETS, 146 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 147 constants.TI_FILTER: frozenset([uc.FLAT_METHOD_FILTER, CLASS2_METHOD_FILTER])}) 148METHOD2_INFO = test_info.TestInfo( 149 uc.MODULE_NAME, 150 atf_tr.AtestTradefedTestRunner.NAME, 151 set(), 152 data={constants.TI_REL_CONFIG: uc.CONFIG_FILE, 153 constants.TI_FILTER: frozenset([METHOD2_FILTER])}) 154 155INT_INFO = test_info.TestInfo( 156 uc.INT_NAME, 157 atf_tr.AtestTradefedTestRunner.NAME, 158 set(), 159 test_finder='INTEGRATION') 160 161MOD_INFO = test_info.TestInfo( 162 uc.MODULE_NAME, 163 atf_tr.AtestTradefedTestRunner.NAME, 164 set(), 165 test_finder='MODULE') 166 167MOD_INFO_NO_TEST_FINDER = test_info.TestInfo( 168 uc.MODULE_NAME, 169 atf_tr.AtestTradefedTestRunner.NAME, 170 set()) 171 172EVENTS_NORMAL = [ 173 ('TEST_MODULE_STARTED', { 174 'moduleContextFileName':'serial-util1146216{974}2772610436.ser', 175 'moduleName':'someTestModule'}), 176 ('TEST_RUN_STARTED', {'testCount': 2}), 177 ('TEST_STARTED', {'start_time':52, 'className':'someClassName', 178 'testName':'someTestName'}), 179 ('TEST_ENDED', {'end_time':1048, 'className':'someClassName', 180 'testName':'someTestName'}), 181 ('TEST_STARTED', {'start_time':48, 'className':'someClassName2', 182 'testName':'someTestName2'}), 183 ('TEST_FAILED', {'className':'someClassName2', 'testName':'someTestName2', 184 'trace': 'someTrace'}), 185 ('TEST_ENDED', {'end_time':9876450, 'className':'someClassName2', 186 'testName':'someTestName2'}), 187 ('TEST_RUN_ENDED', {}), 188 ('TEST_MODULE_ENDED', {'foo': 'bar'}), 189] 190 191#pylint: disable=too-many-public-methods 192class AtestTradefedTestRunnerUnittests(unittest.TestCase): 193 """Unit tests for atest_tf_test_runner.py""" 194 195 #pylint: disable=arguments-differ 196 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_get_ld_library_path') 197 def setUp(self, mock_get_ld_library_path): 198 mock_get_ld_library_path.return_value = RUN_ENV_STR 199 self.tr = atf_tr.AtestTradefedTestRunner(results_dir=uc.TEST_INFO_DIR) 200 if not atest_configs.GLOBAL_ARGS: 201 atest_configs.GLOBAL_ARGS = Namespace() 202 atest_configs.GLOBAL_ARGS.device_count_config = None 203 204 def tearDown(self): 205 mock.patch.stopall() 206 207 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 208 '_start_socket_server') 209 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 210 'run') 211 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 212 '_create_test_args', return_value=['some_args']) 213 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 214 'generate_run_commands', return_value='some_cmd') 215 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 216 '_process_connection', return_value=None) 217 @mock.patch('select.select') 218 @mock.patch('os.killpg', return_value=None) 219 @mock.patch('os.getpgid', return_value=None) 220 @mock.patch('signal.signal', return_value=None) 221 def test_run_tests_pretty(self, _signal, _pgid, _killpg, mock_select, 222 _process, _run_cmd, _test_args, 223 mock_run, mock_start_socket_server): 224 """Test _run_tests_pretty method.""" 225 mock_subproc = mock.Mock() 226 mock_run.return_value = mock_subproc 227 mock_subproc.returncode = 0 228 mock_subproc.poll.side_effect = [True, True, None] 229 mock_server = mock.Mock() 230 mock_server.getsockname.return_value = ('', '') 231 mock_start_socket_server.return_value = mock_server 232 mock_reporter = mock.Mock() 233 234 # Test no early TF exit 235 mock_conn = mock.Mock() 236 mock_server.accept.return_value = (mock_conn, 'some_addr') 237 mock_server.close.return_value = True 238 mock_select.side_effect = [([mock_server], None, None), 239 ([mock_conn], None, None)] 240 self.tr.run_tests_pretty([MODULE2_INFO], {}, mock_reporter) 241 242 # Test early TF exit 243 tmp_file = tempfile.NamedTemporaryFile() 244 with open(tmp_file.name, 'w') as f: 245 f.write("tf msg") 246 self.tr.test_log_file = tmp_file 247 mock_select.side_effect = [([], None, None)] 248 mock_subproc.poll.side_effect = None 249 capture_output = StringIO() 250 sys.stdout = capture_output 251 self.assertRaises(atf_tr.TradeFedExitError, self.tr.run_tests_pretty, 252 [MODULE2_INFO], {}, mock_reporter) 253 sys.stdout = sys.__stdout__ 254 self.assertTrue('tf msg' in capture_output.getvalue()) 255 256 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_process_connection') 257 @mock.patch('select.select') 258 def test_start_monitor_2_connection(self, mock_select, mock_process): 259 """Test _start_monitor method.""" 260 mock_server = mock.Mock() 261 mock_subproc = mock.Mock() 262 mock_reporter = mock.Mock() 263 mock_conn1 = mock.Mock() 264 mock_conn2 = mock.Mock() 265 mock_server.accept.side_effect = [(mock_conn1, 'addr 1'), 266 (mock_conn2, 'addr 2')] 267 mock_select.side_effect = [([mock_server], None, None), 268 ([mock_server], None, None), 269 ([mock_conn1], None, None), 270 ([mock_conn2], None, None), 271 ([mock_conn1], None, None), 272 ([mock_conn2], None, None)] 273 mock_process.side_effect = ['abc', 'def', False, False] 274 mock_subproc.poll.side_effect = [None, None, None, None, 275 None, True] 276 self.tr._start_monitor(mock_server, mock_subproc, mock_reporter, {}) 277 self.assertEqual(mock_process.call_count, 4) 278 calls = [mock.call.accept(), mock.call.close()] 279 mock_server.assert_has_calls(calls) 280 mock_conn1.assert_has_calls([mock.call.close()]) 281 mock_conn2.assert_has_calls([mock.call.close()]) 282 283 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_process_connection') 284 @mock.patch('select.select') 285 def test_start_monitor_tf_exit_before_2nd_connection(self, 286 mock_select, 287 mock_process): 288 """Test _start_monitor method.""" 289 mock_server = mock.Mock() 290 mock_subproc = mock.Mock() 291 mock_reporter = mock.Mock() 292 mock_conn1 = mock.Mock() 293 mock_conn2 = mock.Mock() 294 mock_server.accept.side_effect = [(mock_conn1, 'addr 1'), 295 (mock_conn2, 'addr 2')] 296 mock_select.side_effect = [([mock_server], None, None), 297 ([mock_server], None, None), 298 ([mock_conn1], None, None), 299 ([mock_conn2], None, None), 300 ([mock_conn1], None, None), 301 ([mock_conn2], None, None)] 302 mock_process.side_effect = ['abc', 'def', False, False] 303 # TF exit early but have not processed data in socket buffer. 304 mock_subproc.poll.side_effect = [None, None, True, True, 305 True, True] 306 self.tr._start_monitor(mock_server, mock_subproc, mock_reporter, {}) 307 self.assertEqual(mock_process.call_count, 4) 308 calls = [mock.call.accept(), mock.call.close()] 309 mock_server.assert_has_calls(calls) 310 mock_conn1.assert_has_calls([mock.call.close()]) 311 mock_conn2.assert_has_calls([mock.call.close()]) 312 313 314 def test_start_socket_server(self): 315 """Test start_socket_server method.""" 316 server = self.tr._start_socket_server() 317 host, port = server.getsockname() 318 self.assertEqual(host, atf_tr.SOCKET_HOST) 319 self.assertLessEqual(port, 65535) 320 self.assertGreaterEqual(port, 1024) 321 server.close() 322 323 @mock.patch('os.path.exists') 324 @mock.patch.dict('os.environ', {'APE_API_KEY':'/tmp/123.json'}) 325 def test_try_set_gts_authentication_key_is_set_by_user(self, mock_exist): 326 """Test try_set_authentication_key_is_set_by_user method.""" 327 # Test key is set by user. 328 self.tr._try_set_gts_authentication_key() 329 mock_exist.assert_not_called() 330 331 @mock.patch('os.path.join', return_value='/tmp/file_not_exist.json') 332 def test_try_set_gts_authentication_key_not_set(self, _): 333 """Test try_set_authentication_key_not_set method.""" 334 # Delete the environment variable if it's set. This is fine for this 335 # method because it's for validating the APE_API_KEY isn't set. 336 if os.environ.get('APE_API_KEY'): 337 del os.environ['APE_API_KEY'] 338 self.tr._try_set_gts_authentication_key() 339 self.assertEqual(os.environ.get('APE_API_KEY'), None) 340 341 @mock.patch.object(event_handler.EventHandler, 'process_event') 342 def test_process_connection(self, mock_pe): 343 """Test _process_connection method.""" 344 mock_socket = mock.Mock() 345 for name, data in EVENTS_NORMAL: 346 data_map = {mock_socket: ''} 347 socket_data = '%s %s' % (name, json.dumps(data)) 348 mock_socket.recv.return_value = socket_data 349 self.tr._process_connection(data_map, mock_socket, mock_pe) 350 351 calls = [mock.call.process_event(name, data) for name, data in EVENTS_NORMAL] 352 mock_pe.assert_has_calls(calls) 353 mock_socket.recv.return_value = '' 354 self.assertFalse(self.tr._process_connection(data_map, mock_socket, mock_pe)) 355 356 @mock.patch.object(event_handler.EventHandler, 'process_event') 357 def test_process_connection_multiple_lines_in_single_recv(self, mock_pe): 358 """Test _process_connection when recv reads multiple lines in one go.""" 359 mock_socket = mock.Mock() 360 squashed_events = '\n'.join(['%s %s' % (name, json.dumps(data)) 361 for name, data in EVENTS_NORMAL]) 362 socket_data = [squashed_events, ''] 363 mock_socket.recv.side_effect = socket_data 364 data_map = {mock_socket: ''} 365 self.tr._process_connection(data_map, mock_socket, mock_pe) 366 calls = [mock.call.process_event(name, data) for name, data in EVENTS_NORMAL] 367 mock_pe.assert_has_calls(calls) 368 369 @mock.patch.object(event_handler.EventHandler, 'process_event') 370 def test_process_connection_with_buffering(self, mock_pe): 371 """Test _process_connection when events overflow socket buffer size.""" 372 mock_socket = mock.Mock() 373 module_events = [EVENTS_NORMAL[0], EVENTS_NORMAL[-1]] 374 socket_events = ['%s %s' % (name, json.dumps(data)) 375 for name, data in module_events] 376 # test try-block code by breaking apart first event after first } 377 index = socket_events[0].index('}') + 1 378 socket_data = [socket_events[0][:index], socket_events[0][index:]] 379 # test non-try block buffering with second event 380 socket_data.extend([socket_events[1][:-4], socket_events[1][-4:], '']) 381 mock_socket.recv.side_effect = socket_data 382 data_map = {mock_socket: ''} 383 self.tr._process_connection(data_map, mock_socket, mock_pe) 384 self.tr._process_connection(data_map, mock_socket, mock_pe) 385 self.tr._process_connection(data_map, mock_socket, mock_pe) 386 self.tr._process_connection(data_map, mock_socket, mock_pe) 387 calls = [mock.call.process_event(name, data) for name, data in module_events] 388 mock_pe.assert_has_calls(calls) 389 390 @mock.patch.object(event_handler.EventHandler, 'process_event') 391 def test_process_connection_with_not_completed_event_data(self, mock_pe): 392 """Test _process_connection when event have \n prefix.""" 393 mock_socket = mock.Mock() 394 mock_socket.recv.return_value = ('\n%s %s' 395 %(EVENTS_NORMAL[0][0], 396 json.dumps(EVENTS_NORMAL[0][1]))) 397 data_map = {mock_socket: ''} 398 self.tr._process_connection(data_map, mock_socket, mock_pe) 399 calls = [mock.call.process_event(EVENTS_NORMAL[0][0], 400 EVENTS_NORMAL[0][1])] 401 mock_pe.assert_has_calls(calls) 402 403 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 404 '_is_all_tests_parameter_auto_enabled', 405 return_value=False) 406 @mock.patch('os.environ.get', return_value=None) 407 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 408 '_generate_metrics_folder') 409 @mock.patch('atest.atest_utils.get_result_server_args') 410 def test_generate_run_commands_without_serial_env( 411 self, mock_resultargs, mock_mertrics, _, _mock_all): 412 """Test generate_run_command method.""" 413 # Basic Run Cmd 414 mock_resultargs.return_value = [] 415 mock_mertrics.return_value = '' 416 unittest_utils.assert_strict_equal( 417 self, 418 self.tr.generate_run_commands([], {}), 419 [RUN_CMD.format(env=RUN_ENV_STR, 420 metrics='', 421 serial='', 422 tf_customize_template='', 423 device_early_release=' --no-early-device-release')]) 424 mock_mertrics.return_value = METRICS_DIR 425 unittest_utils.assert_strict_equal( 426 self, 427 self.tr.generate_run_commands([], {}), 428 [RUN_CMD.format(metrics=METRICS_DIR_ARG, 429 serial='', 430 tf_customize_template='', 431 device_early_release=' --no-early-device-release')]) 432 # Run cmd with result server args. 433 result_arg = '--result_arg' 434 mock_resultargs.return_value = [result_arg] 435 mock_mertrics.return_value = '' 436 unittest_utils.assert_strict_equal( 437 self, 438 self.tr.generate_run_commands( 439 [], {}), 440 [RUN_CMD.format(metrics='', 441 serial='', 442 tf_customize_template='', 443 device_early_release=' --no-early-device-release') + ' ' + result_arg]) 444 445 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 446 '_is_all_tests_parameter_auto_enabled', 447 return_value=False) 448 @mock.patch('os.environ.get') 449 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_generate_metrics_folder') 450 @mock.patch('atest.atest_utils.get_result_server_args') 451 def test_generate_run_commands_with_serial_env( 452 self, mock_resultargs, mock_mertrics, mock_env, _mock_all): 453 """Test generate_run_command method.""" 454 # Basic Run Cmd 455 env_device_serial = 'env-device-0' 456 mock_resultargs.return_value = [] 457 mock_mertrics.return_value = '' 458 mock_env.return_value = env_device_serial 459 env_serial_arg = ' --serial %s' % env_device_serial 460 # Serial env be set and without --serial arg. 461 unittest_utils.assert_strict_equal( 462 self, 463 self.tr.generate_run_commands([], {}), 464 [RUN_CMD.format(metrics='', 465 serial=env_serial_arg, 466 tf_customize_template='', 467 device_early_release=' --no-early-device-release')]) 468 # Serial env be set but with --serial arg. 469 arg_device_serial = 'arg-device-0' 470 arg_serial_arg = ' --serial %s' % arg_device_serial 471 unittest_utils.assert_strict_equal( 472 self, 473 self.tr.generate_run_commands( 474 [], {constants.SERIAL: [arg_device_serial]}), 475 [RUN_CMD.format(metrics='', 476 serial=arg_serial_arg, 477 tf_customize_template='', 478 device_early_release=' --no-early-device-release')]) 479 # Serial env be set but with -n arg 480 unittest_utils.assert_strict_equal( 481 self, 482 self.tr.generate_run_commands([], {constants.HOST: True}), 483 [RUN_CMD.format(metrics='', 484 serial='', 485 tf_customize_template='', 486 device_early_release=' --no-early-device-release') + 487 ' -n --prioritize-host-config --skip-host-arch-check']) 488 489 def test_flatten_test_filters(self): 490 """Test _flatten_test_filters method.""" 491 # No Flattening 492 filters = self.tr._flatten_test_filters({uc.CLASS_FILTER}) 493 unittest_utils.assert_strict_equal(self, frozenset([uc.CLASS_FILTER]), 494 filters) 495 filters = self.tr._flatten_test_filters({CLASS2_FILTER}) 496 unittest_utils.assert_strict_equal( 497 self, frozenset([CLASS2_FILTER]), filters) 498 filters = self.tr._flatten_test_filters({uc.METHOD_FILTER}) 499 unittest_utils.assert_strict_equal( 500 self, frozenset([uc.METHOD_FILTER]), filters) 501 filters = self.tr._flatten_test_filters({uc.METHOD_FILTER, 502 CLASS2_METHOD_FILTER}) 503 unittest_utils.assert_strict_equal( 504 self, frozenset([uc.METHOD_FILTER, CLASS2_METHOD_FILTER]), filters) 505 # Flattening 506 filters = self.tr._flatten_test_filters({uc.METHOD_FILTER, 507 METHOD2_FILTER}) 508 unittest_utils.assert_strict_equal( 509 self, filters, frozenset([uc.FLAT_METHOD_FILTER])) 510 filters = self.tr._flatten_test_filters({uc.METHOD_FILTER, 511 METHOD2_FILTER, 512 CLASS2_METHOD_FILTER,}) 513 unittest_utils.assert_strict_equal( 514 self, filters, frozenset([uc.FLAT_METHOD_FILTER, 515 CLASS2_METHOD_FILTER])) 516 517 def test_flatten_test_infos(self): 518 """Test _flatten_test_infos method.""" 519 # No Flattening 520 test_infos = self.tr._flatten_test_infos({uc.MODULE_INFO}) 521 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 522 {uc.MODULE_INFO}) 523 524 test_infos = self.tr._flatten_test_infos([uc.MODULE_INFO, MODULE2_INFO]) 525 unittest_utils.assert_equal_testinfo_sets( 526 self, test_infos, {uc.MODULE_INFO, MODULE2_INFO}) 527 528 test_infos = self.tr._flatten_test_infos({CLASS1_INFO}) 529 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 530 {CLASS1_INFO}) 531 532 test_infos = self.tr._flatten_test_infos({uc.INT_INFO}) 533 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 534 {uc.INT_INFO}) 535 536 test_infos = self.tr._flatten_test_infos({uc.METHOD_INFO}) 537 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 538 {uc.METHOD_INFO}) 539 540 # Flattening 541 test_infos = self.tr._flatten_test_infos({CLASS1_INFO, CLASS2_INFO}) 542 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 543 {FLAT_CLASS_INFO}) 544 545 test_infos = self.tr._flatten_test_infos({CLASS1_INFO, uc.INT_INFO, 546 CLASS2_INFO}) 547 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 548 {uc.INT_INFO, 549 FLAT_CLASS_INFO}) 550 551 test_infos = self.tr._flatten_test_infos({CLASS1_INFO, uc.MODULE_INFO, 552 CLASS2_INFO}) 553 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 554 {CLASS1_CLASS2_MODULE_INFO}) 555 556 test_infos = self.tr._flatten_test_infos({MODULE2_INFO, uc.INT_INFO, 557 CLASS1_INFO, CLASS2_INFO, 558 uc.GTF_INT_INFO}) 559 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 560 {uc.INT_INFO, uc.GTF_INT_INFO, 561 FLAT_CLASS_INFO, 562 MODULE2_INFO}) 563 564 test_infos = self.tr._flatten_test_infos({uc.METHOD_INFO, 565 CLASS2_METHOD_INFO}) 566 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 567 {METHOD_AND_CLASS2_METHOD}) 568 569 test_infos = self.tr._flatten_test_infos({uc.METHOD_INFO, METHOD2_INFO, 570 CLASS2_METHOD_INFO}) 571 unittest_utils.assert_equal_testinfo_sets( 572 self, test_infos, {METHOD_METHOD2_AND_CLASS2_METHOD}) 573 test_infos = self.tr._flatten_test_infos({uc.METHOD_INFO, METHOD2_INFO, 574 CLASS2_METHOD_INFO, 575 MODULE2_INFO, 576 uc.INT_INFO}) 577 unittest_utils.assert_equal_testinfo_sets( 578 self, test_infos, {uc.INT_INFO, MODULE2_INFO, 579 METHOD_METHOD2_AND_CLASS2_METHOD}) 580 581 test_infos = self.tr._flatten_test_infos({CLASS3_INFO, CLASS4_INFO}) 582 unittest_utils.assert_equal_testinfo_sets(self, test_infos, 583 {FLAT2_CLASS_INFO}) 584 585 @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs') 586 def test_create_test_args(self, mock_config): 587 """Test _create_test_args method.""" 588 # Only compile '--skip-loading-config-jar' in TF if it's not 589 # INTEGRATION finder or the finder property isn't set. 590 mock_config.return_value = '', '' 591 args = self.tr._create_test_args([MOD_INFO]) 592 self.assertTrue(constants.TF_SKIP_LOADING_CONFIG_JAR in args) 593 594 args = self.tr._create_test_args([INT_INFO]) 595 self.assertFalse(constants.TF_SKIP_LOADING_CONFIG_JAR in args) 596 597 args = self.tr._create_test_args([MOD_INFO_NO_TEST_FINDER]) 598 self.assertFalse(constants.TF_SKIP_LOADING_CONFIG_JAR in args) 599 600 args = self.tr._create_test_args([MOD_INFO_NO_TEST_FINDER, INT_INFO]) 601 self.assertFalse(constants.TF_SKIP_LOADING_CONFIG_JAR in args) 602 603 args = self.tr._create_test_args([MOD_INFO_NO_TEST_FINDER]) 604 self.assertFalse(constants.TF_SKIP_LOADING_CONFIG_JAR in args) 605 606 args = self.tr._create_test_args([MOD_INFO_NO_TEST_FINDER, INT_INFO, MOD_INFO]) 607 self.assertFalse(constants.TF_SKIP_LOADING_CONFIG_JAR in args) 608 609 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 610 '_is_all_tests_parameter_auto_enabled', 611 return_value=False) 612 @mock.patch('os.environ.get', return_value=None) 613 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 614 '_generate_metrics_folder') 615 @mock.patch('atest.atest_utils.get_result_server_args') 616 def test_generate_run_commands_collect_tests_only( 617 self, mock_resultargs, mock_mertrics, _, _mock_is_all): 618 """Test generate_run_command method.""" 619 # Testing without collect-tests-only 620 mock_resultargs.return_value = [] 621 mock_mertrics.return_value = '' 622 extra_args = {} 623 unittest_utils.assert_strict_equal( 624 self, 625 self.tr.generate_run_commands([], extra_args), 626 [RUN_CMD.format( 627 metrics='', 628 serial='', 629 tf_customize_template='', 630 device_early_release=' --no-early-device-release')]) 631 # Testing with collect-tests-only 632 mock_resultargs.return_value = [] 633 mock_mertrics.return_value = '' 634 extra_args = {constants.COLLECT_TESTS_ONLY: True} 635 unittest_utils.assert_strict_equal( 636 self, 637 self.tr.generate_run_commands([], extra_args), 638 [RUN_CMD.format( 639 metrics='', 640 serial=' --collect-tests-only', 641 tf_customize_template='', 642 device_early_release=' --no-early-device-release')]) 643 644 645 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 646 '_is_all_tests_parameter_auto_enabled', 647 return_value=False) 648 @mock.patch('os.environ.get', return_value=None) 649 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_generate_metrics_folder') 650 @mock.patch('atest.atest_utils.get_result_server_args') 651 def test_generate_run_commands_with_tf_template( 652 self, mock_resultargs, mock_mertrics, _, _mock_all): 653 """Test generate_run_command method.""" 654 tf_tmplate_key1 = 'tf_tmplate_key1' 655 tf_tmplate_val1 = 'tf_tmplate_val1' 656 tf_tmplate_key2 = 'tf_tmplate_key2' 657 tf_tmplate_val2 = 'tf_tmplate_val2' 658 # Testing with only one tradefed template command 659 mock_resultargs.return_value = [] 660 mock_mertrics.return_value = '' 661 extra_args = {constants.TF_TEMPLATE: 662 ['{}={}'.format(tf_tmplate_key1, 663 tf_tmplate_val1)]} 664 unittest_utils.assert_strict_equal( 665 self, 666 self.tr.generate_run_commands([], extra_args), 667 [RUN_CMD.format( 668 metrics='', 669 serial='', 670 device_early_release=' --no-early-device-release', 671 tf_customize_template= 672 '--template:map {}={}').format(tf_tmplate_key1, 673 tf_tmplate_val1)]) 674 # Testing with two tradefed template commands 675 extra_args = {constants.TF_TEMPLATE: 676 ['{}={}'.format(tf_tmplate_key1, 677 tf_tmplate_val1), 678 '{}={}'.format(tf_tmplate_key2, 679 tf_tmplate_val2)]} 680 unittest_utils.assert_strict_equal( 681 self, 682 self.tr.generate_run_commands([], extra_args), 683 [RUN_CMD.format( 684 metrics='', 685 serial='', 686 device_early_release=' --no-early-device-release', 687 tf_customize_template= 688 '--template:map {}={} --template:map {}={}').format( 689 tf_tmplate_key1, 690 tf_tmplate_val1, 691 tf_tmplate_key2, 692 tf_tmplate_val2)]) 693 694 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 695 '_is_all_tests_parameter_auto_enabled', 696 return_value=False) 697 @mock.patch('os.environ.get', return_value=None) 698 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_generate_metrics_folder') 699 @mock.patch('atest.atest_utils.get_result_server_args') 700 def test_generate_run_commands_with_tf_early_device_release( 701 self, mock_resultargs, mock_mertrics, _, _mock_all): 702 """Test generate_run_command method.""" 703 # Testing without collect-tests-only 704 mock_resultargs.return_value = [] 705 mock_mertrics.return_value = '' 706 extra_args = {constants.TF_EARLY_DEVICE_RELEASE: True} 707 unittest_utils.assert_strict_equal( 708 self, 709 self.tr.generate_run_commands([], extra_args), 710 [RUN_CMD.format( 711 metrics='', 712 serial='', 713 tf_customize_template='', 714 device_early_release='')]) 715 716 @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs') 717 def test_has_instant_app_config(self, mock_config): 718 """test _has_instant_app_config method.""" 719 no_instant_config = os.path.join( 720 uc.TEST_DATA_DIR, "parameter_config", "parameter.cfg") 721 instant_config = os.path.join( 722 uc.TEST_DATA_DIR, "parameter_config", "instant_app_parameter.cfg") 723 # Test find instant app config 724 mock_config.return_value = instant_config, '' 725 self.assertTrue( 726 atf_tr.AtestTradefedTestRunner._has_instant_app_config( 727 ['test_info'], 'module_info_obj')) 728 # Test not find instant app config 729 mock_config.return_value = no_instant_config, '' 730 self.assertFalse( 731 atf_tr.AtestTradefedTestRunner._has_instant_app_config( 732 ['test_info'], 'module_info_obj')) 733 734 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 735 '_is_all_tests_parameter_auto_enabled', 736 return_value=False) 737 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 738 '_has_instant_app_config', return_value=True) 739 @mock.patch('os.environ.get', return_value=None) 740 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 741 '_generate_metrics_folder') 742 @mock.patch('atest.atest_utils.get_result_server_args') 743 def test_generate_run_commands_has_instant_app_config( 744 self, mock_resultargs, mock_mertrics, _, _mock_has_config, 745 _mock_is_all): 746 """Test generate_run_command method which has instant app config.""" 747 # Basic Run Cmd 748 mock_resultargs.return_value = [] 749 mock_mertrics.return_value = '' 750 extra_tf_arg = ( 751 '{tf_test_arg} {tf_class}:{option_name}:{option_value}'.format( 752 tf_test_arg = constants.TF_TEST_ARG, 753 tf_class=constants.TF_AND_JUNIT_CLASS, 754 option_name=constants.TF_EXCLUDE_ANNOTATE, 755 option_value=constants.INSTANT_MODE_ANNOTATE)) 756 unittest_utils.assert_strict_equal( 757 self, 758 self.tr.generate_run_commands([], {}), 759 [RUN_CMD.format(env=RUN_ENV_STR, 760 metrics='', 761 serial='', 762 tf_customize_template='', 763 device_early_release=' --no-early-device-release ' 764 + extra_tf_arg)]) 765 766 @mock.patch.object(atest_utils, 'get_config_parameter') 767 @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs') 768 def test_is_parameter_auto_enabled_cfg(self, mock_config, mock_cfg_para): 769 """test _is_parameter_auto_enabled_cfg method.""" 770 # Test if TF_PARA_INSTANT_APP is match 771 mock_config.return_value = 'test_config', '' 772 mock_cfg_para.return_value = {list(constants.DEFAULT_EXCLUDE_PARAS)[1], 773 list(constants.DEFAULT_EXCLUDE_PARAS)[0]} 774 self.assertFalse( 775 atf_tr.AtestTradefedTestRunner._is_parameter_auto_enabled_cfg( 776 ['test_info'], 'module_info_obj')) 777 # Test if DEFAULT_EXCLUDE_NOT_PARAS is match 778 mock_cfg_para.return_value = { 779 list(constants.DEFAULT_EXCLUDE_NOT_PARAS)[2], 780 list(constants.DEFAULT_EXCLUDE_NOT_PARAS)[0]} 781 self.assertFalse( 782 atf_tr.AtestTradefedTestRunner._is_parameter_auto_enabled_cfg( 783 ['test_info'], 'module_info_obj')) 784 # Test if have parameter not in default exclude paras 785 mock_cfg_para.return_value = { 786 'not match parameter', 787 list(constants.DEFAULT_EXCLUDE_PARAS)[1], 788 list(constants.DEFAULT_EXCLUDE_NOT_PARAS)[2]} 789 self.assertTrue( 790 atf_tr.AtestTradefedTestRunner._is_parameter_auto_enabled_cfg( 791 ['test_info'], 'module_info_obj')) 792 793 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 794 '_is_parameter_auto_enabled_cfg', 795 return_value=True) 796 @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs') 797 def test_create_test_args_with_auto_enable_parameter( 798 self, mock_config, _mock_is_enable): 799 """Test _create_test_args method with auto enabled parameter config.""" 800 # Should have --m on args and should not have --include-filter. 801 mock_config.return_value = '', '' 802 args = self.tr._create_test_args([MOD_INFO]) 803 self.assertTrue(constants.TF_MODULE_FILTER in args) 804 self.assertFalse(constants.TF_INCLUDE_FILTER in args) 805 806 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 807 '_is_parameter_auto_enabled_cfg') 808 @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs') 809 def test_parse_extra_args(self, mock_config, _mock_is_enable): 810 """Test _parse_extra_args .""" 811 # If extra_arg enable instant_app or secondary users, should not have 812 # --exclude-module-parameters even though test config parameter is auto 813 # enabled. 814 mock_config.return_value = '', '' 815 _mock_is_enable.return_value = True 816 args, _ = self.tr._parse_extra_args([MOD_INFO], {constants.INSTANT: ''}) 817 self.assertFalse('--exclude-module-parameters' in args) 818 819 # If extra_arg not enable instant_app or secondary users, should have 820 # --exclude-module-rameters if config parameter is auto enabled. 821 _mock_is_enable.return_value = True 822 args, _ = self.tr._parse_extra_args([MOD_INFO], {constants.ALL_ABI: ''}) 823 self.assertTrue('--exclude-module-parameters' in args) 824 825 # If extra_arg not enable instant_app or secondary users, should not 826 # have --exclude-module-rameters if config parameter is not auto enabled 827 _mock_is_enable.return_value = False 828 args, _ = self.tr._parse_extra_args([MOD_INFO], {constants.ALL_ABI: ''}) 829 self.assertFalse('--exclude-module-parameters' in args) 830 831 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 832 '_is_parameter_auto_enabled_cfg', return_value=False) 833 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 834 '_has_instant_app_config', return_value=False) 835 def test_parse_extra_args_has_instant_app( 836 self, _mock_has_instant, _mock_is_para): 837 """Test _parse_extra_args with instant app in customize flag.""" 838 # If customize_arg has module-parameter should also include 839 # --enable-parameterized-modules. 840 args, _ = self.tr._parse_extra_args( 841 [MOD_INFO], 842 {constants.CUSTOM_ARGS: [constants.TF_MODULE_PARAMETER]}) 843 self.assertTrue(constants.TF_ENABLE_PARAMETERIZED_MODULES in args) 844 845 @mock.patch('atest.atest_utils.get_prebuilt_sdk_tools_dir') 846 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 847 '_is_missing_exec', return_value=False) 848 def test_generate_env_vars_aapt_already_in_system_path( 849 self, _mock_is_missing_exec, mock_prebuilt_sdk_dir): 850 """Test generate_env_vars if aapt already in system path.""" 851 prebuilt_sdk_dir = Path('/my/test/sdk/dir') 852 mock_prebuilt_sdk_dir.return_value = prebuilt_sdk_dir 853 854 env_vars = self.tr.generate_env_vars(extra_args={}) 855 856 self.assertFalse( 857 str(prebuilt_sdk_dir) + ':' in env_vars.get('PATH', '')) 858 859 @mock.patch('os.path.exists', return_value=True) 860 @mock.patch('atest.atest_utils.get_prebuilt_sdk_tools_dir') 861 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 862 '_is_missing_exec', return_value=True) 863 def test_generate_env_vars_aapt_not_in_system_path( 864 self, _mock_is_missing_exec, mock_prebuilt_sdk_dir, _mock_exist): 865 """Test generate_env_vars if aapt not in system path.""" 866 prebuilt_sdk_dir = Path('/my/test/sdk/dir') 867 mock_prebuilt_sdk_dir.return_value = prebuilt_sdk_dir 868 869 env_vars = self.tr.generate_env_vars(extra_args={}) 870 871 self.assertTrue(str(prebuilt_sdk_dir) + ':' in env_vars.get('PATH', '')) 872 873 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_handle_native_tests') 874 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_parse_extra_args') 875 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_create_test_args') 876 @mock.patch('os.environ.get', return_value=None) 877 @mock.patch.object( 878 atf_tr.AtestTradefedTestRunner, '_generate_metrics_folder') 879 @mock.patch('atest.atest_utils.get_result_server_args') 880 def test_generate_run_commands_for_aggregate_metric_result( 881 self, mock_resultargs, mock_mertrics, _mock_env, _mock_create, _mock_parse, _mock_handle_native): 882 """Test generate_run_command method for test need aggregate metric.""" 883 mock_resultargs.return_value = [] 884 mock_mertrics.return_value = '' 885 _mock_create.return_value = [] 886 _mock_parse.return_value = [], [] 887 test_info_with_aggregate_metrics = test_info.TestInfo( 888 test_name='perf_test', test_runner='test_runner', 889 build_targets=set()) 890 test_info_with_aggregate_metrics.aggregate_metrics_result = True 891 892 run_cmd = self.tr.generate_run_commands( 893 [test_info_with_aggregate_metrics], extra_args={}) 894 895 self.assertTrue( 896 str(run_cmd).find( 897 'metric_post_processor=' 898 'google/template/postprocessors/metric-file-aggregate') > 0) 899 900 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_handle_native_tests') 901 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_parse_extra_args') 902 @mock.patch.object(atf_tr.AtestTradefedTestRunner, '_create_test_args') 903 @mock.patch('os.environ.get', return_value=None) 904 @mock.patch.object( 905 atf_tr.AtestTradefedTestRunner, '_generate_metrics_folder') 906 @mock.patch('atest.atest_utils.get_result_server_args') 907 def test_run_commands_for_aggregate_metric_result_with_manually_input( 908 self, mock_resultargs, mock_mertrics, _mock_env, _mock_create, 909 _mock_parse, _mock_handle_native): 910 """Test generate_run_command method for test need aggregate metric.""" 911 mock_resultargs.return_value = [] 912 mock_mertrics.return_value = '' 913 _mock_create.return_value = [] 914 _mock_parse.return_value = [], [] 915 test_info_with_aggregate_metrics = test_info.TestInfo( 916 test_name='perf_test', test_runner='test_runner', 917 build_targets=set()) 918 test_info_with_aggregate_metrics.aggregate_metrics_result = True 919 920 run_cmd = self.tr.generate_run_commands( 921 [test_info_with_aggregate_metrics], 922 extra_args={constants.TF_TEMPLATE: ['metric_post_processor=a/b/c']}) 923 924 self.assertTrue( 925 str(run_cmd).find( 926 'metric_post_processor=' 927 'google/template/postprocessors/metric-file-aggregate') < 0) 928 929 self.assertTrue( 930 str(run_cmd).find('metric_post_processor=a/b/c') > 0) 931 932 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 933 '_is_all_tests_parameter_auto_enabled', 934 return_value=False) 935 @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs') 936 def test_create_test_args_with_auto_enable_parameter_but_not_all( 937 self, mock_config, _mock_is_all): 938 """ 939 Test _create_test_args method with not all configs are auto enabled 940 parameter. 941 """ 942 # Should not --m on args and should have --include-filter. 943 mock_config.return_value = '', '' 944 args = self.tr._create_test_args([MOD_INFO]) 945 946 self.assertFalse(constants.TF_MODULE_FILTER in args) 947 self.assertTrue(constants.TF_INCLUDE_FILTER in args) 948 949 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 950 '_is_all_tests_parameter_auto_enabled', 951 return_value=False) 952 @mock.patch.object(atf_tr.AtestTradefedTestRunner, 953 '_is_parameter_auto_enabled_cfg') 954 @mock.patch.object(test_finder_utils, 'get_test_config_and_srcs') 955 def test_parse_extra_args_not_all_cfg_auto_enable_parameter( 956 self, mock_config, _mock_is_enable, _mock_is_all): 957 """Test _parse_extra_args without all config is auto parameter.""" 958 # If not all test config is parameter auto enabled, should not find 959 # --enable-parameterized-modules in test config. 960 mock_config.return_value = '', '' 961 _mock_is_enable.return_value = True 962 963 args, _ = self.tr._parse_extra_args([MOD_INFO], {}) 964 self.assertFalse('--enable-parameterized-modules' in args) 965 966 def assertTokensIn(self, expected_tokens, s): 967 tokens = shlex.split(s) 968 for token in expected_tokens: 969 self.assertIn(token, tokens) 970 971 def assertTokensNotIn(self, unwanted_tokens, s): 972 tokens = shlex.split(s) 973 for token in unwanted_tokens: 974 self.assertNotIn(token, tokens) 975 976 977class ExtraArgsTest(AtestTradefedTestRunnerUnittests): 978 """Unit tests for parsing extra args""" 979 980 def test_args_with_wait_for_debug_and_generate_in_run_cmd(self): 981 extra_args = {constants.WAIT_FOR_DEBUGGER: None} 982 983 cmd = self.tr.generate_run_commands([], extra_args) 984 985 self.assertTokensIn(['--wait-for-debugger'], cmd[0]) 986 987 def test_args_with_disable_installed_and_generate_in_run_cmd(self): 988 extra_args = {constants.DISABLE_INSTALL: None} 989 990 cmd = self.tr.generate_run_commands([], extra_args) 991 992 self.assertTokensIn(['--disable-target-preparers'], cmd[0]) 993 994 def test_multidevice_in_config_and_generate_in_run_cmd(self): 995 atest_configs.GLOBAL_ARGS.device_count_config = 2 996 cmd = self.tr.generate_run_commands([], {}) 997 self.assertTokensIn( 998 ['--replicate-parent-setup', '--multi-device-count', '2'], cmd[0]) 999 1000 atest_configs.GLOBAL_ARGS.device_count_config = 1 1001 cmd = self.tr.generate_run_commands([], {}) 1002 self.assertTokensNotIn( 1003 ['--replicate-parent-setup', '--multi-device-count'], cmd[0]) 1004 1005 atest_configs.GLOBAL_ARGS.device_count_config = None 1006 cmd = self.tr.generate_run_commands([], {}) 1007 self.assertTokensNotIn( 1008 ['--replicate-parent-setup', '--multi-device-count'], cmd[0]) 1009 1010 def test_args_with_serial_no_and_generate_in_run_cmd(self): 1011 extra_args = {constants.SERIAL: ['device1']} 1012 1013 cmd = self.tr.generate_run_commands([], extra_args) 1014 1015 self.assertTokensIn(['--serial', 'device1'], cmd[0]) 1016 1017 def test_args_with_multi_serial_no_and_generate_in_run_cmd(self): 1018 extra_args = {constants.SERIAL: ['device1', 'device2']} 1019 1020 cmd = self.tr.generate_run_commands([], extra_args) 1021 1022 self.assertIn('--serial device1 --serial device2', cmd[0]) 1023 1024 def test_args_with_sharding_and_generate_in_run_cmd(self): 1025 extra_args = {constants.SHARDING: 2} 1026 1027 cmd = self.tr.generate_run_commands([], extra_args) 1028 1029 self.assertIn('--shard-count 2', cmd[0]) 1030 1031 def test_args_with_disable_teardown_and_generate_in_run_cmd(self): 1032 extra_args = {constants.DISABLE_TEARDOWN: True} 1033 1034 cmd = self.tr.generate_run_commands([], extra_args) 1035 1036 self.assertTokensIn(['--disable-teardown'], cmd[0]) 1037 1038 def test_args_with_host_and_generate_in_run_cmd(self): 1039 extra_args = {constants.HOST: True} 1040 1041 cmd = self.tr.generate_run_commands([], extra_args) 1042 1043 self.assertTokensIn(['-n', '--prioritize-host-config', 1044 '--skip-host-arch-check'], cmd[0]) 1045 1046 def test_args_with_custom_args_and_generate_in_run_cmd(self): 1047 extra_args = {constants.CUSTOM_ARGS: ['--a=b']} 1048 1049 cmd = self.tr.generate_run_commands([], extra_args) 1050 1051 self.assertTokensIn(['--a=b'], cmd[0]) 1052 1053 def test_args_with_multi_custom_args_and_generate_in_run_cmd(self): 1054 extra_args = {constants.CUSTOM_ARGS: ['--a=b', '--c=d']} 1055 1056 cmd = self.tr.generate_run_commands([], extra_args) 1057 1058 self.assertTokensIn(['--a=b', '--c=d'], cmd[0]) 1059 1060 def test_args_with_all_abi_and_generate_in_run_cmd(self): 1061 extra_args = {constants.ALL_ABI: True} 1062 1063 cmd = self.tr.generate_run_commands([], extra_args) 1064 1065 self.assertTokensIn(['--all-abi'], cmd[0]) 1066 1067 def test_args_with_dry_run_but_not_generate_in_run_cmd(self): 1068 extra_args = {constants.DRY_RUN: True} 1069 1070 cmd = self.tr.generate_run_commands([], extra_args) 1071 1072 self.assertTokensNotIn(['--dry-run'], cmd[0]) 1073 1074 def test_args_with_verify_env_variable_but_not_generate_in_run_cmd(self): 1075 extra_args = {constants.VERIFY_ENV_VARIABLE: True} 1076 1077 cmd = self.tr.generate_run_commands([], extra_args) 1078 1079 self.assertTokensNotIn(['--verify-env-variable'], cmd[0]) 1080 1081 def test_args_with_fakes_info_but_not_generate_in_run_cmd(self): 1082 extra_args = {constants.FLAKES_INFO: True} 1083 1084 cmd = self.tr.generate_run_commands([], extra_args) 1085 1086 self.assertTokensNotIn(['--flakes-info'], cmd[0]) 1087 1088 def test_args_with_instant_and_generate_in_run_cmd(self): 1089 extra_args = {constants.INSTANT: True} 1090 1091 cmd = self.tr.generate_run_commands([], extra_args) 1092 1093 self.assertTokensIn(['--enable-parameterized-modules', 1094 '--module-parameter', 'instant_app'], cmd[0]) 1095 1096 def test_args_with_user_type_and_generate_in_run_cmd(self): 1097 extra_args = {constants.USER_TYPE: 'hello_user'} 1098 1099 cmd = self.tr.generate_run_commands([], extra_args) 1100 1101 self.assertTokensIn(['--enable-parameterized-modules', 1102 '--enable-optional-parameterization', 1103 '--module-parameter', 'hello_user'], cmd[0]) 1104 1105 def test_args_with_iterations_and_generate_in_run_cmd(self): 1106 extra_args = {constants.ITERATIONS: 2} 1107 1108 cmd = self.tr.generate_run_commands([], extra_args) 1109 1110 self.assertIn('--retry-strategy ITERATIONS', cmd[0]) 1111 self.assertIn('--max-testcase-run-count 2', cmd[0]) 1112 1113 def test_args_with_retry_until_failure_and_generate_in_run_cmd(self): 1114 extra_args = {constants.RERUN_UNTIL_FAILURE: 2} 1115 1116 cmd = self.tr.generate_run_commands([], extra_args) 1117 1118 self.assertIn('--retry-strategy RERUN_UNTIL_FAILURE', cmd[0]) 1119 self.assertIn('--max-testcase-run-count 2', cmd[0]) 1120 1121 def test_args_with_retry_any_failure_and_generate_in_run_cmd(self): 1122 extra_args = {constants.RETRY_ANY_FAILURE: 2} 1123 1124 cmd = self.tr.generate_run_commands([], extra_args) 1125 1126 self.assertIn('--retry-strategy RETRY_ANY_FAILURE', cmd[0]) 1127 self.assertIn('--max-testcase-run-count 2', cmd[0]) 1128 1129 def test_args_with_collect_test_only_and_generate_in_run_cmd(self): 1130 extra_args = {constants.COLLECT_TESTS_ONLY: True} 1131 1132 cmd = self.tr.generate_run_commands([], extra_args) 1133 1134 self.assertTokensIn(['--collect-tests-only'], cmd[0]) 1135 1136 def test_args_with_no_enable_root_and_generate_in_run_cmd(self): 1137 extra_args = {constants.NO_ENABLE_ROOT: True} 1138 1139 cmd = self.tr.generate_run_commands([], extra_args) 1140 1141 self.assertTokensIn(['--no-enable-root'], cmd[0]) 1142 1143 def test_args_with_tf_template_but_not_generate_in_run_cmd(self): 1144 extra_args = {constants.TF_TEMPLATE: ['hello']} 1145 1146 cmd = self.tr.generate_run_commands([], extra_args) 1147 1148 self.assertTokensNotIn(['--tf-template'], cmd[0]) 1149 1150 def test_args_with_tf_early_device_release_but_not_generate_in_cmd(self): 1151 extra_args = {constants.TF_EARLY_DEVICE_RELEASE: True} 1152 1153 cmd = self.tr.generate_run_commands([], extra_args) 1154 1155 self.assertTokensNotIn(['--tf-early-device-release'], cmd[0]) 1156 1157 def test_args_with_timeout_and_generate_in_run_cmd(self): 1158 extra_args = {constants.TEST_TIMEOUT: 10000} 1159 1160 cmd = self.tr.generate_run_commands([], extra_args) 1161 1162 self.assertTokensIn( 1163 ['--test-arg', 1164 'com.android.tradefed.testtype.AndroidJUnitTest:' 1165 'shell-timeout:10000', 1166 '--test-arg', 1167 'com.android.tradefed.testtype.AndroidJUnitTest:' 1168 'test-timeout:10000', 1169 '--test-arg', 1170 'com.android.tradefed.testtype.HostGTest:' 1171 'native-test-timeout:10000', 1172 '--test-arg', 1173 'com.android.tradefed.testtype.GTest:' 1174 'native-test-timeout:10000'], 1175 cmd[0]) 1176 1177if __name__ == '__main__': 1178 unittest.main() 1179