tshield 0.11.10.0 → 0.11.16.0
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/Gemfile +0 -1
- data/README.md +37 -6
- data/Rakefile +1 -1
- data/bin/tshield +2 -11
- data/config/tshield.yml +7 -0
- data/lib/tshield.rb +1 -1
- data/lib/tshield/configuration.rb +5 -0
- data/lib/tshield/controllers/requests.rb +3 -3
- data/lib/tshield/extensions/string_extensions.rb +8 -0
- data/lib/tshield/grpc.rb +73 -0
- data/lib/tshield/grpc/vcr.rb +70 -0
- data/lib/tshield/server.rb +18 -1
- data/lib/tshield/version.rb +1 -1
- data/spec/spec_helper.rb +0 -5
- data/spec/tshield/configuration_spec.rb +19 -0
- data/spec/tshield/fixtures/config/tshield-without-grpc.yml +17 -0
- data/spec/tshield/fixtures/config/tshield.yml +2 -0
- data/spec/tshield/fixtures/proto/test_services_pb.rb +13 -0
- data/spec/tshield/grpc_spec.rb +24 -0
- data/tshield.gemspec +5 -1
- metadata +96 -9
- data/lib/tshield/simple_tcp_server.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6430dfd31f893ec3e51fc02ad401ea29f9dbcfa09c9b34a30ef4e23b7b9a3216
|
4
|
+
data.tar.gz: 1f021ab7cc8688ee6ab077140d34dd239a76a578c0c738b639a974d36d91d48d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b86bd18dc24834098e199e179d33a92b74b29a55fa495685e2939196c6f4be9558a324ee7b63590363bf3c0ec5deb512073c172ac828a2eea6f19f3ed842d77d
|
7
|
+
data.tar.gz: 597db12ad099b8024841fd6f6e9d5b9eb2954750d617382c95654a930273558b44c18fc4f8a3ea67b3d9d66a7820b1dc2ddfe462b2eac591de67683db3c213f3
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -13,9 +13,10 @@ TShield is an open source proxy for mocks API responses.
|
|
13
13
|
* REST
|
14
14
|
* SOAP
|
15
15
|
* Session manager to separate multiple scenarios (success, error, sucess variation, ...)
|
16
|
+
gRPC [EXPERIMENTAL]
|
16
17
|
* Lightweight
|
17
18
|
* MIT license
|
18
|
-
|
19
|
+
|
19
20
|
## Table of Contents
|
20
21
|
|
21
22
|
* [Basic Usage](#basic-usage)
|
@@ -26,7 +27,7 @@ TShield is an open source proxy for mocks API responses.
|
|
26
27
|
* [Features](#features)
|
27
28
|
* [Examples](#examples)
|
28
29
|
* [Contributing](#contributing)
|
29
|
-
|
30
|
+
|
30
31
|
## Basic Usage
|
31
32
|
### Install
|
32
33
|
|
@@ -37,7 +38,7 @@ TShield is an open source proxy for mocks API responses.
|
|
37
38
|
To run server execute this command
|
38
39
|
|
39
40
|
tshield
|
40
|
-
|
41
|
+
|
41
42
|
Default port is `4567`
|
42
43
|
|
43
44
|
#### Command Line Options
|
@@ -102,7 +103,7 @@ To register stub into a session create an object with following attributes:
|
|
102
103
|
* **session**: name of session.
|
103
104
|
* **stubs**: an array with objects described above.
|
104
105
|
|
105
|
-
### Example of matching configuration
|
106
|
+
### Example of HTTP matching configuration
|
106
107
|
|
107
108
|
```json
|
108
109
|
[
|
@@ -163,7 +164,7 @@ To register stub into a session create an object with following attributes:
|
|
163
164
|
]
|
164
165
|
```
|
165
166
|
|
166
|
-
## Config options for VCR
|
167
|
+
## Config options for HTTP VCR
|
167
168
|
```yaml
|
168
169
|
request:
|
169
170
|
timeout: 8
|
@@ -227,7 +228,7 @@ You can use TShield sessions to separate multiple scenarios for your mocks
|
|
227
228
|
By default TShield save request/response into
|
228
229
|
|
229
230
|
requests/<<domain_name>>/<<resource_with_param>>/<<http_verb>>/<<index_based.content and json>>
|
230
|
-
|
231
|
+
|
231
232
|
If you start a session a folder with de **session_name** will be placed between **"requests/"** and **"<<domain_name>>"**
|
232
233
|
|
233
234
|
### Start TShield session
|
@@ -249,6 +250,36 @@ _DELETE_ to http://localhost:4567/sessions
|
|
249
250
|
curl -X DELETE \
|
250
251
|
http://localhost:4567/sessions
|
251
252
|
```
|
253
|
+
## [Experimental] Config options for gRPC
|
254
|
+
|
255
|
+
```yaml
|
256
|
+
grpc:
|
257
|
+
port: 5678
|
258
|
+
proto_dir: 'proto'
|
259
|
+
services:
|
260
|
+
'helloworld_services_pb':
|
261
|
+
module: 'Helloworld::Greeter'
|
262
|
+
hostname: '0.0.0.0:50051'
|
263
|
+
```
|
264
|
+
|
265
|
+
|
266
|
+
### Not Implemented Yet
|
267
|
+
|
268
|
+
- Sessions
|
269
|
+
- Matching
|
270
|
+
|
271
|
+
### Configuration
|
272
|
+
|
273
|
+
First, generate ruby files from proto files. Use `grpc_tools_ruby_protoc`
|
274
|
+
present in the gem `grpc-tools`. Example:
|
275
|
+
|
276
|
+
`grpc_tools_ruby_protoc -I proto --ruby_out=proto --grpc_out=proto proto/<INPUT>.proto`
|
277
|
+
|
278
|
+
Call example in component_tests using [grpcurl](https://github.com/fullstorydev/grpcurl):
|
279
|
+
|
280
|
+
`grpcurl -plaintext -import-path component_tests/proto -proto helloworld.proto -d '{"name": "teste"}' localhost:5678 helloworld.Greeter/SayHello`
|
281
|
+
|
282
|
+
### Using in VCR mode
|
252
283
|
|
253
284
|
## Custom controllers
|
254
285
|
|
data/Rakefile
CHANGED
data/bin/tshield
CHANGED
@@ -5,14 +5,5 @@ require 'tshield/options'
|
|
5
5
|
TShield::Options.init
|
6
6
|
|
7
7
|
require 'tshield'
|
8
|
-
|
9
|
-
|
10
|
-
configuration = TShield::Configuration.load_configuration
|
11
|
-
(configuration.tcp_servers || []).each do |tcp_server|
|
12
|
-
puts "initializing #{tcp_server['name']}"
|
13
|
-
require "./servers/#{tcp_server['file']}"
|
14
|
-
klass = Object.const_get(tcp_server['name'])
|
15
|
-
Thread.new { klass.new.listen(tcp_server['port']) }
|
16
|
-
end
|
17
|
-
|
18
|
-
tshield.join
|
8
|
+
Thread.new { TShield::Server.run! }
|
9
|
+
TShield::Grpc.run!
|
data/config/tshield.yml
CHANGED
data/lib/tshield.rb
CHANGED
@@ -103,6 +103,11 @@ module TShield
|
|
103
103
|
session_path || '/sessions'
|
104
104
|
end
|
105
105
|
|
106
|
+
def grpc
|
107
|
+
defaults = { 'port' => 5678, 'proto_dir' => 'proto', 'services' => {} }
|
108
|
+
defaults.merge(@grpc || {})
|
109
|
+
end
|
110
|
+
|
106
111
|
def self.get_url_for_domain_by_path(path, config)
|
107
112
|
config['paths'].select { |pattern| path =~ Regexp.new(pattern) }[0]
|
108
113
|
end
|
@@ -65,7 +65,7 @@ module TShield
|
|
65
65
|
api_response = TShield::RequestMatching.new(path, options.clone).match_request
|
66
66
|
|
67
67
|
unless api_response
|
68
|
-
add_headers(
|
68
|
+
add_headers(options, path)
|
69
69
|
|
70
70
|
api_response ||= TShield::RequestVCR.new(path, options.clone).response
|
71
71
|
api_response.headers.reject! do |key, _v|
|
@@ -85,9 +85,9 @@ module TShield
|
|
85
85
|
body api_response.body
|
86
86
|
end
|
87
87
|
|
88
|
-
def add_headers(
|
88
|
+
def add_headers(options, path)
|
89
89
|
(configuration.get_headers(domain(path)) || {}).each do |source, destiny|
|
90
|
-
headers[destiny] = request.env[source] if request.env[source]
|
90
|
+
options[:headers][destiny] = request.env[source] if request.env[source]
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -5,6 +5,14 @@ module StringExtensions
|
|
5
5
|
def to_rack_name
|
6
6
|
"HTTP_#{upcase.tr('-', '_')}"
|
7
7
|
end
|
8
|
+
|
9
|
+
def underscore
|
10
|
+
gsub(/::/, '/')
|
11
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
12
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
13
|
+
.tr('-', '_')
|
14
|
+
.downcase
|
15
|
+
end
|
8
16
|
end
|
9
17
|
|
10
18
|
String.include StringExtensions
|
data/lib/tshield/grpc.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'grpc'
|
4
|
+
|
5
|
+
require 'tshield/configuration'
|
6
|
+
require 'tshield/sessions'
|
7
|
+
require 'tshield/grpc/vcr'
|
8
|
+
|
9
|
+
module TShield
|
10
|
+
module Grpc
|
11
|
+
module RequestHandler
|
12
|
+
include TShield::Grpc::VCR
|
13
|
+
def handler(method_name, request)
|
14
|
+
options = self.class.options
|
15
|
+
handler_in_vcr_mode(method_name, request, options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def self.run!
|
19
|
+
@configuration = TShield::Configuration.singleton.grpc
|
20
|
+
|
21
|
+
lib_dir = File.join(Dir.pwd, @configuration['proto_dir'])
|
22
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
23
|
+
|
24
|
+
TShield.logger.info("loading proto files from #{lib_dir}")
|
25
|
+
|
26
|
+
bind = "0.0.0.0:#{@configuration['port']}"
|
27
|
+
|
28
|
+
server = GRPC::RpcServer.new
|
29
|
+
server.add_http2_port(bind, :this_port_is_insecure)
|
30
|
+
|
31
|
+
services = load_services(@configuration['services'])
|
32
|
+
services.each do |class_service|
|
33
|
+
class_service.include RequestHandler
|
34
|
+
server.handle(class_service)
|
35
|
+
end
|
36
|
+
|
37
|
+
server.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT']) unless services.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.load_services(services)
|
41
|
+
handlers = []
|
42
|
+
number_of_handlers = 0
|
43
|
+
services.each do |file, options|
|
44
|
+
require file
|
45
|
+
|
46
|
+
base = Object.const_get("#{options['module']}::Service")
|
47
|
+
number_of_handlers += 1
|
48
|
+
|
49
|
+
implementation = build_handler(base, base.rpc_descs, number_of_handlers, options)
|
50
|
+
handlers << implementation
|
51
|
+
end
|
52
|
+
handlers
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.build_handler(base, descriptions, number_of_handlers, options)
|
56
|
+
handler = Class.new(base) do
|
57
|
+
class << self
|
58
|
+
attr_writer :options
|
59
|
+
attr_reader :options
|
60
|
+
end
|
61
|
+
descriptions.each do |service_name, description|
|
62
|
+
puts description
|
63
|
+
method_name = service_name.to_s.underscore.to_sym
|
64
|
+
define_method(method_name) do |request, _unused_call|
|
65
|
+
handler(__method__, request)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
handler.options = options
|
70
|
+
TShield::Grpc.const_set "GrpcService#{number_of_handlers}", handler
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TShield
|
4
|
+
module Grpc
|
5
|
+
module VCR
|
6
|
+
def handler_in_vcr_mode(method_name, request, options)
|
7
|
+
module_name = options['module']
|
8
|
+
|
9
|
+
response = saved_response(module_name, method_name, request)
|
10
|
+
return response if response
|
11
|
+
|
12
|
+
client_class = Object.const_get("#{module_name}::Stub")
|
13
|
+
client_instance = client_class.new(options['hostname'], :this_channel_is_insecure)
|
14
|
+
response = client_instance.send(method_name, request)
|
15
|
+
save_request_and_response(request, response)
|
16
|
+
response
|
17
|
+
end
|
18
|
+
|
19
|
+
def saved_response(module_name, method_name, request)
|
20
|
+
create_destiny(module_name, method_name, request)
|
21
|
+
response_file = File.join(@complete_path, 'response')
|
22
|
+
return false unless File.exist? response_file
|
23
|
+
|
24
|
+
content = JSON.parse File.open(response_file).read
|
25
|
+
response_class = File.open(File.join(@complete_path, 'response_class')).read.strip
|
26
|
+
Kernel.const_get(response_class).new(content)
|
27
|
+
end
|
28
|
+
|
29
|
+
def save_request_and_response(request, response)
|
30
|
+
save_request(request)
|
31
|
+
save_response(response)
|
32
|
+
end
|
33
|
+
|
34
|
+
def save_request(request)
|
35
|
+
file = File.open(File.join(@complete_path, 'original_request'), 'w')
|
36
|
+
file.puts request.to_json
|
37
|
+
file.close
|
38
|
+
end
|
39
|
+
|
40
|
+
def save_response(response)
|
41
|
+
file = File.open(File.join(@complete_path, 'response'), 'w')
|
42
|
+
file.puts response.to_json
|
43
|
+
file.close
|
44
|
+
|
45
|
+
response_class = File.open(File.join(@complete_path, 'response_class'), 'w')
|
46
|
+
response_class.puts response.class.to_s
|
47
|
+
response_class.close
|
48
|
+
end
|
49
|
+
|
50
|
+
def complete_path(module_name, method_name, request)
|
51
|
+
return @complete_path if @complete_path
|
52
|
+
|
53
|
+
@complete_path = ['requests', 'grpc', module_name, method_name.to_s, hexdigest(request)]
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_destiny(module_name, method_name, request)
|
57
|
+
current_path = []
|
58
|
+
complete_path(module_name, method_name, request).each do |path|
|
59
|
+
current_path << path
|
60
|
+
destiny = File.join current_path
|
61
|
+
Dir.mkdir destiny unless File.exist? destiny
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def hexdigest(request)
|
66
|
+
Digest::SHA1.hexdigest request.to_json
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/tshield/server.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
2
|
|
3
3
|
require 'sinatra'
|
4
|
+
require 'sinatra/cross_origin'
|
4
5
|
|
5
6
|
require 'tshield/options'
|
6
7
|
require 'tshield/controllers/requests'
|
@@ -16,6 +17,23 @@ module TShield
|
|
16
17
|
set :views, File.join(File.dirname(__FILE__), 'views')
|
17
18
|
set :bind, '0.0.0.0'
|
18
19
|
set :port, TShield::Options.instance.port
|
20
|
+
set :server, :puma
|
21
|
+
|
22
|
+
configure do
|
23
|
+
enable :cross_origin
|
24
|
+
end
|
25
|
+
|
26
|
+
before do
|
27
|
+
response.headers['Access-Control-Allow-Origin'] = '*'
|
28
|
+
end
|
29
|
+
|
30
|
+
options '*' do
|
31
|
+
response.headers['Allow'] = 'GET, PUT, POST, DELETE, OPTIONS'
|
32
|
+
response.headers['Access-Control-Allow-Headers'] = 'Authorization, Content-Type,
|
33
|
+
Accept, X-User-Email, X-Auth-Token'
|
34
|
+
response.headers['Access-Control-Allow-Origin'] = '*'
|
35
|
+
200
|
36
|
+
end
|
19
37
|
|
20
38
|
def self.register_resources
|
21
39
|
load_controllers
|
@@ -39,7 +57,6 @@ module TShield
|
|
39
57
|
|
40
58
|
def self.run!
|
41
59
|
register_resources
|
42
|
-
require 'byebug'
|
43
60
|
super
|
44
61
|
end
|
45
62
|
end
|
data/lib/tshield/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -35,6 +35,12 @@ describe TShield::Configuration do
|
|
35
35
|
)
|
36
36
|
end
|
37
37
|
|
38
|
+
context 'on grpc configuration' do
|
39
|
+
it 'recover server port' do
|
40
|
+
expect(@configuration.grpc['port']).to(eq(5678))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
38
44
|
context 'on load filters' do
|
39
45
|
it 'recover filters for a domain' do
|
40
46
|
expect(@configuration.get_filters('example.org')).to eq([ExampleFilter])
|
@@ -72,4 +78,17 @@ describe TShield::Configuration do
|
|
72
78
|
expect { TShield::Configuration.singleton }.to raise_error RuntimeError
|
73
79
|
end
|
74
80
|
end
|
81
|
+
|
82
|
+
context 'on config exists without grpc entry' do
|
83
|
+
before :each do
|
84
|
+
options_instance = double
|
85
|
+
allow(options_instance).to receive(:configuration_file)
|
86
|
+
.and_return('spec/tshield/fixtures/config/tshield-without-grpc.yml')
|
87
|
+
allow(TShield::Options).to receive(:instance).and_return(options_instance)
|
88
|
+
@configuration = TShield::Configuration.singleton
|
89
|
+
end
|
90
|
+
it 'should set default value for port' do
|
91
|
+
expect(@configuration.grpc).to eql('port' => 5678, 'proto_dir' => 'proto', 'services' => {})
|
92
|
+
end
|
93
|
+
end
|
75
94
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
request:
|
3
|
+
timeout: 0
|
4
|
+
domains:
|
5
|
+
'example.org':
|
6
|
+
name: 'example.org'
|
7
|
+
filters:
|
8
|
+
- 'ExampleFilter'
|
9
|
+
paths:
|
10
|
+
- '/api/one'
|
11
|
+
- '/api/two'
|
12
|
+
skip_query_params:
|
13
|
+
- 'a'
|
14
|
+
'example.com':
|
15
|
+
name: 'example.com'
|
16
|
+
paths:
|
17
|
+
- '/api/three'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
require 'tshield/grpc'
|
6
|
+
|
7
|
+
describe TShield::Grpc do
|
8
|
+
context 'on load services' do
|
9
|
+
before :each do
|
10
|
+
lib_dir = File.join(__dir__, 'fixtures/proto')
|
11
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
12
|
+
|
13
|
+
@services = {
|
14
|
+
'test_services_pb' => { 'module' => 'TestServices', 'hostname' => '0.0.0.0:5678' }
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should implement a service from options' do
|
19
|
+
implementation = TShield::Grpc.load_services(@services).first
|
20
|
+
instance = implementation.new
|
21
|
+
expect(instance.respond_to?(:service_method)).to be_truthy
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/tshield.gemspec
CHANGED
@@ -25,14 +25,18 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.required_ruby_version = '>= 2.3'
|
26
26
|
|
27
27
|
s.add_dependency('byebug', '~> 11.0', '>= 11.0.1')
|
28
|
+
s.add_dependency('grpc', '~> 1.28', '>= 1.28.0')
|
29
|
+
s.add_dependency('grpc-tools', '~> 1.28', '>= 1.28.0')
|
28
30
|
s.add_dependency('httparty', '~> 0.14', '>= 0.14.0')
|
29
31
|
s.add_dependency('json', '~> 2.0', '>= 2.0')
|
32
|
+
s.add_dependency('puma', '~> 4.3', '>= 4.3.3')
|
30
33
|
s.add_dependency('sinatra', '~> 1.4', '>= 1.4.0')
|
34
|
+
s.add_dependency('sinatra-cross_origin', '~> 0.4.0', '>= 0.4')
|
31
35
|
s.add_development_dependency('coveralls')
|
32
36
|
s.add_development_dependency('cucumber', '~> 3.1', '>= 3.1.2')
|
33
37
|
s.add_development_dependency('guard', '~> 2.15', '>= 2.15.0')
|
34
38
|
s.add_development_dependency('guard-rspec', '~> 4.7', '>= 4.7.3')
|
35
|
-
s.add_development_dependency('rake', '
|
39
|
+
s.add_development_dependency('rake', '>= 10.0', '~> 13.0')
|
36
40
|
s.add_development_dependency('rdoc', '~> 6.0', '>= 6.0')
|
37
41
|
s.add_development_dependency('reek', '~> 5.4.0', '>= 5.4.0')
|
38
42
|
s.add_development_dependency('rspec', '~> 3.5', '>= 3.5.0')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tshield
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Diego Rubin
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-07-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: byebug
|
@@ -31,6 +31,46 @@ dependencies:
|
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 11.0.1
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: grpc
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.28.0
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.28'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.28.0
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.28'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: grpc-tools
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 1.28.0
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '1.28'
|
64
|
+
type: :runtime
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.28.0
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '1.28'
|
34
74
|
- !ruby/object:Gem::Dependency
|
35
75
|
name: httparty
|
36
76
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,6 +111,26 @@ dependencies:
|
|
71
111
|
- - "~>"
|
72
112
|
- !ruby/object:Gem::Version
|
73
113
|
version: '2.0'
|
114
|
+
- !ruby/object:Gem::Dependency
|
115
|
+
name: puma
|
116
|
+
requirement: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - "~>"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '4.3'
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: 4.3.3
|
124
|
+
type: :runtime
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '4.3'
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: 4.3.3
|
74
134
|
- !ruby/object:Gem::Dependency
|
75
135
|
name: sinatra
|
76
136
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,6 +151,26 @@ dependencies:
|
|
91
151
|
- - "~>"
|
92
152
|
- !ruby/object:Gem::Version
|
93
153
|
version: '1.4'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: sinatra-cross_origin
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0.4'
|
161
|
+
- - "~>"
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: 0.4.0
|
164
|
+
type: :runtime
|
165
|
+
prerelease: false
|
166
|
+
version_requirements: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0.4'
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 0.4.0
|
94
174
|
- !ruby/object:Gem::Dependency
|
95
175
|
name: coveralls
|
96
176
|
requirement: !ruby/object:Gem::Requirement
|
@@ -174,7 +254,7 @@ dependencies:
|
|
174
254
|
version: '10.0'
|
175
255
|
- - "~>"
|
176
256
|
- !ruby/object:Gem::Version
|
177
|
-
version: '
|
257
|
+
version: '13.0'
|
178
258
|
type: :development
|
179
259
|
prerelease: false
|
180
260
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -184,7 +264,7 @@ dependencies:
|
|
184
264
|
version: '10.0'
|
185
265
|
- - "~>"
|
186
266
|
- !ruby/object:Gem::Version
|
187
|
-
version: '
|
267
|
+
version: '13.0'
|
188
268
|
- !ruby/object:Gem::Dependency
|
189
269
|
name: rdoc
|
190
270
|
requirement: !ruby/object:Gem::Requirement
|
@@ -347,6 +427,8 @@ files:
|
|
347
427
|
- lib/tshield/controllers/sessions.rb
|
348
428
|
- lib/tshield/counter.rb
|
349
429
|
- lib/tshield/extensions/string_extensions.rb
|
430
|
+
- lib/tshield/grpc.rb
|
431
|
+
- lib/tshield/grpc/vcr.rb
|
350
432
|
- lib/tshield/logger.rb
|
351
433
|
- lib/tshield/matching/filters.rb
|
352
434
|
- lib/tshield/options.rb
|
@@ -356,15 +438,17 @@ files:
|
|
356
438
|
- lib/tshield/response.rb
|
357
439
|
- lib/tshield/server.rb
|
358
440
|
- lib/tshield/sessions.rb
|
359
|
-
- lib/tshield/simple_tcp_server.rb
|
360
441
|
- lib/tshield/version.rb
|
361
442
|
- spec/spec_helper.rb
|
362
443
|
- spec/tshield/after_filter_spec.rb
|
363
444
|
- spec/tshield/configuration_spec.rb
|
364
445
|
- spec/tshield/controllers/requests_spec.rb
|
446
|
+
- spec/tshield/fixtures/config/tshield-without-grpc.yml
|
365
447
|
- spec/tshield/fixtures/config/tshield.yml
|
366
448
|
- spec/tshield/fixtures/filters/example_filter.rb
|
367
449
|
- spec/tshield/fixtures/matching/example.json
|
450
|
+
- spec/tshield/fixtures/proto/test_services_pb.rb
|
451
|
+
- spec/tshield/grpc_spec.rb
|
368
452
|
- spec/tshield/options_spec.rb
|
369
453
|
- spec/tshield/request_matching_spec.rb
|
370
454
|
- spec/tshield/request_vcr_spec.rb
|
@@ -388,18 +472,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
388
472
|
- !ruby/object:Gem::Version
|
389
473
|
version: '0'
|
390
474
|
requirements: []
|
391
|
-
rubygems_version: 3.0.
|
475
|
+
rubygems_version: 3.0.8
|
392
476
|
signing_key:
|
393
477
|
specification_version: 4
|
394
478
|
summary: Proxy for mocks API responses
|
395
479
|
test_files:
|
396
480
|
- spec/spec_helper.rb
|
397
|
-
- spec/tshield/
|
481
|
+
- spec/tshield/request_matching_spec.rb
|
482
|
+
- spec/tshield/grpc_spec.rb
|
398
483
|
- spec/tshield/configuration_spec.rb
|
399
484
|
- spec/tshield/request_vcr_spec.rb
|
400
485
|
- spec/tshield/controllers/requests_spec.rb
|
486
|
+
- spec/tshield/options_spec.rb
|
401
487
|
- spec/tshield/after_filter_spec.rb
|
402
|
-
- spec/tshield/fixtures/config/tshield.yml
|
403
488
|
- spec/tshield/fixtures/matching/example.json
|
489
|
+
- spec/tshield/fixtures/proto/test_services_pb.rb
|
404
490
|
- spec/tshield/fixtures/filters/example_filter.rb
|
405
|
-
- spec/tshield/
|
491
|
+
- spec/tshield/fixtures/config/tshield.yml
|
492
|
+
- spec/tshield/fixtures/config/tshield-without-grpc.yml
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'socket'
|
4
|
-
|
5
|
-
module TShield
|
6
|
-
class SimpleTCPServer
|
7
|
-
def initialize
|
8
|
-
@running = true
|
9
|
-
end
|
10
|
-
|
11
|
-
def on_connect(_client)
|
12
|
-
raise 'should implement method on_connect'
|
13
|
-
end
|
14
|
-
|
15
|
-
def close
|
16
|
-
@running = false
|
17
|
-
end
|
18
|
-
|
19
|
-
def listen(port)
|
20
|
-
puts "listening #{port}"
|
21
|
-
@server = TCPServer.new(port)
|
22
|
-
while @running
|
23
|
-
client = @server.accept
|
24
|
-
on_connect(client)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|