diff --git a/mobly/controllers/android_device_lib/snippet_client_v2.py b/mobly/controllers/android_device_lib/snippet_client_v2.py index 33826092..ec3adab6 100644 --- a/mobly/controllers/android_device_lib/snippet_client_v2.py +++ b/mobly/controllers/android_device_lib/snippet_client_v2.py @@ -34,7 +34,7 @@ # The command template to start the snippet server _LAUNCH_CMD = ( - '{shell_cmd} am instrument {user} -w -e action start' + '{shell_cmd} {env_str} am instrument {user} -w -e action start' ' {instrument_options}' f' {{snippet_package}}/{_INSTRUMENTATION_RUNNER_PACKAGE}' ) @@ -111,12 +111,15 @@ class Config: other purposes may not take effect and you should use snippet RPCs. This is because Mobly snippet runner changes the subsequent instrumentation process. + env: A string of prefix options (e.g., environment variables or command + wrappers) prepended before the `am instrument` command. user_id: The user id under which to launch the snippet process. """ am_instrument_options: Dict[str, str] = dataclasses.field( default_factory=dict ) + env: str = '' user_id: Union[int, None] = None @@ -308,8 +311,10 @@ def start_server(self): _PROTOCOL_MINOR_VERSION, ) option_str = self._get_instrument_options_str() + env_str = self._config.env.strip() cmd = _LAUNCH_CMD.format( shell_cmd=persists_shell_cmd, + env_str=env_str, user=self._get_user_command_string(), snippet_package=self.package, instrument_options=option_str, diff --git a/tests/mobly/controllers/android_device_lib/snippet_client_v2_test.py b/tests/mobly/controllers/android_device_lib/snippet_client_v2_test.py index 7dc8a976..97cd8cef 100644 --- a/tests/mobly/controllers/android_device_lib/snippet_client_v2_test.py +++ b/tests/mobly/controllers/android_device_lib/snippet_client_v2_test.py @@ -511,7 +511,7 @@ def test_start_server_with_user_id(self, mock_adb, mock_start_subprocess): 'adb', 'shell', ( - f'setsid am instrument --user {MOCK_USER_ID} -w -e action start ' + f'setsid am instrument --user {MOCK_USER_ID} -w -e action start ' f'{MOCK_SERVER_PATH}' ), ] @@ -540,7 +540,7 @@ def test_start_server_with_config_specific_user_id( 'adb', 'shell', ( - 'setsid am instrument --user 42 -w -e action start ' + 'setsid am instrument --user 42 -w -e action start ' f'{MOCK_SERVER_PATH}' ), ] @@ -563,7 +563,7 @@ def test_start_server_without_user_id(self, mock_adb, mock_start_subprocess): start_cmd_list = [ 'adb', 'shell', - f'setsid am instrument -w -e action start {MOCK_SERVER_PATH}', + f'setsid am instrument -w -e action start {MOCK_SERVER_PATH}', ] self.assertListEqual( mock_start_subprocess.call_args_list, @@ -593,7 +593,7 @@ def test_start_server_without_persisting_commands( 'adb', 'shell', ( - f' am instrument --user {MOCK_USER_ID} -w -e action start ' + f' am instrument --user {MOCK_USER_ID} -w -e action start ' f'{MOCK_SERVER_PATH}' ), ] @@ -627,7 +627,7 @@ def _mocked_shell(arg): 'adb', 'shell', ( - f'nohup am instrument --user {MOCK_USER_ID} -w -e action start ' + f'nohup am instrument --user {MOCK_USER_ID} -w -e action start ' f'{MOCK_SERVER_PATH}' ), ] @@ -657,7 +657,7 @@ def _mocked_shell(arg): 'adb', 'shell', ( - f'setsid am instrument --user {MOCK_USER_ID} -w -e action start ' + f'setsid am instrument --user {MOCK_USER_ID} -w -e action start ' f'{MOCK_SERVER_PATH}' ), ] @@ -686,7 +686,7 @@ def test_start_server_with_instrument_options(self, mock_start_subprocess): 'adb', 'shell', ( - f' am instrument --user {MOCK_USER_ID} -w -e action start ' + f' am instrument --user {MOCK_USER_ID} -w -e action start ' f'{instrument_options_str} {MOCK_SERVER_PATH}' ), ] @@ -696,6 +696,34 @@ def test_start_server_with_instrument_options(self, mock_start_subprocess): ) self.assertEqual(self.client.device_port, 1234) + @mock.patch( + 'mobly.controllers.android_device_lib.snippet_client_v2.' + 'utils.start_standing_subprocess' + ) + def test_start_server_with_env(self, mock_start_subprocess): + """Checks the starting server command with env options.""" + config = snippet_client_v2.Config( + env='env CLASSPATH=foo', + ) + self._make_client(config=config) + self._mock_server_process_starting_response(mock_start_subprocess) + + self.client.start_server() + + start_cmd_list = [ + 'adb', + 'shell', + ( + f' env CLASSPATH=foo am instrument --user {MOCK_USER_ID} -w -e' + f' action start {MOCK_SERVER_PATH}' + ), + ] + self.assertListEqual( + mock_start_subprocess.call_args_list, + [mock.call(start_cmd_list, shell=False)], + ) + self.assertEqual(self.client.device_port, 1234) + @mock.patch( 'mobly.controllers.android_device_lib.snippet_client_v2.' 'utils.start_standing_subprocess'