[sonic-py-common] Add gRPC framework with gNOI client#26473
Open
sigabrtv1-ui wants to merge 4 commits into
Open
[sonic-py-common] Add gRPC framework with gNOI client#26473sigabrtv1-ui wants to merge 4 commits into
sigabrtv1-ui wants to merge 4 commits into
Conversation
Collaborator
|
/azp run Azure.sonic-buildimage |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Add sonic_py_common.grpc — a reusable gRPC framework for SONiC Python
components, starting with gNOI support.
Structure:
sonic_py_common/
grpc/ # gRPC framework root
__init__.py # future: gnmi, gribi sub-packages
gnoi/ # gNOI services
__init__.py
client.py # GnoiClient - channel manager + service stubs
system_pb2.py # vendored proto stubs (openconfig/gnoi)
system_pb2_grpc.py
types_pb2.py
types_pb2_grpc.py
common_pb2.py
common_pb2_grpc.py
GnoiClient is service-agnostic: stubs accessed via properties
(client.system, with scaffolding for healthz/cert/file/os).
The grpc/ namespace leaves room for gnmi/ and gribi/ sub-packages.
Dependencies: grpcio, protobuf (already used by other SONiC components).
Signed-off-by: sigabrtv1-ui <sig.abrt.v1@gmail.com>
Signed-off-by: Dawei Huang <daweihuang@microsoft.com>
2dc389d to
2585cd8
Compare
Collaborator
|
/azp run Azure.sonic-buildimage |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Add sonic_py_common.grpc.gnoi.testing with:
- FakeSystemStub: controllable System service stub with injectable
responses, side_effects (including sequences for polling scenarios),
and call history for assertions
- FakeGnoiClient: drop-in replacement for GnoiClient with no real
gRPC connections, same context manager protocol
Consumers can write tests like:
fake = FakeGnoiClient()
fake.system.set_reboot_status(active=False, status=STATUS_SUCCESS)
with patch('my_module.GnoiClient', return_value=fake):
assert my_reboot_function() == True
assert len(fake.system.reboot_calls) == 1
12 new tests for the fake itself.
Signed-off-by: sigabrtv1-ui <sig.abrt.v1@gmail.com>
Signed-off-by: Dawei Huang <daweihuang@microsoft.com>
Collaborator
|
/azp run Azure.sonic-buildimage |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Replace mock-based testing with a real gRPC fake server: - FakeGnoiServer: starts a real gRPC server on localhost with controllable service implementations. Tests use the real GnoiClient connecting over a real channel — no mocking of gRPC internals. - FakeSystemServicer: configurable System service with: - set_reboot_response() / set_reboot_status() for single responses - set_reboot_status_sequence() for polling scenarios (active→done) - Error injection via grpc.StatusCode - Call history for assertions (reboot_calls, etc.) - reset() to clear state between tests - Rewrote all client tests to use FakeGnoiServer (no sys.modules mocking) 19 tests, all using real gRPC. Zero mocks. Signed-off-by: sigabrtv1-ui <sig.abrt.v1@gmail.com> Signed-off-by: Dawei Huang <daweihuang@microsoft.com>
Collaborator
|
/azp run Azure.sonic-buildimage |
|
Azure Pipelines successfully started running 1 pipeline(s). |
The generated protobuf stubs were created with protobuf 6.31.1 which uses 'runtime_version' import not available in the build image's protobuf 4.25.9. Regenerated using grpcio-tools 1.60.1 + protobuf 4.25.9 for compatibility with the SONiC build environment. Signed-off-by: Dawei Huang <daweihuang@microsoft.com>
Collaborator
|
/azp run Azure.sonic-buildimage |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Contributor
|
@vaibhavhd can you review this PR |
hdwhdw
approved these changes
May 11, 2026
Contributor
|
@qiluo-msft that's my bot so someone else should review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What I did
Added
sonic_py_common.gnoi— a reusable gNOI gRPC client framework that any SONiC Python component can use.Why I did it
Today,
gnoi_shutdown_daemonin sonic-host-services shells out todocker exec gnmi gnoi_clientwhich has:"reboot complete"against JSON output that never contains itsuppress_stderr=TrueOther components (pmon, sonic-utilities) may also need gNOI access. A shared framework in sonic-py-common avoids duplicating gRPC boilerplate across repos.
How I did it
sonic_py_common/gnoi/:GnoiClient— thin gRPC channel manager with service stubs as properties (client.system, extensible forclient.healthz,client.cert, etc.)system_pb2,types_pb2,common_pb2generated from openconfig/gnoi. Vendored because sonic-py-common has no proto compilation infra and gNOI System proto is stable.setup.py: addedgrpcio/protobufto deps andsonic_py_common.gnoito packages.Usage
How to verify
cd src/sonic-py-common python3 -m pytest tests/test_gnoi_client.py -vDependencies
grpcioandprotobuf— already used by other SONiC componentsRelated