def add_snippet_client(self, name, package): """Adds a snippet client to the management. Args: name: string, the attribute name to which to attach the snippet client. E.g. `name='maps'` attaches the snippet client to `ad.maps`. package: string, the package name of the snippet apk to connect to. Raises: Error, if a duplicated name or package is passed in. """ # Should not load snippet with the same name more than once. if name in self._snippet_clients: raise Error( self, 'Name "%s" is already registered with package "%s", it cannot ' 'be used again.' % (name, self._snippet_clients[name].client.package)) # Should not load the same snippet package more than once. for snippet_name, client in self._snippet_clients.items(): if package == client.package: raise Error( self, 'Snippet package "%s" has already been loaded under name' ' "%s".' % (package, snippet_name)) client = snippet_client.SnippetClient(package=package, ad=self._device) client.start_app_and_connect() self._snippet_clients[name] = client
def load_snippet(self, name, package): """Starts the snippet apk with the given package name and connects. Examples: .. code-block:: python ad.load_snippet( name='maps', package='com.google.maps.snippets') ad.maps.activateZoom('3') Args: name: The attribute name to which to attach the snippet server. e.g. name='maps' will attach the snippet server to ad.maps. package: The package name defined in AndroidManifest.xml of the snippet apk. Raises: SnippetError: Illegal load operations are attempted. """ # Should not load snippet with the same attribute more than once. if name in self._snippet_clients: raise SnippetError( self, 'Attribute "%s" is already registered with package "%s", it ' 'cannot be used again.' % (name, self._snippet_clients[name].package)) # Should not load snippet with an existing attribute. if hasattr(self, name): raise SnippetError( self, 'Attribute "%s" already exists, please use a different name.' % name) # Should not load the same snippet package more than once. for client_name, client in self._snippet_clients.items(): if package == client.package: raise SnippetError( self, 'Snippet package "%s" has already been loaded under name' ' "%s".' % (package, client_name)) client = snippet_client.SnippetClient(package=package, ad=self) try: client.start_app_and_connect() except snippet_client.AppStartPreCheckError: # Precheck errors don't need cleanup, directly raise. raise except Exception as e: # Log the stacktrace of `e` as re-raising doesn't preserve trace. self.log.exception('Failed to start app and connect.') # If errors happen, make sure we clean up before raising. try: client.stop_app() except: self.log.exception( 'Failed to stop app after failure to start app and connect.' ) # Explicitly raise the error from start app failure. raise e self._snippet_clients[name] = client setattr(self, name, client)
def test_check_app_installed_fail_app_not_installed( self, mock_create_connection, mock_client_base): sc = snippet_client.SnippetClient(MOCK_PACKAGE_NAME, 42, MockAdbProxy(apk_not_installed=True)) expected_msg = '%s is not installed on .*' % MOCK_PACKAGE_NAME with self.assertRaisesRegexp(jsonrpc_client_base.AppStartError, expected_msg): sc.check_app_installed()
def load_snippet(self, name, package): """Starts the snippet apk with the given package name and connects. Examples: >>> ad.load_snippet( name='maps', package='com.google.maps.snippets') >>> ad.maps.activateZoom('3') Args: name: The attribute name to which to attach the snippet server. e.g. name='maps' will attach the snippet server to ad.maps. package: The package name defined in AndroidManifest.xml of the snippet apk. Raises: SnippetError is raised if illegal load operations are attempted. """ # Should not load snippet with the same attribute more than once. if name in self._snippet_clients: raise SnippetError( self, 'Attribute "%s" is already registered with package "%s", it ' 'cannot be used again.' % (name, self._snippet_clients[name].package)) # Should not load snippet with an existing attribute. if hasattr(self, name): raise SnippetError( self, 'Attribute "%s" already exists, please use a different name.' % name) # Should not load the same snippet package more than once. for client_name, client in self._snippet_clients.items(): if package == client.package: raise SnippetError( self, 'Snippet package "%s" has already been loaded under name' ' "%s".' % (package, client_name)) client = snippet_client.SnippetClient(package=package, adb_proxy=self.adb, log=self.log) try: client.start_app_and_connect() except Exception as e: # If errors happen, make sure we clean up before raising. try: client.stop_app() except: self.log.exception( 'Failed to stop app after failure to launch.') # Raise the error from start app failure. raise e self._snippet_clients[name] = client setattr(self, name, client)
def _make_client(self, adb_proxy=None): adb_proxy = adb_proxy or mock_android_device.MockAdbProxy( instrumented_packages=[(MOCK_PACKAGE_NAME, snippet_client._INSTRUMENTATION_RUNNER_PACKAGE, MOCK_PACKAGE_NAME)]) ad = mock.Mock() ad.adb = adb_proxy ad.adb.current_user_id = MOCK_USER_ID ad.build_info = { 'build_version_codename': ad.adb.getprop('ro.build.version.codename'), 'build_version_sdk': ad.adb.getprop('ro.build.version.sdk'), } return snippet_client.SnippetClient(package=MOCK_PACKAGE_NAME, ad=ad)
def test_snippet_stop_app_stops_event_client_without_connection( self, mock_stop_standing_subprocess, mock_create_connection): adb_proxy = mock.MagicMock() adb_proxy.shell.return_value = b'OK (0 tests)' client = self._make_client(adb_proxy) event_client = snippet_client.SnippetClient( package=MOCK_PACKAGE_NAME, ad=client._ad) client._event_client = event_client event_client._conn = None client.stop_app() self.assertFalse(client.is_alive) self.assertIsNone(client._event_client) self.assertIsNone(event_client._conn)
def load_snippet(self, name, package): """Starts the snippet apk with the given package name and connects. Examples: >>> ad = AndroidDevice() >>> ad.load_snippet( name='maps', package='com.google.maps.snippets') >>> ad.maps.activateZoom('3') Args: name: The attribute name to which to attach the snippet server. e.g. name='maps' will attach the snippet server to ad.maps. package: The package name defined in AndroidManifest.xml of the snippet apk. Raises: SnippetError is raised if illegal load operations are attempted. """ # Should not load snippet with the same attribute more than once. if name in self._snippet_clients: raise SnippetError( self, 'Attribute "%s" is already registered with package "%s", it ' 'cannot be used again.' % (name, self._snippet_clients[name].package)) # Should not load snippet with an existing attribute. if hasattr(self, name): raise SnippetError( self, 'Attribute "%s" already exists, please use a different name.' % name) # Should not load the same snippet package more than once. for client_name, client in self._snippet_clients.items(): if package == client.package: raise SnippetError( self, 'Snippet package "%s" has already been loaded under name' ' "%s".' % (package, client_name)) host_port = utils.get_available_host_port() client = snippet_client.SnippetClient( package=package, host_port=host_port, adb_proxy=self.adb, log=self.log) self._start_jsonrpc_client(client) self._snippet_clients[name] = client setattr(self, name, client)
def _make_client(self, adb_proxy=None): adb_proxy = adb_proxy or MockAdbProxy() ad = mock.Mock() ad.adb = adb_proxy return snippet_client.SnippetClient(package=MOCK_PACKAGE_NAME, ad=ad)
def test_check_app_installed_normal(self, mock_create_connection, mock_client_base): sc = snippet_client.SnippetClient(MOCK_PACKAGE_NAME, 42, MockAdbProxy()) sc.check_app_installed()
def _make_client(self, adb_proxy=MockAdbProxy()): return snippet_client.SnippetClient( package=MOCK_PACKAGE_NAME, adb_proxy=adb_proxy)