Skip to content

GrpcPlugin

GrpcPlugin

GrpcPlugin(verifier)

Bases: BasePlugin

gRPC interception plugin.

Patches grpc.insecure_channel and grpc.secure_channel at the module level. Uses reference counting so nested sandboxes work correctly.

Each (call_type, method) pair has its own FIFO deque of GrpcMockConfig objects.

Source code in src/tripwire/plugins/grpc_plugin.py
def __init__(self, verifier: StrictVerifier) -> None:
    super().__init__(verifier)
    self._queues: dict[str, deque[GrpcMockConfig]] = {}
    self._registry_lock: threading.Lock = threading.Lock()

mock_unary_unary

mock_unary_unary(method, *, returns, raises=None, required=True)

Register a mock for a unary-unary gRPC call.

Source code in src/tripwire/plugins/grpc_plugin.py
def mock_unary_unary(
    self,
    method: str,
    *,
    returns: Any,  # noqa: ANN401
    raises: BaseException | None = None,
    required: bool = True,
) -> None:
    """Register a mock for a unary-unary gRPC call."""
    self._mock_call("unary_unary", method, returns=returns, raises=raises, required=required)

mock_unary_stream

mock_unary_stream(method, *, returns, raises=None, required=True)

Register a mock for a unary-stream (server streaming) gRPC call.

Source code in src/tripwire/plugins/grpc_plugin.py
def mock_unary_stream(
    self,
    method: str,
    *,
    returns: list[Any],
    raises: BaseException | None = None,
    required: bool = True,
) -> None:
    """Register a mock for a unary-stream (server streaming) gRPC call."""
    self._mock_call("unary_stream", method, returns=returns, raises=raises, required=required)

mock_stream_unary

mock_stream_unary(method, *, returns, raises=None, required=True)

Register a mock for a stream-unary (client streaming) gRPC call.

Source code in src/tripwire/plugins/grpc_plugin.py
def mock_stream_unary(
    self,
    method: str,
    *,
    returns: Any,  # noqa: ANN401
    raises: BaseException | None = None,
    required: bool = True,
) -> None:
    """Register a mock for a stream-unary (client streaming) gRPC call."""
    self._mock_call("stream_unary", method, returns=returns, raises=raises, required=required)

mock_stream_stream

mock_stream_stream(method, *, returns, raises=None, required=True)

Register a mock for a stream-stream (bidi streaming) gRPC call.

Source code in src/tripwire/plugins/grpc_plugin.py
def mock_stream_stream(
    self,
    method: str,
    *,
    returns: list[Any],
    raises: BaseException | None = None,
    required: bool = True,
) -> None:
    """Register a mock for a stream-stream (bidi streaming) gRPC call."""
    self._mock_call("stream_stream", method, returns=returns, raises=raises, required=required)

install_patches

install_patches()

Install gRPC channel patches.

Source code in src/tripwire/plugins/grpc_plugin.py
def install_patches(self) -> None:
    """Install gRPC channel patches."""
    if not _GRPC_AVAILABLE:
        raise ImportError(
            "Install python-tripwire[grpc] to use GrpcPlugin: pip install python-tripwire[grpc]"
        )
    GrpcPlugin._original_insecure_channel = grpc_lib.insecure_channel
    GrpcPlugin._original_secure_channel = grpc_lib.secure_channel
    grpc_lib.insecure_channel = _patched_insecure_channel
    grpc_lib.secure_channel = _patched_secure_channel

restore_patches

restore_patches()

Restore original gRPC channel functions.

Source code in src/tripwire/plugins/grpc_plugin.py
def restore_patches(self) -> None:
    """Restore original gRPC channel functions."""
    if GrpcPlugin._original_insecure_channel is not None:
        grpc_lib.insecure_channel = GrpcPlugin._original_insecure_channel
        GrpcPlugin._original_insecure_channel = None
    if GrpcPlugin._original_secure_channel is not None:
        grpc_lib.secure_channel = GrpcPlugin._original_secure_channel
        GrpcPlugin._original_secure_channel = None

matches

matches(interaction, expected)

Field-by-field comparison with dirty-equals support.

Source code in src/tripwire/plugins/grpc_plugin.py
def matches(self, interaction: Interaction, expected: dict[str, Any]) -> bool:
    """Field-by-field comparison with dirty-equals support."""
    try:
        for key, expected_val in expected.items():
            actual_val = interaction.details.get(key)
            if expected_val != actual_val:
                return False
        return True
    except Exception:
        return False

get_unused_mocks

get_unused_mocks()

Return all GrpcMockConfig with required=True still in any queue.

Source code in src/tripwire/plugins/grpc_plugin.py
def get_unused_mocks(self) -> list[GrpcMockConfig]:
    """Return all GrpcMockConfig with required=True still in any queue."""
    unused: list[GrpcMockConfig] = []
    with self._registry_lock:
        for queue in self._queues.values():
            for config in queue:
                if config.required:
                    unused.append(config)
    return unused

assert_unary_unary

assert_unary_unary(method, request, metadata=None, raised=_ABSENT)

Typed helper: assert the next unary_unary interaction.

Source code in src/tripwire/plugins/grpc_plugin.py
def assert_unary_unary(
    self,
    method: str,
    request: Any,  # noqa: ANN401
    metadata: Any = None,  # noqa: ANN401
    raised: Any = _ABSENT,  # noqa: ANN401
) -> None:
    """Typed helper: assert the next unary_unary interaction."""
    self._assert_call("unary_unary", method, request, metadata, raised)

assert_unary_stream

assert_unary_stream(method, request, metadata=None, raised=_ABSENT)

Typed helper: assert the next unary_stream interaction.

Source code in src/tripwire/plugins/grpc_plugin.py
def assert_unary_stream(
    self,
    method: str,
    request: Any,  # noqa: ANN401
    metadata: Any = None,  # noqa: ANN401
    raised: Any = _ABSENT,  # noqa: ANN401
) -> None:
    """Typed helper: assert the next unary_stream interaction."""
    self._assert_call("unary_stream", method, request, metadata, raised)

assert_stream_unary

assert_stream_unary(method, request, metadata=None, raised=_ABSENT)

Typed helper: assert the next stream_unary interaction.

Source code in src/tripwire/plugins/grpc_plugin.py
def assert_stream_unary(
    self,
    method: str,
    request: Any,  # noqa: ANN401
    metadata: Any = None,  # noqa: ANN401
    raised: Any = _ABSENT,  # noqa: ANN401
) -> None:
    """Typed helper: assert the next stream_unary interaction."""
    self._assert_call("stream_unary", method, request, metadata, raised)

assert_stream_stream

assert_stream_stream(method, request, metadata=None, raised=_ABSENT)

Typed helper: assert the next stream_stream interaction.

Source code in src/tripwire/plugins/grpc_plugin.py
def assert_stream_stream(
    self,
    method: str,
    request: Any,  # noqa: ANN401
    metadata: Any = None,  # noqa: ANN401
    raised: Any = _ABSENT,  # noqa: ANN401
) -> None:
    """Typed helper: assert the next stream_stream interaction."""
    self._assert_call("stream_stream", method, request, metadata, raised)