nonnative 1.20.0 → 1.25.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/.rubocop.yml +1 -1
- data/Gemfile.lock +56 -53
- data/Makefile +0 -1
- data/README.md +62 -28
- data/lib/nonnative.rb +5 -0
- data/lib/nonnative/chaos_proxy.rb +15 -43
- data/lib/nonnative/close_all_socket_pair.rb +9 -0
- data/lib/nonnative/command.rb +1 -1
- data/lib/nonnative/configuration.rb +4 -2
- data/lib/nonnative/configuration_process.rb +1 -1
- data/lib/nonnative/configuration_proxy.rb +2 -1
- data/lib/nonnative/configuration_server.rb +2 -2
- data/lib/nonnative/delay_socket_pair.rb +12 -0
- data/lib/nonnative/grpc_server.rb +5 -0
- data/lib/nonnative/http_client.rb +12 -8
- data/lib/nonnative/http_server.rb +3 -1
- data/lib/nonnative/invalid_data_socket_pair.rb +11 -0
- data/lib/nonnative/proxy.rb +1 -2
- data/lib/nonnative/socket_pair.rb +50 -0
- data/lib/nonnative/socket_pair_factory.rb +20 -0
- data/lib/nonnative/version.rb +1 -1
- data/nonnative.gemspec +3 -4
- metadata +35 -50
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 02a90943c6dc7f21344409f9ee8be6f2a885fdf93a349ec89d3d0e690f040727
|
|
4
|
+
data.tar.gz: '029e6c5d065db3e63a757d54fa163b9523c8dce1114341c43416709aa0fb3407'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8274f8202cd8b5b4a9bf81872ef9d25944b58171451469ef16c2ca9040cceda0ed41ab3e28b69c780b33260c4bfee5c231e5947738bf12413d3324e0f00a9d3e
|
|
7
|
+
data.tar.gz: bdedecceaf8a08ca7bd8b52e69fdbb8e5cc4336ca28677d0bce5f17a9db735a08d59a7180e2cd4e65c6819be704155ac6aac8a07db48d3ba293de2839ba69d84
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
nonnative (1.
|
|
4
|
+
nonnative (1.25.0)
|
|
5
5
|
concurrent-ruby (~> 1.0, >= 1.0.5)
|
|
6
|
-
cucumber (
|
|
7
|
-
grpc (
|
|
6
|
+
cucumber (>= 4, < 5)
|
|
7
|
+
grpc (>= 1, < 2)
|
|
8
8
|
puma (~> 4.3, >= 4.3.3)
|
|
9
9
|
rest-client (~> 2.1)
|
|
10
10
|
rspec-benchmark (~> 0.6.0)
|
|
@@ -14,47 +14,57 @@ PATH
|
|
|
14
14
|
GEM
|
|
15
15
|
remote: https://rubygems.org/
|
|
16
16
|
specs:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
activesupport (6.0.3.2)
|
|
18
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
19
|
+
i18n (>= 0.7, < 2)
|
|
20
|
+
minitest (~> 5.1)
|
|
21
|
+
tzinfo (~> 1.1)
|
|
22
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
|
20
23
|
ast (2.4.1)
|
|
21
24
|
backport (1.1.2)
|
|
22
|
-
backports (3.18.1)
|
|
23
25
|
benchmark (0.1.0)
|
|
24
26
|
benchmark-malloc (0.2.0)
|
|
25
27
|
benchmark-perf (0.6.0)
|
|
26
28
|
benchmark-trend (0.4.0)
|
|
27
29
|
builder (3.2.4)
|
|
28
|
-
chutney (2.0.3.1)
|
|
29
|
-
amatch (~> 0.4.0)
|
|
30
|
-
gherkin (~> 5.1.0)
|
|
31
|
-
i18n (~> 1.8.2)
|
|
32
|
-
pastel (~> 0.7)
|
|
33
|
-
tty-pie (~> 0.3)
|
|
34
30
|
concurrent-ruby (1.1.6)
|
|
35
|
-
cucumber (
|
|
36
|
-
builder (>= 2.
|
|
37
|
-
cucumber-core (~>
|
|
38
|
-
cucumber-
|
|
39
|
-
cucumber-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
31
|
+
cucumber (4.1.0)
|
|
32
|
+
builder (~> 3.2, >= 3.2.3)
|
|
33
|
+
cucumber-core (~> 7.1, >= 7.1.0)
|
|
34
|
+
cucumber-create-meta (~> 1.0.0, >= 1.0.0)
|
|
35
|
+
cucumber-cucumber-expressions (~> 10.1, >= 10.1.0)
|
|
36
|
+
cucumber-gherkin (~> 14.0, >= 14.0.1)
|
|
37
|
+
cucumber-html-formatter (~> 7.0, >= 7.0.0)
|
|
38
|
+
cucumber-messages (~> 12.2, >= 12.2.0)
|
|
39
|
+
cucumber-wire (~> 3.1, >= 3.1.0)
|
|
40
|
+
diff-lcs (~> 1.3, >= 1.3, < 1.4)
|
|
41
|
+
multi_test (~> 0.1, >= 0.1.2)
|
|
42
|
+
sys-uname (~> 1.0, >= 1.0.2)
|
|
43
|
+
cucumber-core (7.1.0)
|
|
44
|
+
cucumber-gherkin (~> 14.0, >= 14.0.1)
|
|
45
|
+
cucumber-messages (~> 12.2, >= 12.2.0)
|
|
46
|
+
cucumber-tag-expressions (~> 2.0, >= 2.0.4)
|
|
47
|
+
cucumber-create-meta (1.0.0)
|
|
48
|
+
cucumber-messages (~> 12.2, >= 12.2.0)
|
|
49
|
+
sys-uname (~> 1.2, >= 1.2.1)
|
|
50
|
+
cucumber-cucumber-expressions (10.2.1)
|
|
51
|
+
cucumber-gherkin (14.0.1)
|
|
52
|
+
cucumber-messages (~> 12.2, >= 12.2.0)
|
|
53
|
+
cucumber-html-formatter (7.0.0)
|
|
54
|
+
cucumber-messages (~> 12.2, >= 12.2.0)
|
|
55
|
+
cucumber-messages (12.2.0)
|
|
56
|
+
protobuf-cucumber (~> 3.10, >= 3.10.8)
|
|
57
|
+
cucumber-tag-expressions (2.0.4)
|
|
58
|
+
cucumber-wire (3.1.0)
|
|
59
|
+
cucumber-core (~> 7.1, >= 7.1.0)
|
|
60
|
+
cucumber-cucumber-expressions (~> 10.1, >= 10.1.0)
|
|
61
|
+
cucumber-messages (~> 12.2, >= 12.2.0)
|
|
62
|
+
diff-lcs (1.3)
|
|
52
63
|
docile (1.3.2)
|
|
53
64
|
domain_name (0.5.20190701)
|
|
54
65
|
unf (>= 0.0.5, < 1.0.0)
|
|
55
66
|
e2mmap (0.1.0)
|
|
56
|
-
|
|
57
|
-
gherkin (5.1.0)
|
|
67
|
+
ffi (1.13.1)
|
|
58
68
|
google-protobuf (3.12.2)
|
|
59
69
|
googleapis-common-protos-types (1.0.5)
|
|
60
70
|
google-protobuf (~> 3.11)
|
|
@@ -70,13 +80,12 @@ GEM
|
|
|
70
80
|
jaro_winkler (1.5.4)
|
|
71
81
|
json (2.3.0)
|
|
72
82
|
maruku (0.7.3)
|
|
83
|
+
middleware (0.1.0)
|
|
73
84
|
mime-types (3.3.1)
|
|
74
85
|
mime-types-data (~> 3.2015)
|
|
75
86
|
mime-types-data (3.2020.0512)
|
|
76
87
|
mini_portile2 (2.4.0)
|
|
77
|
-
|
|
78
|
-
protocol (~> 2.0)
|
|
79
|
-
multi_json (1.14.1)
|
|
88
|
+
minitest (5.14.1)
|
|
80
89
|
multi_test (0.1.2)
|
|
81
90
|
mustermann (1.1.1)
|
|
82
91
|
ruby2_keywords (~> 0.0.1)
|
|
@@ -87,11 +96,11 @@ GEM
|
|
|
87
96
|
parallel (1.19.2)
|
|
88
97
|
parser (2.7.1.4)
|
|
89
98
|
ast (~> 2.4.1)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
protobuf-cucumber (3.10.8)
|
|
100
|
+
activesupport (>= 3.2)
|
|
101
|
+
middleware
|
|
102
|
+
thor
|
|
103
|
+
thread_safe
|
|
95
104
|
puma (4.3.5)
|
|
96
105
|
nio4r (~> 2.0)
|
|
97
106
|
rack (2.2.3)
|
|
@@ -139,9 +148,6 @@ GEM
|
|
|
139
148
|
parser (>= 2.7.0.1)
|
|
140
149
|
ruby-progressbar (1.10.1)
|
|
141
150
|
ruby2_keywords (0.0.2)
|
|
142
|
-
ruby_parser (3.14.2)
|
|
143
|
-
sexp_processor (~> 4.9)
|
|
144
|
-
sexp_processor (4.15.0)
|
|
145
151
|
simplecov (0.17.1)
|
|
146
152
|
docile (~> 1.1)
|
|
147
153
|
json (>= 1.8, < 3)
|
|
@@ -166,29 +172,26 @@ GEM
|
|
|
166
172
|
thor (~> 1.0)
|
|
167
173
|
tilt (~> 2.0)
|
|
168
174
|
yard (~> 0.9, >= 0.9.24)
|
|
169
|
-
|
|
175
|
+
sys-uname (1.2.1)
|
|
176
|
+
ffi (>= 1.0.0)
|
|
170
177
|
thor (1.0.1)
|
|
178
|
+
thread_safe (0.3.6)
|
|
171
179
|
tilt (2.0.10)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
tty-color (0.5.1)
|
|
175
|
-
tty-cursor (0.7.1)
|
|
176
|
-
tty-pie (0.3.0)
|
|
177
|
-
pastel (~> 0.7.3)
|
|
178
|
-
tty-cursor (~> 0.7)
|
|
180
|
+
tzinfo (1.2.7)
|
|
181
|
+
thread_safe (~> 0.1)
|
|
179
182
|
unf (0.1.4)
|
|
180
183
|
unf_ext
|
|
181
184
|
unf_ext (0.0.7.7)
|
|
182
185
|
unicode-display_width (1.7.0)
|
|
183
186
|
yard (0.9.25)
|
|
187
|
+
zeitwerk (2.3.1)
|
|
184
188
|
|
|
185
189
|
PLATFORMS
|
|
186
190
|
ruby
|
|
187
191
|
|
|
188
192
|
DEPENDENCIES
|
|
189
193
|
bundler (~> 2.1, >= 2.1.4)
|
|
190
|
-
|
|
191
|
-
grpc-tools (~> 1.30, >= 1.30.1)
|
|
194
|
+
grpc-tools (>= 1, < 2)
|
|
192
195
|
nonnative!
|
|
193
196
|
rake (~> 13.0, >= 13.0.1)
|
|
194
197
|
rubocop (~> 0.87.1)
|
data/Makefile
CHANGED
data/README.md
CHANGED
|
@@ -57,7 +57,7 @@ Nonnative.configure do |config|
|
|
|
57
57
|
d.command = 'features/support/bin/start 12_321'
|
|
58
58
|
d.timeout = 0.5
|
|
59
59
|
d.port = 12_321
|
|
60
|
-
d.
|
|
60
|
+
d.log = 'features/logs/12_321.log'
|
|
61
61
|
d.signal = 'INT' # Possible values are described in Signal.list.keys
|
|
62
62
|
end
|
|
63
63
|
|
|
@@ -66,7 +66,7 @@ Nonnative.configure do |config|
|
|
|
66
66
|
d.command = 'features/support/bin/start 12_322'
|
|
67
67
|
d.timeout = 0.5
|
|
68
68
|
d.port = 12_322
|
|
69
|
-
d.
|
|
69
|
+
d.log = 'features/logs/12_322.log'
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
```
|
|
@@ -82,14 +82,14 @@ processes:
|
|
|
82
82
|
command: features/support/bin/start 12_321
|
|
83
83
|
timeout: 5
|
|
84
84
|
port: 12321
|
|
85
|
-
|
|
85
|
+
log: features/logs/12_321.log
|
|
86
86
|
signal: INT # Possible values are described in Signal.list.keys
|
|
87
87
|
-
|
|
88
88
|
name: start_2
|
|
89
89
|
command: features/support/bin/start 12_322
|
|
90
90
|
timeout: 5
|
|
91
91
|
port: 12322
|
|
92
|
-
|
|
92
|
+
log: features/logs/12_322.log
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
Then load the file with
|
|
@@ -133,18 +133,20 @@ require 'nonnative'
|
|
|
133
133
|
Nonnative.configure do |config|
|
|
134
134
|
config.strategy = :manual
|
|
135
135
|
|
|
136
|
-
config.server do |
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
config.server do |s|
|
|
137
|
+
s.name = 'server_1'
|
|
138
|
+
s.klass = Nonnative::EchoServer
|
|
139
|
+
s.timeout = 1
|
|
140
|
+
s.port = 12_323
|
|
141
|
+
s.log = 'features/logs/server_1.log'
|
|
141
142
|
end
|
|
142
143
|
|
|
143
|
-
config.server do |
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
config.server do |s|
|
|
145
|
+
s.name = 'server_2'
|
|
146
|
+
s.klass = Nonnative::EchoServer
|
|
147
|
+
s.timeout = 1
|
|
148
|
+
s.port = 12_324
|
|
149
|
+
s.log = 'features/logs/server_2.log'
|
|
148
150
|
end
|
|
149
151
|
end
|
|
150
152
|
```
|
|
@@ -160,11 +162,13 @@ servers:
|
|
|
160
162
|
klass: Nonnative::EchoServer
|
|
161
163
|
timeout: 1
|
|
162
164
|
port: 12323
|
|
165
|
+
log: features/logs/server_1.log
|
|
163
166
|
-
|
|
164
167
|
name: server_2
|
|
165
168
|
klass: Nonnative::EchoServer
|
|
166
169
|
timeout: 1
|
|
167
170
|
port: 12324
|
|
171
|
+
log: features/logs/server_2.log
|
|
168
172
|
```
|
|
169
173
|
|
|
170
174
|
Then load the file with:
|
|
@@ -182,7 +186,11 @@ Define your server:
|
|
|
182
186
|
```ruby
|
|
183
187
|
module Nonnative
|
|
184
188
|
module Features
|
|
185
|
-
class Application < Sinatra::
|
|
189
|
+
class Application < Sinatra::Application
|
|
190
|
+
configure do
|
|
191
|
+
set :server_settings, log_requests: true
|
|
192
|
+
end
|
|
193
|
+
|
|
186
194
|
get '/hello' do
|
|
187
195
|
'Hello World!'
|
|
188
196
|
end
|
|
@@ -205,11 +213,12 @@ require 'nonnative'
|
|
|
205
213
|
Nonnative.configure do |config|
|
|
206
214
|
config.strategy = :manual
|
|
207
215
|
|
|
208
|
-
config.server do |
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
216
|
+
config.server do |s|
|
|
217
|
+
s.name = 'http_server_1'
|
|
218
|
+
s.klass = Nonnative::Features::HTTPServer
|
|
219
|
+
s.timeout = 1
|
|
220
|
+
s.port = 4567
|
|
221
|
+
s.log = 'features/logs/http_server_1.log'
|
|
213
222
|
end
|
|
214
223
|
end
|
|
215
224
|
```
|
|
@@ -225,6 +234,7 @@ servers:
|
|
|
225
234
|
klass: Nonnative::Features::HTTPServer
|
|
226
235
|
timeout: 1
|
|
227
236
|
port: 4567
|
|
237
|
+
log: features/logs/http_server_1.log
|
|
228
238
|
```
|
|
229
239
|
|
|
230
240
|
Then load the file with:
|
|
@@ -265,11 +275,12 @@ require 'nonnative'
|
|
|
265
275
|
Nonnative.configure do |config|
|
|
266
276
|
config.strategy = :manual
|
|
267
277
|
|
|
268
|
-
config.server do |
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
278
|
+
config.server do |s|
|
|
279
|
+
s.name = 'grpc_server_1'
|
|
280
|
+
s.klass = Nonnative::Features::GRPCServer
|
|
281
|
+
s.timeout = 1
|
|
282
|
+
s.port = 9002
|
|
283
|
+
s.log = 'features/logs/grpc_server_1.log'
|
|
273
284
|
end
|
|
274
285
|
end
|
|
275
286
|
```
|
|
@@ -285,6 +296,7 @@ servers:
|
|
|
285
296
|
klass: Nonnative::Features::GRPCServer
|
|
286
297
|
timeout: 1
|
|
287
298
|
port: 9002
|
|
299
|
+
log: features/logs/grpc_server_1.log
|
|
288
300
|
```
|
|
289
301
|
|
|
290
302
|
Then load the file with:
|
|
@@ -297,8 +309,8 @@ Nonnative.load_configuration('configuration.yml')
|
|
|
297
309
|
#### Proxies
|
|
298
310
|
|
|
299
311
|
We allow different proxies to be configured. These proxies can be used to simulate all kind of situations. The proxies that can be configured are:
|
|
300
|
-
- none (this is the default)
|
|
301
|
-
- chaos
|
|
312
|
+
- `none` (this is the default)
|
|
313
|
+
- `chaos`
|
|
302
314
|
|
|
303
315
|
Setup it up programmatically:
|
|
304
316
|
|
|
@@ -311,7 +323,10 @@ Nonnative.configure do |config|
|
|
|
311
323
|
config.server do |d|
|
|
312
324
|
d.proxy = {
|
|
313
325
|
type: 'chaos',
|
|
314
|
-
port: 20_000
|
|
326
|
+
port: 20_000,
|
|
327
|
+
options: {
|
|
328
|
+
delay: 5
|
|
329
|
+
}
|
|
315
330
|
}
|
|
316
331
|
end
|
|
317
332
|
end
|
|
@@ -327,4 +342,23 @@ servers:
|
|
|
327
342
|
proxy:
|
|
328
343
|
type: chaos
|
|
329
344
|
port: 20000
|
|
345
|
+
options:
|
|
346
|
+
delay: 5
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
##### Fault Injection
|
|
350
|
+
|
|
351
|
+
The `chaos` proxy allows you to simulate failures by injecting them. We currently support the following:
|
|
352
|
+
- `close_all` - Closes the socket as soon as it connects.
|
|
353
|
+
- `delay` - This delays the communication between the connection. Default is 2 secs can be configured through options.
|
|
354
|
+
- `invalid_data` - This takes the input and rearranges it to produce invalid data.
|
|
355
|
+
|
|
356
|
+
Setup it up programmatically:
|
|
357
|
+
|
|
358
|
+
```ruby
|
|
359
|
+
name = 'name of server in configuration'
|
|
360
|
+
server = Nonnative.pool.server_by_name(name)
|
|
361
|
+
|
|
362
|
+
server.proxy.close_all # To use close_all.
|
|
363
|
+
server.proxy.reset # To reset it back to a good state.
|
|
330
364
|
```
|
data/lib/nonnative.rb
CHANGED
|
@@ -35,6 +35,11 @@ require 'nonnative/proxy_factory'
|
|
|
35
35
|
require 'nonnative/proxy'
|
|
36
36
|
require 'nonnative/no_proxy'
|
|
37
37
|
require 'nonnative/chaos_proxy'
|
|
38
|
+
require 'nonnative/socket_pair'
|
|
39
|
+
require 'nonnative/close_all_socket_pair'
|
|
40
|
+
require 'nonnative/delay_socket_pair'
|
|
41
|
+
require 'nonnative/invalid_data_socket_pair'
|
|
42
|
+
require 'nonnative/socket_pair_factory'
|
|
38
43
|
|
|
39
44
|
module Nonnative
|
|
40
45
|
class << self
|
|
@@ -24,6 +24,14 @@ module Nonnative
|
|
|
24
24
|
apply_state :close_all
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
def delay
|
|
28
|
+
apply_state :delay
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def invalid_data
|
|
32
|
+
apply_state :invalid_data
|
|
33
|
+
end
|
|
34
|
+
|
|
27
35
|
def reset
|
|
28
36
|
apply_state :none
|
|
29
37
|
end
|
|
@@ -38,57 +46,21 @@ module Nonnative
|
|
|
38
46
|
|
|
39
47
|
def perform_start
|
|
40
48
|
loop do
|
|
41
|
-
thread = Thread.start(tcp_server.accept)
|
|
49
|
+
thread = Thread.start(tcp_server.accept) do |local_socket|
|
|
50
|
+
SocketPairFactory.create(read_state, service.proxy).connect(local_socket)
|
|
51
|
+
connections.delete(Thread.current.object_id)
|
|
52
|
+
end
|
|
53
|
+
thread.report_on_exception = false
|
|
42
54
|
connections[thread.object_id] = thread
|
|
43
55
|
end
|
|
44
56
|
end
|
|
45
57
|
|
|
46
|
-
def connect(local_socket)
|
|
47
|
-
return local_socket.close if state?(:close_all)
|
|
48
|
-
|
|
49
|
-
remote_socket = create_remote_socket
|
|
50
|
-
return unless remote_socket
|
|
51
|
-
|
|
52
|
-
loop do
|
|
53
|
-
ready = select([local_socket, remote_socket], nil, nil)
|
|
54
|
-
|
|
55
|
-
break if write(ready, local_socket, remote_socket)
|
|
56
|
-
break if write(ready, remote_socket, local_socket)
|
|
57
|
-
end
|
|
58
|
-
rescue Errno::ECONNRESET
|
|
59
|
-
# Just ignore it.
|
|
60
|
-
ensure
|
|
61
|
-
local_socket.close
|
|
62
|
-
remote_socket&.close
|
|
63
|
-
connections.delete(Thread.current.object_id)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def create_remote_socket
|
|
67
|
-
timeout.perform do
|
|
68
|
-
::TCPSocket.new('0.0.0.0', port)
|
|
69
|
-
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
|
70
|
-
sleep 0.01
|
|
71
|
-
retry
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def write(ready, socket1, socket2)
|
|
76
|
-
if ready[0].include?(socket1)
|
|
77
|
-
data = socket1.recv(1024)
|
|
78
|
-
return true if data.empty?
|
|
79
|
-
|
|
80
|
-
socket2.write(data)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
false
|
|
84
|
-
end
|
|
85
|
-
|
|
86
58
|
def apply_state(state)
|
|
87
59
|
mutex.synchronize { @state = state }
|
|
88
60
|
end
|
|
89
61
|
|
|
90
|
-
def
|
|
91
|
-
mutex.synchronize {
|
|
62
|
+
def read_state
|
|
63
|
+
mutex.synchronize { state }
|
|
92
64
|
end
|
|
93
65
|
end
|
|
94
66
|
end
|
data/lib/nonnative/command.rb
CHANGED
|
@@ -24,7 +24,7 @@ module Nonnative
|
|
|
24
24
|
d.command = fd['command']
|
|
25
25
|
d.timeout = fd['timeout']
|
|
26
26
|
d.port = fd['port']
|
|
27
|
-
d.
|
|
27
|
+
d.log = fd['log']
|
|
28
28
|
d.signal = fd['signal']
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -38,13 +38,15 @@ module Nonnative
|
|
|
38
38
|
s.klass = Object.const_get(fd['klass'])
|
|
39
39
|
s.timeout = fd['timeout']
|
|
40
40
|
s.port = fd['port']
|
|
41
|
+
s.log = fd['log']
|
|
41
42
|
|
|
42
43
|
proxy = fd['proxy']
|
|
43
44
|
|
|
44
45
|
if proxy
|
|
45
46
|
s.proxy = {
|
|
46
47
|
type: proxy['type'],
|
|
47
|
-
port: proxy['port']
|
|
48
|
+
port: proxy['port'],
|
|
49
|
+
options: proxy['options']
|
|
48
50
|
}
|
|
49
51
|
end
|
|
50
52
|
end
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Nonnative
|
|
4
4
|
class ConfigurationServer
|
|
5
|
-
attr_accessor :name, :klass, :timeout, :port
|
|
6
|
-
|
|
5
|
+
attr_accessor :name, :klass, :timeout, :port, :log
|
|
7
6
|
attr_reader :proxy
|
|
8
7
|
|
|
9
8
|
def initialize
|
|
@@ -13,6 +12,7 @@ module Nonnative
|
|
|
13
12
|
def proxy=(value)
|
|
14
13
|
proxy.type = value[:type]
|
|
15
14
|
proxy.port = value[:port]
|
|
15
|
+
proxy.options = value[:options]
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|
|
@@ -6,6 +6,11 @@ module Nonnative
|
|
|
6
6
|
@server = GRPC::RpcServer.new
|
|
7
7
|
server.handle(svc)
|
|
8
8
|
|
|
9
|
+
# Unfortunately gRPC has only one logger so the first server wins.
|
|
10
|
+
GRPC.define_singleton_method(:logger) do
|
|
11
|
+
@logger ||= Logger.new(service.log)
|
|
12
|
+
end
|
|
13
|
+
|
|
9
14
|
super service
|
|
10
15
|
end
|
|
11
16
|
|
|
@@ -8,31 +8,33 @@ module Nonnative
|
|
|
8
8
|
|
|
9
9
|
protected
|
|
10
10
|
|
|
11
|
-
def get(pathname, headers = {})
|
|
11
|
+
def get(pathname, headers = {}, timeout = 60)
|
|
12
12
|
with_exception do
|
|
13
13
|
uri = URI.join(host, pathname)
|
|
14
|
-
RestClient.get
|
|
14
|
+
RestClient::Request.execute(method: :get, url: uri.to_s, headers: headers, timeout: timeout)
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def post(pathname, payload, headers = {})
|
|
18
|
+
def post(pathname, payload, headers = {}, timeout = 60)
|
|
19
19
|
with_exception do
|
|
20
20
|
uri = URI.join(host, pathname)
|
|
21
|
-
RestClient.post
|
|
21
|
+
RestClient::Request.execute(method: :post, url: uri.to_s, payload: payload.to_json, headers: headers,
|
|
22
|
+
timeout: timeout)
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
def delete(pathname, headers = {})
|
|
26
|
+
def delete(pathname, headers = {}, timeout = 60)
|
|
26
27
|
with_exception do
|
|
27
28
|
uri = URI.join(host, pathname)
|
|
28
|
-
RestClient.delete
|
|
29
|
+
RestClient::Request.execute(method: :delete, url: uri.to_s, headers: headers, timeout: timeout)
|
|
29
30
|
end
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
def put(pathname, payload, headers = {})
|
|
33
|
+
def put(pathname, payload, headers = {}, timeout = 60)
|
|
33
34
|
with_exception do
|
|
34
35
|
uri = URI.join(host, pathname)
|
|
35
|
-
RestClient.put
|
|
36
|
+
RestClient::Request.execute(method: :put, url: uri.to_s, payload: payload.to_json, headers: headers,
|
|
37
|
+
timeout: timeout)
|
|
36
38
|
end
|
|
37
39
|
end
|
|
38
40
|
|
|
@@ -42,6 +44,8 @@ module Nonnative
|
|
|
42
44
|
|
|
43
45
|
def with_exception
|
|
44
46
|
yield
|
|
47
|
+
rescue RestClient::Exceptions::ReadTimeout => e
|
|
48
|
+
raise e
|
|
45
49
|
rescue RestClient::ExceptionWithResponse => e
|
|
46
50
|
e.response
|
|
47
51
|
end
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
module Nonnative
|
|
4
4
|
class HTTPServer < Nonnative::Server
|
|
5
5
|
def initialize(service)
|
|
6
|
-
|
|
6
|
+
log = File.open(service.log, 'a')
|
|
7
|
+
events = Puma::Events.new(log, log)
|
|
8
|
+
@server = Puma::Server.new(app, events)
|
|
7
9
|
|
|
8
10
|
super service
|
|
9
11
|
end
|
data/lib/nonnative/proxy.rb
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nonnative
|
|
4
|
+
class SocketPair
|
|
5
|
+
def initialize(proxy)
|
|
6
|
+
@proxy = proxy
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def connect(local_socket)
|
|
10
|
+
remote_socket = create_remote_socket
|
|
11
|
+
|
|
12
|
+
loop do
|
|
13
|
+
ready = select([local_socket, remote_socket], nil, nil)
|
|
14
|
+
|
|
15
|
+
break if pipe(ready, local_socket, remote_socket)
|
|
16
|
+
break if pipe(ready, remote_socket, local_socket)
|
|
17
|
+
end
|
|
18
|
+
ensure
|
|
19
|
+
local_socket.close
|
|
20
|
+
remote_socket&.close
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
protected
|
|
24
|
+
|
|
25
|
+
attr_reader :proxy
|
|
26
|
+
|
|
27
|
+
def create_remote_socket
|
|
28
|
+
::TCPSocket.new('0.0.0.0', proxy.port)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def pipe(ready, socket1, socket2)
|
|
32
|
+
if ready[0].include?(socket1)
|
|
33
|
+
data = read(socket1)
|
|
34
|
+
return true if data.empty?
|
|
35
|
+
|
|
36
|
+
write socket2, data
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
false
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def read(socket)
|
|
43
|
+
socket.recv(1024)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def write(socket, data)
|
|
47
|
+
socket.write(data)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nonnative
|
|
4
|
+
class SocketPairFactory
|
|
5
|
+
class << self
|
|
6
|
+
def create(type, port)
|
|
7
|
+
case type
|
|
8
|
+
when :close_all
|
|
9
|
+
CloseAllSocketPair.new(port)
|
|
10
|
+
when :delay
|
|
11
|
+
DelaySocketPair.new(port)
|
|
12
|
+
when :invalid_data
|
|
13
|
+
InvalidDataSocketPair.new(port)
|
|
14
|
+
else
|
|
15
|
+
SocketPair.new(port)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/nonnative/version.rb
CHANGED
data/nonnative.gemspec
CHANGED
|
@@ -25,8 +25,8 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
spec.require_paths = ['lib']
|
|
26
26
|
|
|
27
27
|
spec.add_dependency 'concurrent-ruby', '~> 1.0', '>= 1.0.5'
|
|
28
|
-
spec.add_dependency 'cucumber', '
|
|
29
|
-
spec.add_dependency 'grpc', '
|
|
28
|
+
spec.add_dependency 'cucumber', ['>= 4', '< 5']
|
|
29
|
+
spec.add_dependency 'grpc', ['>= 1', '< 2']
|
|
30
30
|
spec.add_dependency 'puma', '~> 4.3', '>= 4.3.3'
|
|
31
31
|
spec.add_dependency 'rest-client', '~> 2.1'
|
|
32
32
|
spec.add_dependency 'rspec-benchmark', '~> 0.6.0'
|
|
@@ -34,8 +34,7 @@ Gem::Specification.new do |spec|
|
|
|
34
34
|
spec.add_dependency 'sinatra', '~> 2.0', '>= 2.0.8.1'
|
|
35
35
|
|
|
36
36
|
spec.add_development_dependency 'bundler', '~> 2.1', '>= 2.1.4'
|
|
37
|
-
spec.add_development_dependency '
|
|
38
|
-
spec.add_development_dependency 'grpc-tools', '~> 1.30', '>= 1.30.1'
|
|
37
|
+
spec.add_development_dependency 'grpc-tools', ['>= 1', '< 2']
|
|
39
38
|
spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.1'
|
|
40
39
|
spec.add_development_dependency 'rubocop', '~> 0.87.1'
|
|
41
40
|
spec.add_development_dependency 'simplecov', '~> 0.17.1'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nonnative
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.25.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Falkowski
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-07-
|
|
11
|
+
date: 2020-07-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -34,42 +34,42 @@ dependencies:
|
|
|
34
34
|
name: cucumber
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '3.1'
|
|
40
37
|
- - ">="
|
|
41
38
|
- !ruby/object:Gem::Version
|
|
42
|
-
version:
|
|
39
|
+
version: '4'
|
|
40
|
+
- - "<"
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '5'
|
|
43
43
|
type: :runtime
|
|
44
44
|
prerelease: false
|
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
46
46
|
requirements:
|
|
47
|
-
- - "~>"
|
|
48
|
-
- !ruby/object:Gem::Version
|
|
49
|
-
version: '3.1'
|
|
50
47
|
- - ">="
|
|
51
48
|
- !ruby/object:Gem::Version
|
|
52
|
-
version:
|
|
49
|
+
version: '4'
|
|
50
|
+
- - "<"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '5'
|
|
53
53
|
- !ruby/object:Gem::Dependency
|
|
54
54
|
name: grpc
|
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
|
56
56
|
requirements:
|
|
57
|
-
- - "~>"
|
|
58
|
-
- !ruby/object:Gem::Version
|
|
59
|
-
version: '1.30'
|
|
60
57
|
- - ">="
|
|
61
58
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: 1
|
|
59
|
+
version: '1'
|
|
60
|
+
- - "<"
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '2'
|
|
63
63
|
type: :runtime
|
|
64
64
|
prerelease: false
|
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
66
66
|
requirements:
|
|
67
|
-
- - "~>"
|
|
68
|
-
- !ruby/object:Gem::Version
|
|
69
|
-
version: '1.30'
|
|
70
67
|
- - ">="
|
|
71
68
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: 1
|
|
69
|
+
version: '1'
|
|
70
|
+
- - "<"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '2'
|
|
73
73
|
- !ruby/object:Gem::Dependency
|
|
74
74
|
name: puma
|
|
75
75
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -178,46 +178,26 @@ dependencies:
|
|
|
178
178
|
- - ">="
|
|
179
179
|
- !ruby/object:Gem::Version
|
|
180
180
|
version: 2.1.4
|
|
181
|
-
- !ruby/object:Gem::Dependency
|
|
182
|
-
name: chutney
|
|
183
|
-
requirement: !ruby/object:Gem::Requirement
|
|
184
|
-
requirements:
|
|
185
|
-
- - "~>"
|
|
186
|
-
- !ruby/object:Gem::Version
|
|
187
|
-
version: '2.0'
|
|
188
|
-
- - ">="
|
|
189
|
-
- !ruby/object:Gem::Version
|
|
190
|
-
version: 2.0.3.1
|
|
191
|
-
type: :development
|
|
192
|
-
prerelease: false
|
|
193
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
194
|
-
requirements:
|
|
195
|
-
- - "~>"
|
|
196
|
-
- !ruby/object:Gem::Version
|
|
197
|
-
version: '2.0'
|
|
198
|
-
- - ">="
|
|
199
|
-
- !ruby/object:Gem::Version
|
|
200
|
-
version: 2.0.3.1
|
|
201
181
|
- !ruby/object:Gem::Dependency
|
|
202
182
|
name: grpc-tools
|
|
203
183
|
requirement: !ruby/object:Gem::Requirement
|
|
204
184
|
requirements:
|
|
205
|
-
- - "~>"
|
|
206
|
-
- !ruby/object:Gem::Version
|
|
207
|
-
version: '1.30'
|
|
208
185
|
- - ">="
|
|
209
186
|
- !ruby/object:Gem::Version
|
|
210
|
-
version: 1
|
|
187
|
+
version: '1'
|
|
188
|
+
- - "<"
|
|
189
|
+
- !ruby/object:Gem::Version
|
|
190
|
+
version: '2'
|
|
211
191
|
type: :development
|
|
212
192
|
prerelease: false
|
|
213
193
|
version_requirements: !ruby/object:Gem::Requirement
|
|
214
194
|
requirements:
|
|
215
|
-
- - "~>"
|
|
216
|
-
- !ruby/object:Gem::Version
|
|
217
|
-
version: '1.30'
|
|
218
195
|
- - ">="
|
|
219
196
|
- !ruby/object:Gem::Version
|
|
220
|
-
version: 1
|
|
197
|
+
version: '1'
|
|
198
|
+
- - "<"
|
|
199
|
+
- !ruby/object:Gem::Version
|
|
200
|
+
version: '2'
|
|
221
201
|
- !ruby/object:Gem::Dependency
|
|
222
202
|
name: rake
|
|
223
203
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -304,15 +284,18 @@ files:
|
|
|
304
284
|
- lib/nonnative.rb
|
|
305
285
|
- lib/nonnative/before.rb
|
|
306
286
|
- lib/nonnative/chaos_proxy.rb
|
|
287
|
+
- lib/nonnative/close_all_socket_pair.rb
|
|
307
288
|
- lib/nonnative/command.rb
|
|
308
289
|
- lib/nonnative/configuration.rb
|
|
309
290
|
- lib/nonnative/configuration_process.rb
|
|
310
291
|
- lib/nonnative/configuration_proxy.rb
|
|
311
292
|
- lib/nonnative/configuration_server.rb
|
|
293
|
+
- lib/nonnative/delay_socket_pair.rb
|
|
312
294
|
- lib/nonnative/error.rb
|
|
313
295
|
- lib/nonnative/grpc_server.rb
|
|
314
296
|
- lib/nonnative/http_client.rb
|
|
315
297
|
- lib/nonnative/http_server.rb
|
|
298
|
+
- lib/nonnative/invalid_data_socket_pair.rb
|
|
316
299
|
- lib/nonnative/manual.rb
|
|
317
300
|
- lib/nonnative/no_proxy.rb
|
|
318
301
|
- lib/nonnative/observability.rb
|
|
@@ -322,6 +305,8 @@ files:
|
|
|
322
305
|
- lib/nonnative/proxy_factory.rb
|
|
323
306
|
- lib/nonnative/server.rb
|
|
324
307
|
- lib/nonnative/service.rb
|
|
308
|
+
- lib/nonnative/socket_pair.rb
|
|
309
|
+
- lib/nonnative/socket_pair_factory.rb
|
|
325
310
|
- lib/nonnative/start_error.rb
|
|
326
311
|
- lib/nonnative/startup.rb
|
|
327
312
|
- lib/nonnative/stop_error.rb
|
|
@@ -333,7 +318,7 @@ homepage: https://github.com/alexfalkowski/nonnative
|
|
|
333
318
|
licenses:
|
|
334
319
|
- Unlicense
|
|
335
320
|
metadata: {}
|
|
336
|
-
post_install_message:
|
|
321
|
+
post_install_message:
|
|
337
322
|
rdoc_options: []
|
|
338
323
|
require_paths:
|
|
339
324
|
- lib
|
|
@@ -348,8 +333,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
348
333
|
- !ruby/object:Gem::Version
|
|
349
334
|
version: '0'
|
|
350
335
|
requirements: []
|
|
351
|
-
rubygems_version: 3.0.
|
|
352
|
-
signing_key:
|
|
336
|
+
rubygems_version: 3.0.8
|
|
337
|
+
signing_key:
|
|
353
338
|
specification_version: 4
|
|
354
339
|
summary: Allows you to keep using the power of ruby to test other systems
|
|
355
340
|
test_files: []
|