grpc_mock 0.4.1 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +25 -0
- data/README.md +2 -2
- data/lib/grpc_mock/grpc_stub_adapter.rb +50 -11
- data/lib/grpc_mock/mocked_call.rb +77 -0
- data/lib/grpc_mock/mocked_operation.rb +5 -0
- data/lib/grpc_mock/response.rb +4 -4
- data/lib/grpc_mock/version.rb +1 -1
- metadata +8 -6
- data/.travis.yml +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2061779fc0f48faecd97933713277ba734d97c7d1581b0aee12899f54c1ec0c
|
4
|
+
data.tar.gz: 78ef2ecb1199bb9e0dedddcfb2aa32ac6d3af6afedd8055396600174d008e17a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d50395ad65d30b8284628ed6a26d1234c99767a4bc8bee47452ae8c018a6e43aadcbf08cc9a04d130c92f3c5c749be53260c823b1238ae2977aca0f135869f8c
|
7
|
+
data.tar.gz: 6d93f5de445f48b68128b4c0d4f01f287289fb2f63e882de12e2446500c7fe00682a6af858033e0aa3e531173b1dccae8b59527d2357a8950c8b5eba99ec0cfb
|
@@ -0,0 +1,25 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request: {}
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby-version:
|
15
|
+
- '2.5'
|
16
|
+
- '2.6'
|
17
|
+
- '2.7'
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v2
|
20
|
+
- uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby-version }}
|
23
|
+
bundler-cache: true
|
24
|
+
|
25
|
+
- run: 'bundle exec rake'
|
data/README.md
CHANGED
@@ -28,7 +28,7 @@ require 'grpc_mock/rspec'
|
|
28
28
|
|
29
29
|
## Examples
|
30
30
|
|
31
|
-
See definition of protocol buffers and gRPC generated code in [spec/
|
31
|
+
See definition of protocol buffers and gRPC generated code in [spec/examples/hello](https://github.com/ganmacs/grpc_mock/tree/master/spec/examples/hello)
|
32
32
|
|
33
33
|
### Stubbed request based on path and with the default response
|
34
34
|
|
@@ -52,7 +52,7 @@ client client.hello(Hello::HelloRequest.new(msg: 'hi')) # => Hello::HelloResp
|
|
52
52
|
### Responding dynamically to the stubbed requests
|
53
53
|
|
54
54
|
```ruby
|
55
|
-
GrpcMock.stub_request("/hello.hello/Hello").to_return do |req|
|
55
|
+
GrpcMock.stub_request("/hello.hello/Hello").to_return do |req, call|
|
56
56
|
Hello::HelloResponse.new(msg: "#{req.msg} too")
|
57
57
|
end
|
58
58
|
|
@@ -2,20 +2,30 @@
|
|
2
2
|
|
3
3
|
require 'grpc'
|
4
4
|
require 'grpc_mock/errors'
|
5
|
+
require 'grpc_mock/mocked_call'
|
5
6
|
|
6
7
|
module GrpcMock
|
7
8
|
class GrpcStubAdapter
|
8
9
|
# To make hook point for GRPC::ClientStub
|
9
10
|
# https://github.com/grpc/grpc/blob/bec3b5ada2c5e5d782dff0b7b5018df646b65cb0/src/ruby/lib/grpc/generic/service.rb#L150-L186
|
10
|
-
|
11
|
-
def request_response(method, request, *args)
|
11
|
+
module Adapter
|
12
|
+
def request_response(method, request, *args, metadata: {}, return_op: false, **kwargs)
|
12
13
|
unless GrpcMock::GrpcStubAdapter.enabled?
|
13
14
|
return super
|
14
15
|
end
|
15
16
|
|
16
17
|
mock = GrpcMock.stub_registry.response_for_request(method, request)
|
17
18
|
if mock
|
18
|
-
|
19
|
+
call = GrpcMock::MockedCall.new(metadata: metadata)
|
20
|
+
if return_op
|
21
|
+
operation = call.operation
|
22
|
+
operation.define_singleton_method(:execute) do
|
23
|
+
mock.evaluate(request, call.single_req_view)
|
24
|
+
end
|
25
|
+
operation
|
26
|
+
else
|
27
|
+
mock.evaluate(request, call.single_req_view)
|
28
|
+
end
|
19
29
|
elsif GrpcMock.config.allow_net_connect
|
20
30
|
super
|
21
31
|
else
|
@@ -24,7 +34,7 @@ module GrpcMock
|
|
24
34
|
end
|
25
35
|
|
26
36
|
# TODO
|
27
|
-
def client_streamer(method, requests, *args)
|
37
|
+
def client_streamer(method, requests, *args, metadata: {}, return_op: false, **kwargs)
|
28
38
|
unless GrpcMock::GrpcStubAdapter.enabled?
|
29
39
|
return super
|
30
40
|
end
|
@@ -32,7 +42,16 @@ module GrpcMock
|
|
32
42
|
r = requests.to_a # FIXME: this may not work
|
33
43
|
mock = GrpcMock.stub_registry.response_for_request(method, r)
|
34
44
|
if mock
|
35
|
-
|
45
|
+
call = GrpcMock::MockedCall.new(metadata: metadata)
|
46
|
+
if return_op
|
47
|
+
operation = call.operation
|
48
|
+
operation.define_singleton_method(:execute) do
|
49
|
+
mock.evaluate(r, call.multi_req_view)
|
50
|
+
end
|
51
|
+
operation
|
52
|
+
else
|
53
|
+
mock.evaluate(r, call.multi_req_view)
|
54
|
+
end
|
36
55
|
elsif GrpcMock.config.allow_net_connect
|
37
56
|
super
|
38
57
|
else
|
@@ -40,14 +59,22 @@ module GrpcMock
|
|
40
59
|
end
|
41
60
|
end
|
42
61
|
|
43
|
-
def server_streamer(method, request, *args)
|
62
|
+
def server_streamer(method, request, *args, metadata: {}, return_op: false, **kwargs)
|
44
63
|
unless GrpcMock::GrpcStubAdapter.enabled?
|
45
64
|
return super
|
46
65
|
end
|
47
66
|
|
48
67
|
mock = GrpcMock.stub_registry.response_for_request(method, request)
|
49
68
|
if mock
|
50
|
-
|
69
|
+
if return_op
|
70
|
+
operation = call.operation
|
71
|
+
operation.define_singleton_method(:execute) do
|
72
|
+
mock.evaluate(request, call.single_req_view)
|
73
|
+
end
|
74
|
+
operation
|
75
|
+
else
|
76
|
+
mock.evaluate(request, call.single_req_view)
|
77
|
+
end
|
51
78
|
elsif GrpcMock.config.allow_net_connect
|
52
79
|
super
|
53
80
|
else
|
@@ -55,7 +82,7 @@ module GrpcMock
|
|
55
82
|
end
|
56
83
|
end
|
57
84
|
|
58
|
-
def bidi_streamer(method, requests, *args)
|
85
|
+
def bidi_streamer(method, requests, *args, metadata: {}, return_op: false, **kwargs)
|
59
86
|
unless GrpcMock::GrpcStubAdapter.enabled?
|
60
87
|
return super
|
61
88
|
end
|
@@ -63,7 +90,15 @@ module GrpcMock
|
|
63
90
|
r = requests.to_a # FIXME: this may not work
|
64
91
|
mock = GrpcMock.stub_registry.response_for_request(method, r)
|
65
92
|
if mock
|
66
|
-
|
93
|
+
if return_op
|
94
|
+
operation = call.operation
|
95
|
+
operation.define_singleton_method(:execute) do
|
96
|
+
mock.evaluate(r, nil) # FIXME: provide BidiCall equivalent
|
97
|
+
end
|
98
|
+
operation
|
99
|
+
else
|
100
|
+
mock.evaluate(r, nil) # FIXME: provide BidiCall equivalent
|
101
|
+
end
|
67
102
|
elsif GrpcMock.config.allow_net_connect
|
68
103
|
super
|
69
104
|
else
|
@@ -71,8 +106,6 @@ module GrpcMock
|
|
71
106
|
end
|
72
107
|
end
|
73
108
|
end
|
74
|
-
GRPC.send(:remove_const, :ClientStub)
|
75
|
-
GRPC.send(:const_set, :ClientStub, AdapterClass)
|
76
109
|
|
77
110
|
def self.disable!
|
78
111
|
@enabled = false
|
@@ -95,3 +128,9 @@ module GrpcMock
|
|
95
128
|
end
|
96
129
|
end
|
97
130
|
end
|
131
|
+
|
132
|
+
module GRPC
|
133
|
+
class ClientStub
|
134
|
+
prepend GrpcMock::GrpcStubAdapter::Adapter
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grpc'
|
4
|
+
require 'grpc_mock/mocked_operation'
|
5
|
+
|
6
|
+
module GrpcMock
|
7
|
+
class MockedCall
|
8
|
+
attr_reader :deadline, :metadata
|
9
|
+
|
10
|
+
def initialize(metadata: {}, deadline: nil)
|
11
|
+
@metadata = sanitize_metadata(metadata)
|
12
|
+
@deadline = deadline
|
13
|
+
end
|
14
|
+
|
15
|
+
def multi_req_view
|
16
|
+
GRPC::ActiveCall::MultiReqView.new(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def single_req_view
|
20
|
+
GRPC::ActiveCall::SingleReqView.new(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def operation
|
24
|
+
GrpcMock::MockedOperation.new(self, metadata, deadline)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def sanitize_metadata(metadata)
|
30
|
+
# Largely based on
|
31
|
+
# - grpc_rb_md_ary_fill_hash_cb https://github.com/grpc/grpc/blob/v1.29.1/src/ruby/ext/grpc/rb_call.c#L390-L465
|
32
|
+
# - grpc_rb_md_ary_convert https://github.com/grpc/grpc/blob/v1.29.1/src/ruby/ext/grpc/rb_call.c#L490-L511
|
33
|
+
# - grpc_rb_md_ary_to_h https://github.com/grpc/grpc/blob/v1.29.1/src/ruby/ext/grpc/rb_call.c#L513-L541
|
34
|
+
# See also https://github.com/grpc/grpc/blob/v1.29.1/doc/PROTOCOL-HTTP2.md for specification
|
35
|
+
|
36
|
+
raise TypeError, "got <#{metadata.class}>, want <Hash>" unless metadata.is_a?(Hash)
|
37
|
+
|
38
|
+
headers = []
|
39
|
+
metadata.each do |key, value|
|
40
|
+
raise TypeError, "bad type for key parameter" unless key.is_a?(String) || key.is_a?(Symbol)
|
41
|
+
|
42
|
+
key = key.to_s
|
43
|
+
# https://github.com/grpc/grpc/blob/v1.29.1/src/core/lib/surface/validate_metadata.cc#L61-L79
|
44
|
+
raise ArgumentError, "'#{key}' is an invalid header key" unless key.match?(/\A[a-z0-9\-_.]+\z/) && key != ''
|
45
|
+
raise ArgumentError, "Header values must be of type string or array" unless value.is_a?(String) || value.is_a?(Array)
|
46
|
+
|
47
|
+
Array(value).each do |elem|
|
48
|
+
raise TypeError, "Header value must be of type string" unless elem.is_a?(String)
|
49
|
+
|
50
|
+
unless key.end_with?('-bin')
|
51
|
+
# Non-binary metadata are translated as plain HTTP2 headers, thus this requirement.
|
52
|
+
# https://github.com/grpc/grpc/blob/v1.29.1/src/core/lib/surface/validate_metadata.cc#L85-L92
|
53
|
+
raise ArgumentError, "Header value '#{elem}' has invalid characters" unless elem.match(/\A[ -~]+\z/)
|
54
|
+
|
55
|
+
# "ASCII-Value should not have leading or trailing whitespace. If it contains leading or trailing whitespace, it may be stripped."
|
56
|
+
# https://github.com/grpc/grpc/blob/v1.29.1/doc/PROTOCOL-HTTP2.md
|
57
|
+
elem = elem.strip
|
58
|
+
end
|
59
|
+
headers << [key, elem]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
metadata = {}
|
64
|
+
headers.each do |key, elem|
|
65
|
+
if metadata[key].nil?
|
66
|
+
metadata[key] = elem
|
67
|
+
elsif metadata[key].is_a?(Array)
|
68
|
+
metadata[key] << elem
|
69
|
+
else
|
70
|
+
metadata[key] = [metadata[key], elem]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
metadata
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/grpc_mock/response.rb
CHANGED
@@ -16,7 +16,7 @@ module GrpcMock
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def evaluate(_request = nil)
|
19
|
+
def evaluate(_request = nil, _call = nil)
|
20
20
|
raise @exception.dup
|
21
21
|
end
|
22
22
|
end
|
@@ -26,7 +26,7 @@ module GrpcMock
|
|
26
26
|
@value = value
|
27
27
|
end
|
28
28
|
|
29
|
-
def evaluate(_request = nil)
|
29
|
+
def evaluate(_request = nil, _call = nil)
|
30
30
|
@value.dup
|
31
31
|
end
|
32
32
|
end
|
@@ -36,8 +36,8 @@ module GrpcMock
|
|
36
36
|
@block = block
|
37
37
|
end
|
38
38
|
|
39
|
-
def evaluate(request)
|
40
|
-
@block.call(request)
|
39
|
+
def evaluate(request, call = nil)
|
40
|
+
@block.call(request, call)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
data/lib/grpc_mock/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grpc_mock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuta Iwama
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grpc
|
@@ -121,10 +121,10 @@ executables: []
|
|
121
121
|
extensions: []
|
122
122
|
extra_rdoc_files: []
|
123
123
|
files:
|
124
|
+
- ".github/workflows/ci.yml"
|
124
125
|
- ".gitignore"
|
125
126
|
- ".rspec"
|
126
127
|
- ".rubocop.yml"
|
127
|
-
- ".travis.yml"
|
128
128
|
- Gemfile
|
129
129
|
- LICENSE.txt
|
130
130
|
- README.md
|
@@ -140,6 +140,8 @@ files:
|
|
140
140
|
- lib/grpc_mock/grpc_stub_adapter.rb
|
141
141
|
- lib/grpc_mock/matchers/hash_argument_matcher.rb
|
142
142
|
- lib/grpc_mock/matchers/request_including_matcher.rb
|
143
|
+
- lib/grpc_mock/mocked_call.rb
|
144
|
+
- lib/grpc_mock/mocked_operation.rb
|
143
145
|
- lib/grpc_mock/request_pattern.rb
|
144
146
|
- lib/grpc_mock/request_stub.rb
|
145
147
|
- lib/grpc_mock/response.rb
|
@@ -151,7 +153,7 @@ homepage: https://github.com/ganmacs/grpc_mock
|
|
151
153
|
licenses:
|
152
154
|
- MIT
|
153
155
|
metadata: {}
|
154
|
-
post_install_message:
|
156
|
+
post_install_message:
|
155
157
|
rdoc_options: []
|
156
158
|
require_paths:
|
157
159
|
- lib
|
@@ -167,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
169
|
version: '0'
|
168
170
|
requirements: []
|
169
171
|
rubygems_version: 3.0.3
|
170
|
-
signing_key:
|
172
|
+
signing_key:
|
171
173
|
specification_version: 4
|
172
174
|
summary: Library for stubbing grpc in Ruby
|
173
175
|
test_files: []
|