[Local Agent] b/282592569 Retrieve commission RPC request.
functional proof: https://paste.googleplex.com/5265599176376320
Test coverage: https://paste.googleplex.com/4949417630105600
Design Doc: go/ghts:dd:matter-enhance
Change-Id: I7ffe0b50f01dbdd69b025eb53948c653bd0959eb
diff --git a/local_agent/local_agent.py b/local_agent/local_agent.py
index 25398d1..5400fa1 100644
--- a/local_agent/local_agent.py
+++ b/local_agent/local_agent.py
@@ -50,6 +50,7 @@
'~/.config/google/local_agent_config.ini')
_START_TEST_SUITE_METHOD = 'startTestSuite'
_END_TEST_SUITE_METHOD = 'endTestSuite'
+_COMMISSION_TO_GOOGLE_FABRIC_METHOD = 'commissionToGoogleFabric'
_USER_CONFIG_ROOT_KEY = 'ServerConfig'
_USER_CONFIG_AMS_HOST = 'AMS_HOST'
_USER_CONFIG_AMS_PORT = 'AMS_PORT'
@@ -67,6 +68,8 @@
START_TEST_SUITE = enum.auto()
END_TEST_SUITE = enum.auto()
DEVICE_QUERY_CONTROL = enum.auto()
+ COMMISSION_TO_GOOGLE_FABRIC = enum.auto()
+
# ======================== Module level functions ========================== #
def rpc_request_type(method: str) -> RpcRequestType:
@@ -82,6 +85,8 @@
return RpcRequestType.START_TEST_SUITE
elif method == _END_TEST_SUITE_METHOD:
return RpcRequestType.END_TEST_SUITE
+ elif method == _COMMISSION_TO_GOOGLE_FABRIC_METHOD:
+ return RpcRequestType.COMMISSION_TO_GOOGLE_FABRIC
else:
return RpcRequestType.DEVICE_QUERY_CONTROL
# ========================================================================== #
@@ -323,6 +328,10 @@
elif req_type == RpcRequestType.DEVICE_QUERY_CONTROL:
resp = self._translator.dispatch_to_cmd_handler(rpc_request)
+ elif req_type == RpcRequestType.COMMISSION_TO_GOOGLE_FABRIC:
+ # TODO(b/282592569): Move commission_to_google_fabric out of translator.
+ resp = self._translator.commission_to_google_fabric(rpc_request)
+
else:
raise errors.InvalidRPCError(
f'Invalid RPC request type {req_type}.')
diff --git a/local_agent/tests/unit_tests/test_local_agent.py b/local_agent/tests/unit_tests/test_local_agent.py
index 184685b..6d05c94 100644
--- a/local_agent/tests/unit_tests/test_local_agent.py
+++ b/local_agent/tests/unit_tests/test_local_agent.py
@@ -39,9 +39,11 @@
_FAKE_RPC_RESPONSE = {'fake': 'response'}
_FAKE_RPC_ID = 'fake-rpc-id'
_FAKE_ERROR_MSG = 'fake-error-msg'
+_FAKE_COMMISSION_ERROR_MSG = 'Unable to commission the device.'
_FAKE_ARTIFACTS_DIR = 'fake-artifacts-dir'
_START_TEST_SUITE = 'startTestSuite'
_END_TEST_SUITE = 'endTestSuite'
+_COMMISSION_TO_GOOGLE_FABRIC = 'commissionToGoogleFabric'
_LOCK_DEVICE = 'setLock'
_FAKE_CONTROLLER_PACKAGE = 'FAKE_CONTROLLER_PACKAGE'
#############################################################################
@@ -612,6 +614,35 @@
self.assertEqual(_FAKE_RPC_RESPONSE, rpc_response)
mock_dispatch.assert_called_once_with(fake_rpc_request)
+ @mock.patch.object(
+ translation_layer.TranslationLayer, 'commission_to_google_fabric')
+ def test_handle_rpc_request_commission_to_google_fabric_on_success(self, mock_commission):
+ """Verifies handle_rpc_request to commission a device to google fabric on success."""
+ mock_commission.return_value = _FAKE_RPC_RESPONSE
+ fake_rpc_request = {'method': _COMMISSION_TO_GOOGLE_FABRIC}
+
+ rpc_response = self.proc._handle_rpc_request(fake_rpc_request)
+
+ self.assertEqual(_FAKE_RPC_RESPONSE, rpc_response)
+ mock_commission.assert_called_once_with(fake_rpc_request)
+
+ @mock.patch.object(translation_layer.TranslationLayer, 'commission_to_google_fabric')
+ def test_handle_rpc_request_returns_a_commissioning_error(
+ self, mock_commission
+ ):
+ """Verifies handle_rpc_request returns a commissioning error."""
+ mock_commission.side_effect = errors.InvalidRPCError(
+ _FAKE_COMMISSION_ERROR_MSG
+ )
+ fake_rpc_request = {
+ 'id': _FAKE_RPC_ID,
+ 'method': _COMMISSION_TO_GOOGLE_FABRIC,
+ }
+
+ rpc_response = self.proc._handle_rpc_request(fake_rpc_request)
+
+ self.assertIn(_FAKE_COMMISSION_ERROR_MSG, rpc_response['error']['message'])
+
@mock.patch.object(local_agent, 'rpc_request_type', return_value='')
def test_handle_rpc_request_invalid_rpc_type(self, mock_req_type):
"""Verifies handle_rpc_request on failure with invalid RPC type."""
diff --git a/local_agent/tests/unit_tests/test_translation_layer.py b/local_agent/tests/unit_tests/test_translation_layer.py
index ddfa844..f292b9c 100644
--- a/local_agent/tests/unit_tests/test_translation_layer.py
+++ b/local_agent/tests/unit_tests/test_translation_layer.py
@@ -28,8 +28,10 @@
_FAKE_DEVICE_TYPE = 'fake-device-type'
_FAKE_DEVICE_ID = 'fake-device-id'
_FAKE_CAPABILITY = 'fake-device-capability'
+_FAKE_PAIRING_CODE = 'fake-pairing-code'
_SET_ON = 'setOn'
_SET_LOCK = 'setLock'
+_COMMISSION_TO_GOOGLE_FABRIC = 'commissionToGoogleFabric'
##############################################################################
@@ -218,6 +220,21 @@
self.mock_client.send_rpc_response.assert_called_once()
self.assertTrue(self.translator.is_rpc_timeout(_FAKE_DEVICE_ID))
+ def test_commission_to_google_fabric_on_failure(self):
+ """Verifies commission_to_google_fabric throws an error when pairing code not found."""
+ invalid_rpc_request = rpc_request(_COMMISSION_TO_GOOGLE_FABRIC, {})
+ error_msg = 'Invalid rpc command, no pairingCode in params was found.'
+ with self.assertRaisesRegex(agent_errors.InvalidRPCError, error_msg):
+ self.translator.commission_to_google_fabric(invalid_rpc_request)
+
+ def test_commission_to_google_fabric_on_success(self):
+ """Verifies commission_to_google_fabric on success when pairing code is provided."""
+ valid_rpc_request = rpc_request(
+ _COMMISSION_TO_GOOGLE_FABRIC, {'pairingCode': _FAKE_PAIRING_CODE})
+ response = self.translator.commission_to_google_fabric(valid_rpc_request)
+
+ # Id is fake and it was made by `rpc_request` wrapper.
+ self.assertEqual(response, {'id': 0, 'jsonrpc': '2.0', 'result': {}})
if __name__ == '__main__':
unittest.main(failfast=True)
diff --git a/local_agent/translation_layer/translation_layer.py b/local_agent/translation_layer/translation_layer.py
index eeb02e6..5da05fe 100644
--- a/local_agent/translation_layer/translation_layer.py
+++ b/local_agent/translation_layer/translation_layer.py
@@ -280,3 +280,26 @@
'message': err_mesg}
self._ams_client.send_rpc_response(err_resp)
self._timeout_rpc.add(rpc_id)
+
+ def commission_to_google_fabric(self, rpc_request: dict[str, dict[str, str]]) -> dict[str, Any]:
+ """Subroutine for handling COMMISSION_TO_GOOGLE_FABRIC command.
+
+ Args:
+ rpc_request: JSON-RPC request.
+
+ Raises:
+ InvalidRPCError: Invalid RPC.
+
+ Returns:
+ RPC response.
+ """
+ pairing_code = rpc_request['params'].get('pairingCode')
+ if pairing_code is None:
+ raise agent_errors.InvalidRPCError(
+ 'Invalid rpc command, no pairingCode in params was found.')
+
+ request_id = rpc_request['id']
+ # TODO(b/282592569): Use this pairing code to commission a matter device on GHA.
+ logger.info(f'Completed request for {request_id}, pairingCode: {pairing_code}')
+
+ return {'id': request_id, 'jsonrpc': '2.0', 'result': {}}