Repository navigation
Update adb connect method to disconnect first - #1072
kavitha-subr wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces an adb disconnect method and updates connect to flush stale socket states by disconnecting first. It also adds a reconnection mechanism for TCP devices during adb root retries, along with corresponding unit tests. The review feedback highlights a critical issue where calling self._exec_adb_cmd on an AdbProxy instance with a serial set will incorrectly prepend -s <serial> to global commands like connect and disconnect. The reviewer suggests using a serial-less AdbProxy instance for these commands and updating the tests to verify that they are executed without the serial prefix.
| return self._exec_adb_cmd( | ||
| 'disconnect', address, shell=False, timeout=None, stderr=None | ||
| ) |
There was a problem hiding this comment.
Calling self._exec_adb_cmd on an AdbProxy instance that has self.serial set will prepend -s <serial> to the adb disconnect command. Since adb disconnect is a global command and does not target a specific device via -s (and will fail if the device is offline/disconnected), it should be executed using a serial-less AdbProxy instance.
| return self._exec_adb_cmd( | |
| 'disconnect', address, shell=False, timeout=None, stderr=None | |
| ) | |
| return AdbProxy()._exec_adb_cmd( | |
| 'disconnect', address, shell=False, timeout=None, stderr=None | |
| ) |
| stdout = self._exec_adb_cmd( | ||
| 'connect', address, shell=False, timeout=None, stderr=None | ||
| ) |
There was a problem hiding this comment.
Calling self._exec_adb_cmd on an AdbProxy instance that has self.serial set will prepend -s <serial> to the adb connect command. Since adb connect is a global command and does not target a specific device via -s (and will fail with a 'device not found' error if the device is offline/disconnected), it should be executed using a serial-less AdbProxy instance.
| stdout = self._exec_adb_cmd( | |
| 'connect', address, shell=False, timeout=None, stderr=None | |
| ) | |
| stdout = AdbProxy()._exec_adb_cmd( | |
| 'connect', address, shell=False, timeout=None, stderr=None | |
| ) |
| def test_connect_ignores_disconnect_error(self, mock_run_command): | ||
| mock_address = 'localhost:1234' | ||
| mock_run_command.side_effect = [ | ||
| (1, b'', b'error: no such device'), | ||
| (0, f'connected to {mock_address}'.encode('utf-8'), b''), | ||
| ] | ||
| out = adb.AdbProxy().connect(mock_address) | ||
| self.assertEqual('connected to localhost:1234', out.decode('utf-8')) | ||
| self.assertEqual(mock_run_command.call_count, 2) |
There was a problem hiding this comment.
Update the test to instantiate AdbProxy with a serial and assert that run_command is called without the -s prefix. This ensures that connect and disconnect remain global commands and do not incorrectly target a specific device serial.
@mock.patch('mobly.utils.run_command')
def test_connect_ignores_disconnect_error(self, mock_run_command):
mock_address = 'localhost:1234'
mock_run_command.side_effect = [
(1, b'', b'error: no such device'),
(0, f'connected to {mock_address}'.encode('utf-8'), b''),
]
out = adb.AdbProxy(mock_address).connect(mock_address)
self.assertEqual('connected to localhost:1234', out.decode('utf-8'))
self.assertEqual(mock_run_command.call_count, 2)
mock_run_command.assert_has_calls([
mock.call(['adb', 'disconnect', mock_address], shell=False, timeout=None),
mock.call(['adb', 'connect', mock_address], shell=False, timeout=None),
])|
Thanks for the detailed investigation and for validating this against your lab. We discussed this on mobly-eng and are going to decline this change; closing the PR. Summary of the reasoning: The diagnosis doesn't match how the host adb server works. The host The log in b/483347888#comment3 shows a different primary failure. The first The A/B result doesn't isolate the variable. The patched code only runs after the first attempt has already failed and adds a 10 s sleep + disconnect + connect before retrying; any change that lets the device finish restarting before the retry would show the same improvement. A control run with only the root timeout raised (no disconnect/connect) would be needed to attribute the gain to the disconnect. The change itself is risky for other users. Recommendation: investigate on the SDV side what terminates |
|
Closing per the discussion above and on mobly-eng. |
Tests experience device not found / device offline errors when a adb.root() is performed after a reboot. When adbd restarts as root, the host ADB server likely holds a stale connection causing this issue.
This PR updates introduces a "connect" attempt in cases of such errors for TCP connections. The connect method first attempts to disconnect the connection and then connect to ensure any stale connections are flushed.