camouflage icon indicating copy to clipboard operation
camouflage copied to clipboard

GRPC - cannot simulate gRPC error status, false positive mock response

Open szokebarnabas opened this issue 2 years ago • 2 comments

Describe the bug Hi, apologies in advance if the answer to my question is trivial but I don't have any experience with gRpc and protobufs.

What I would like to achieve is:

  • Simulate an error status (e.g return standard gRPC error codes: https://grpc.github.io/grpc/core/md_doc_statuscodes.html): It's not documented in camouflage and I did not manage to create an error stub using this spec: https://cloud.google.com/apis/design/errors
  • Simulate a successful response - it's working but I cannot define request patterns in the stubs

To Reproduce Steps to reproduce the behavior:

  1. Mock File Content
https://github.com/stargate/stargate/tree/master/grpc-proto/proto
  1. File structure:

mocks:

./mocks/stargate/Stargate/ExecuteBatch.mock

protos:

./protos/query.proto
./protos/stargate.proto
  1. Docker-compose:
version: "3.9"
networks:
  camouflage:
    driver: bridge

volumes:
  prometheus_data: {}
  grafana_data: {}
  camouflage_data: {}

services:
  camouflage_ui:
    image: shubhendumadhukar/camouflage-filemanager:latest
    container_name: camouflage_ui_2
    volumes:
      - camouflage_data:/opt/virtual_services
    environment:
      FS_ROOT: /opt/virtual_services
      WRITE_PROTECTED: "false"
      PORT: 3001
    ports:
      - "3001:3001"
    labels:
      org.label-schema.group: "camouflage"

  camouflage:
    image: shubhendumadhukar/camouflage:latest
    container_name: camouflage_2
    volumes:
       - ./protos:/app/grpc/protos
       - ./mocks:/app/grpc/mocks
       - ./config/config.yml:/app/config.yml
       - ./config/.protoignore:/app/.protoignore
    restart: unless-stopped
    ports:
      - "8080:8080"
      - "8443:8443"
      - "8081:8081"
      - "4312:4312"
      - "8082:8082"
      - "5555:5555"
    networks:
      - camouflage
    labels:
      org.label-schema.group: "camouflage"

  1. ExecuteBatch.mock:
{
  "warnings": [
    "hello"
  ],
  "schema_change": {
    "change_type": "CREATED"
  },
  "result_set": {
    "columns": [
      {
        "name": "my column",
        "type": {
          "basic": "ASCII"
        }
      }
    ],
    "rows": [
      {
        "values": [
          {
            "string": "hello world"
          }
        ]
      }
    ]
  }
}
  1. Execute the following gRpc request:
grpcurl -v -d '{"queries":[{"cql":"UPDATE bookmarking.bookmarks USING TTL :ttl AND TIMESTAMP :timestamp SET streamPosition = :streamposition, created = :created WHERE pvid = :pvid AND providerterritory = :providerterritory AND provider = :provider AND householdId = :householdid AND timeBucket = :timebucket and personaId = :personaid;"}]}' -proto query.proto -proto stargate.proto -plaintext localhost:4312 stargate.Stargate/ExecuteBatch

Response:

Resolved method descriptor:
// Executes a batch of CQL queries.
rpc ExecuteBatch ( .stargate.Batch ) returns ( .stargate.Response );

Request metadata to send:
(empty)

Response headers received:
content-type: application/grpc+proto
date: Fri, 02 Sep 2022 07:38:52 GMT
grpc-accept-encoding: identity,deflate,gzip

Response contents:
{
  "warnings": [
    "hello"
  ],
  "schemaChange": {
    "changeType": "DROPPED"
  }
}

Response trailers received:
(empty)
Sent 1 request and received 1 response

Expected behavior It's should be possible to define request matchers and return responses accordingly.

Thanks, Barnabas

szokebarnabas avatar Sep 02 '22 07:09 szokebarnabas

Hi @szokebarnabas,

It's should be possible to define request matchers and return responses accordingly.

Could you please elaborate with an example, what kind of request matchers are you referring to?

shubhendumadhukar avatar Sep 02 '22 13:09 shubhendumadhukar

I'm unsure if this is a bug or if this isn't documented or supported.

Take HTTP: Camouflage mocks HTTP by having you provide the entire HTTP response in your *.mock file, including status code headers, etc. This would allow me to test scenarios like when the server responds with a HTTP 400, then I can verify my app behaves accordingly.

Similarly in gRPC we have status codes and I may want to do the same thing where I configure camouflage to return GRPC 16 "Unauthorized" so that I can verify my app behaves accordingly when such a thing happens. I don't see it documented.

Since I'm proxying with envoy to camouflage, I also would like to set headers but I know I may be asking for too much there.

scvnc avatar Oct 03 '22 17:10 scvnc