def testDisableSubEventLoggingNesting(self): """Tests the disable_subevent_logging option. Tests whether the top event's disable_subevent_logging can overwrite subevents of deeper levels when set to True. """ # Test top event disable_subevent_logging option set to True event = tfi.Begin(self.name, self.category, disable_subevent_logging=True) self.assertTrue(event._disable_subevent_logging) event_sub = tfi.Begin(self.name, self.category, disable_subevent_logging=False) self.assertTrue(event_sub._disable_subevent_logging) event_sub_sub1 = tfi.Begin(self.name, self.category) self.assertTrue(event_sub_sub1._disable_subevent_logging) event_sub_sub1.End() event_sub_sub2 = tfi.Begin(self.name, self.category, disable_subevent_logging=False) self.assertTrue(event_sub_sub2._disable_subevent_logging) event_sub_sub2.End() event_sub.End() event.End()
def main(): """Execute the test class in a test module. This is to be used in a test script's main so the script can be executed directly. It will discover all the classes that inherit from BaseTestClass and excute them. all the test results will be aggregated into one. A VTS host-driven test case has three args: 1st arg: the path of a test case config file. 2nd arg: the serial ID of a target device (device config). 3rd arg: the path of a test case data dir. Returns: The TestResult object that holds the results of the test run. """ event = tfi.Begin('Test runner main method') test_classes = [] main_module_members = sys.modules["__main__"] for _, module_member in main_module_members.__dict__.items(): if inspect.isclass(module_member): if issubclass(module_member, base_test.BaseTestClass): test_classes.append(module_member) # TODO(angli): Need to handle the case where more than one test class is in # a test script. The challenge is to handle multiple configs and how to do # default config in this case. if len(test_classes) != 1: logging.error("Expected 1 test class per file, found %s (%s).", len(test_classes), test_classes) sys.exit(1) test_result = runTestClass(test_classes[0]) event.End() tfi.CompileResults() return test_result
def testEndMatch(self): """Tests End command with name matching.""" event = tfi.Begin(self.name, self.category) self.assertEqual(event.status, 1) tfi.End(self.name, self.category) self.assertEqual(event.status, 2) self.assertIsNone(event.error)
def testEnableLogging(self): """Tests the enable_logging option.""" # Test not specified case event = tfi.Begin(self.name, self.category) self.assertFalse(event._enable_logging) event.End() # Test set to True case event = tfi.Begin(self.name, self.category, enable_logging=True) self.assertTrue(event._enable_logging) event.End() # Test set to False case event = tfi.Begin(self.name, self.category, enable_logging=None) self.assertFalse(event._enable_logging) event.End()
def testEndFromOtherModule(self): """Tests the use of End command from another module.""" event = tfi.Begin(self.name, self.category) self.assertEqual(event.status, 1) tfits.TestFrameworkInstrumentationTestSubmodule().End( self.name, self.category) self.assertEqual(event.status, 2) self.assertIsNone(event.error)
def testGenerateTextReport(self): """Tests the GenerateTextReport method.""" event = tfi.Begin('name1', 'cat1', disable_subevent_logging=True) event_sub = tfi.Begin('name2', 'cat2', disable_subevent_logging=False) event_sub.End() event.End() res = tfi.GenerateTextReport() # Checks result is not empty self.assertGreater(len(res), 0) # Since the format of the result is subject to change, here we only # checks whether the names and categories are mentioned in the result. self.assertIn('name1', res) self.assertIn('name2', res) self.assertIn('cat1', res) self.assertIn('cat2', res)
def testEndAlreadyEnded(self): """Tests End command on already ended event.""" event = tfi.Begin(self.name, self.category, enable_logging=False) event.End() self.assertEqual(event.status, 2) self.assertIsNone(event.error) event.End() self.assertEqual(event.status, 2) self.assertTrue(event.error)
def testEndAlreadyRemoved(self): """Tests End command on already ended event.""" event = tfi.Begin(self.name, self.category, enable_logging=False) reason = 'no reason' event.Remove(reason) self.assertEqual(event.status, 3) self.assertEqual(event.error, reason) event.End() self.assertEqual(event.status, 3) self.assertNotEqual(event.error, reason)
def unregisterControllers(self): """Destroy controller objects and clear internal registry. This will be called at the end of each TestRunner.run call. """ event = tfi.Begin('test_runner unregisterControllers', tfi.categories.FRAMEWORK_TEARDOWN) for name, destroy in self.controller_destructors.items(): try: logging.debug("Destroying %s.", name) dut = self.controller_destructors[name] destroy(self.controller_registry[name]) except: logging.exception("Exception occurred destroying %s.", name) self.controller_registry = {} self.controller_destructors = {} event.End()
def stopAdbLogcat(self): """Stops the adb logcat collection subprocess. """ if not self.isAdbLogcatOn: raise AndroidDeviceError( "Android device %s does not have an ongoing adb logcat collection." % self.serial) event = tfi.Begin("stop adb logcat from android_device", tfi.categories.FRAMEWORK_TEARDOWN) try: utils.stop_standing_subprocess(self.adb_logcat_process) except utils.VTSUtilsError as e: event.Remove("Cannot stop adb logcat. %s" % e) logging.error("Cannot stop adb logcat. %s", e) self.adb_logcat_process = None event.End()
def testCheckEnded(self): """Tests the CheckEnded method of TestFrameworkInstrumentationEvent""" event = tfi.Begin(self.name, self.category) # Verify initial condition self.assertTrue(bool(tfie.event_stack)) self.assertEqual(event.status, 1) event.CheckEnded() # Check event status is Remove self.assertEqual(event.status, 3) # Check event is removed from stack self.assertFalse(bool(tfie.event_stack)) # Check whether duplicate calls doesn't give error event.CheckEnded() self.assertEqual(event.status, 3)
def testDisableSubEventLoggingOverwriting(self): """Tests the disable_subevent_logging option's overwriting feature. Tests whether the top event's disable_subevent_logging overwrite subevent's disable_subevent_logging option only when it is set to True """ # Test top event disable_subevent_logging option not specified case event = tfi.Begin(self.name, self.category) self.assertFalse(event._disable_subevent_logging) event_sub = tfi.Begin(self.name, self.category, disable_subevent_logging=True) self.assertTrue(event_sub._disable_subevent_logging) event_sub.End() event.End() # Test top event disable_subevent_logging option set to False event = tfi.Begin(self.name, self.category, disable_subevent_logging=False) self.assertFalse(event._disable_subevent_logging) event_sub = tfi.Begin(self.name, self.category, disable_subevent_logging=True) self.assertTrue(event_sub._disable_subevent_logging) event_sub.End() event.End() # Test top event disable_subevent_logging option set to True event = tfi.Begin(self.name, self.category, disable_subevent_logging=True) self.assertTrue(event._disable_subevent_logging) event_sub1 = tfi.Begin(self.name, self.category, disable_subevent_logging=False) self.assertTrue(event_sub1._disable_subevent_logging) event_sub1.End() event_sub2 = tfi.Begin(self.name, self.category) self.assertTrue(event_sub2._disable_subevent_logging) event_sub2.End() event.End()
def startAdbLogcat(self): """Starts a standing adb logcat collection in separate subprocesses and save the logcat in a file. """ if self.isAdbLogcatOn: raise AndroidDeviceError(("Android device %s already has an adb " "logcat thread going on. Cannot start " "another one.") % self.serial) event = tfi.Begin("start adb logcat from android_device", tfi.categories.FRAMEWORK_SETUP) f_name = "adblog_%s_%s.txt" % (self.model, self.serial) utils.create_dir(self.log_path) logcat_file_path = os.path.join(self.log_path, f_name) try: extra_params = self.adb_logcat_param except AttributeError: extra_params = "-b all" cmd = "adb -s %s logcat -v threadtime %s >> %s" % ( self.serial, extra_params, logcat_file_path) self.adb_logcat_process = utils.start_standing_subprocess(cmd) self.adb_logcat_file_path = logcat_file_path event.End()
def startServices(self): """Starts long running services on the android device. 1. Start adb logcat capture. 2. Start VtsAgent and create HalMirror unless disabled in config. """ event = tfi.Begin("start vts services", tfi.categories.FRAMEWORK_SETUP) self.enable_vts_agent = getattr(self, "enable_vts_agent", True) try: self.startAdbLogcat() except Exception as e: msg = "Failed to start adb logcat!" event.Remove(msg) self.log.error(msg) self.log.exception(e) raise if self.enable_vts_agent: self.startVtsAgent() self.device_command_port = int( self.adb.shell("cat /data/local/tmp/vts_tcp_server_port")) logging.debug("device_command_port: %s", self.device_command_port) if not self.host_command_port: self.host_command_port = adb.get_available_host_port() self.adb.tcp_forward(self.host_command_port, self.device_command_port) self.hal = mirror_tracker.MirrorTracker(self.host_command_port, self.host_callback_port, True) self.lib = mirror_tracker.MirrorTracker(self.host_command_port) self.shell = mirror_tracker.MirrorTracker( host_command_port=self.host_command_port, adb=self.adb) self.shell.shell_default_nohup = self.shell_default_nohup self.resource = mirror_tracker.MirrorTracker( self.host_command_port) event.End()
def registerController(self, module, start_services=True): """Registers a controller module for a test run. This declares a controller dependency of this test class. If the target module exists and matches the controller interface, the controller module will be instantiated with corresponding configs in the test config file. The module should be imported first. Params: module: A module that follows the controller module interface. start_services: boolean, controls whether services (e.g VTS agent) are started on the target. Returns: A list of controller objects instantiated from controller_module. Raises: ControllerError is raised if no corresponding config can be found, or if the controller module has already been registered. """ event = tfi.Begin('test_runner registerController', tfi.categories.FRAMEWORK_SETUP) logging.debug("cwd: %s", os.getcwd()) logging.info("adb devices: %s", module.list_adb_devices()) self.verifyControllerModule(module) module_ref_name = module.__name__.split('.')[-1] if module_ref_name in self.controller_registry: event.End() raise signals.ControllerError( ("Controller module %s has already " "been registered. It can not be " "registered again.") % module_ref_name) # Create controller objects. create = module.create module_config_name = module.VTS_CONTROLLER_CONFIG_NAME if module_config_name not in self.testbed_configs: msg = "No corresponding config found for %s" % module_config_name event.Remove(msg) raise signals.ControllerError(msg) try: # Make a deep copy of the config to pass to the controller module, # in case the controller module modifies the config internally. original_config = self.testbed_configs[module_config_name] controller_config = copy.deepcopy(original_config) # Add log_severity config to device controller config. if isinstance(controller_config, list): for config in controller_config: if isinstance(config, dict): config["log_severity"] = self.log_severity logging.debug("controller_config: %s", controller_config) if "use_vts_agent" not in self.testbed_configs: objects = create(controller_config, start_services) else: objects = create(controller_config, self.testbed_configs["use_vts_agent"]) except: msg = "Failed to initialize objects for controller %s, abort!" % module_config_name event.Remove(msg) logging.error(msg) raise if not isinstance(objects, list): msg = "Controller module %s did not return a list of objects, abort." % module_ref_name event.Remove(msg) raise signals.ControllerError(msg) self.controller_registry[module_ref_name] = objects logging.debug("Found %d objects for controller %s", len(objects), module_config_name) destroy_func = module.destroy self.controller_destructors[module_ref_name] = destroy_func event.End() return objects
def startVtsAgent(self): """Start HAL agent on the AndroidDevice. This function starts the target side native agent and is persisted throughout the test run. """ self.log.info("Starting VTS agent") if self.vts_agent_process: raise AndroidDeviceError("HAL agent is already running on %s." % self.serial) event = tfi.Begin("start vts agent", tfi.categories.FRAMEWORK_SETUP) self._StopLLKD() event_cleanup = tfi.Begin("start vts agent -- cleanup", tfi.categories.FRAMEWORK_SETUP) cleanup_commands = [ "rm -f /data/local/tmp/vts_driver_*", "rm -f /data/local/tmp/vts_agent_callback*" ] kill_command = "pgrep 'vts_*' | xargs kill" cleanup_commands.append(kill_command) try: self.adb.shell("\"" + " ; ".join(cleanup_commands) + "\"") except adb.AdbError as e: self.log.warning( "A command to setup the env to start the VTS Agent failed %s", e) event_cleanup.End() log_severity = getattr(self, keys.ConfigKeys.KEY_LOG_SEVERITY, "INFO") bits = ['64', '32'] if self.is64Bit else ['32'] file_names = ['vts_hal_agent', 'vts_hal_driver', 'vts_shell_driver'] for bitness in bits: vts_agent_log_path = os.path.join( self.log_path, 'vts_agent_%s_%s.log' % (bitness, self.serial)) chmod_cmd = ' '.join( map( lambda file_name: 'chmod 755 {path}/{bit}/{file_name}{bit};'.format( path=DEFAULT_AGENT_BASE_DIR, bit=bitness, file_name=file_name), file_names)) cmd = ( 'adb -s {s} shell "{chmod} LD_LIBRARY_PATH={path}/{bitness} ' '{path}/{bitness}/vts_hal_agent{bitness} ' '--hal_driver_path_32={path}/32/vts_hal_driver32 ' '--hal_driver_path_64={path}/64/vts_hal_driver64 ' '--spec_dir={path}/spec ' '--shell_driver_path_32={path}/32/vts_shell_driver32 ' '--shell_driver_path_64={path}/64/vts_shell_driver64 ' '-l {severity}" >> {log} 2>&1').format( s=self.serial, chmod=chmod_cmd, bitness=bitness, path=DEFAULT_AGENT_BASE_DIR, log=vts_agent_log_path, severity=log_severity) try: self.vts_agent_process = utils.start_standing_subprocess( cmd, check_health_delay=1) break except utils.VTSUtilsError as e: logging.exception(e) with open(vts_agent_log_path, 'r') as log_file: logging.error("VTS agent output:\n") logging.error(log_file.read()) # one common cause is that 64-bit executable is not supported # in low API level devices. if bitness == '32': msg = "unrecognized bitness" event.Remove(msg) logging.error(msg) raise else: logging.error('retrying using a 32-bit binary.') event.End()