nonnative 1.10.0 → 1.15.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 +21 -0
- data/Gemfile.lock +23 -22
- data/README.md +58 -18
- data/lib/nonnative.rb +19 -3
- data/lib/nonnative/chaos_proxy.rb +64 -0
- data/lib/nonnative/command.rb +36 -18
- data/lib/nonnative/configuration.rb +10 -0
- data/lib/nonnative/configuration_process.rb +2 -0
- data/lib/nonnative/configuration_proxy.rb +13 -0
- data/lib/nonnative/configuration_server.rb +6 -0
- data/lib/nonnative/grpc_server.rb +12 -6
- data/lib/nonnative/http_client.rb +14 -0
- data/lib/nonnative/http_server.rb +15 -18
- data/lib/nonnative/no_proxy.rb +17 -0
- data/lib/nonnative/pool.rb +1 -1
- data/lib/nonnative/proxy.rb +14 -0
- data/lib/nonnative/proxy_factory.rb +17 -0
- data/lib/nonnative/server.rb +30 -15
- data/lib/nonnative/service.rb +26 -0
- data/lib/nonnative/startup.rb +2 -2
- data/lib/nonnative/version.rb +1 -1
- data/nonnative.gemspec +1 -2
- metadata +13 -27
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9da36cc51d6dd5d1a440767c808455d81dacbf9aa425c185b6d3c3cba24ba949
|
|
4
|
+
data.tar.gz: b5f13df29130761c28cf96f277392ab7b7a9f0a479ed7539d54b3ffc207687bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7a7efe67bb02696eec25e19ff231199219a4e709fb74b746d3d7326358131331f7cb6300e9ec466eec1a7d644d31968d9015ca2a94187d8870fa5c8e6fdf20a1
|
|
7
|
+
data.tar.gz: 2ef73fa52844639694efa346214f95f6705ffbfeea2b8ab6a1476948cd485a7aaf7269150be72b43dd7d660021c77beb8c61a875a10782061557963824c30e03
|
data/.rubocop.yml
CHANGED
|
@@ -8,6 +8,12 @@ Layout/LineLength:
|
|
|
8
8
|
Metrics/MethodLength:
|
|
9
9
|
Max: 15
|
|
10
10
|
|
|
11
|
+
Metrics/BlockLength:
|
|
12
|
+
Max: 35
|
|
13
|
+
|
|
14
|
+
Metrics/AbcSize:
|
|
15
|
+
Max: 20
|
|
16
|
+
|
|
11
17
|
Style/Documentation:
|
|
12
18
|
Enabled: false
|
|
13
19
|
|
|
@@ -37,3 +43,18 @@ Layout/EmptyLinesAroundAttributeAccessor:
|
|
|
37
43
|
|
|
38
44
|
Style/SlicingWithRange:
|
|
39
45
|
Enabled: true
|
|
46
|
+
|
|
47
|
+
Lint/DeprecatedOpenSSLConstant:
|
|
48
|
+
Enabled: true
|
|
49
|
+
|
|
50
|
+
Lint/MixedRegexpCaptureTypes:
|
|
51
|
+
Enabled: true
|
|
52
|
+
|
|
53
|
+
Style/RedundantRegexpCharacterClass:
|
|
54
|
+
Enabled: true
|
|
55
|
+
|
|
56
|
+
Style/RedundantRegexpEscape:
|
|
57
|
+
Enabled: true
|
|
58
|
+
|
|
59
|
+
Style/RedundantFetchBlock:
|
|
60
|
+
Enabled: true
|
data/Gemfile.lock
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
nonnative (1.
|
|
4
|
+
nonnative (1.15.0)
|
|
5
5
|
cucumber (~> 3.1, >= 3.1.2)
|
|
6
6
|
grpc (~> 1.28)
|
|
7
|
-
puma (~> 4.3, >= 4.3.3)
|
|
8
7
|
rest-client (~> 2.1)
|
|
9
8
|
rspec-benchmark (~> 0.6.0)
|
|
10
9
|
rspec-expectations (~> 3.9, >= 3.9.2)
|
|
@@ -16,9 +15,9 @@ GEM
|
|
|
16
15
|
amatch (0.4.0)
|
|
17
16
|
mize
|
|
18
17
|
tins (~> 1.0)
|
|
19
|
-
ast (2.4.
|
|
18
|
+
ast (2.4.1)
|
|
20
19
|
backport (1.1.2)
|
|
21
|
-
backports (3.
|
|
20
|
+
backports (3.18.1)
|
|
22
21
|
benchmark (0.1.0)
|
|
23
22
|
benchmark-malloc (0.2.0)
|
|
24
23
|
benchmark-perf (0.6.0)
|
|
@@ -31,7 +30,7 @@ GEM
|
|
|
31
30
|
pastel (~> 0.7)
|
|
32
31
|
tty-pie (~> 0.3)
|
|
33
32
|
concurrent-ruby (1.1.6)
|
|
34
|
-
cucumber (3.
|
|
33
|
+
cucumber (3.2.0)
|
|
35
34
|
builder (>= 2.1.2)
|
|
36
35
|
cucumber-core (~> 3.2.0)
|
|
37
36
|
cucumber-expressions (~> 6.0.1)
|
|
@@ -47,14 +46,14 @@ GEM
|
|
|
47
46
|
cucumber-expressions (6.0.1)
|
|
48
47
|
cucumber-tag_expressions (1.1.1)
|
|
49
48
|
cucumber-wire (0.0.1)
|
|
50
|
-
diff-lcs (1.
|
|
49
|
+
diff-lcs (1.4.2)
|
|
51
50
|
docile (1.3.2)
|
|
52
51
|
domain_name (0.5.20190701)
|
|
53
52
|
unf (>= 0.0.5, < 1.0.0)
|
|
54
53
|
e2mmap (0.1.0)
|
|
55
54
|
equatable (0.6.1)
|
|
56
55
|
gherkin (5.1.0)
|
|
57
|
-
google-protobuf (3.
|
|
56
|
+
google-protobuf (3.12.2)
|
|
58
57
|
googleapis-common-protos-types (1.0.5)
|
|
59
58
|
google-protobuf (~> 3.11)
|
|
60
59
|
grpc (1.28.0)
|
|
@@ -64,7 +63,7 @@ GEM
|
|
|
64
63
|
http-accept (1.7.0)
|
|
65
64
|
http-cookie (1.0.3)
|
|
66
65
|
domain_name (~> 0.5)
|
|
67
|
-
i18n (1.8.
|
|
66
|
+
i18n (1.8.3)
|
|
68
67
|
concurrent-ruby (~> 1.0)
|
|
69
68
|
jaro_winkler (1.5.4)
|
|
70
69
|
json (2.3.0)
|
|
@@ -80,30 +79,28 @@ GEM
|
|
|
80
79
|
mustermann (1.1.1)
|
|
81
80
|
ruby2_keywords (~> 0.0.1)
|
|
82
81
|
netrc (0.11.0)
|
|
83
|
-
nio4r (2.5.2)
|
|
84
82
|
nokogiri (1.10.9)
|
|
85
83
|
mini_portile2 (~> 2.4.0)
|
|
86
|
-
parallel (1.19.
|
|
87
|
-
parser (2.7.1.
|
|
88
|
-
ast (~> 2.4.
|
|
84
|
+
parallel (1.19.2)
|
|
85
|
+
parser (2.7.1.4)
|
|
86
|
+
ast (~> 2.4.1)
|
|
89
87
|
pastel (0.7.4)
|
|
90
88
|
equatable (~> 0.6)
|
|
91
89
|
tty-color (~> 0.5)
|
|
92
90
|
protocol (2.0.0)
|
|
93
91
|
ruby_parser (~> 3.0)
|
|
94
|
-
|
|
95
|
-
nio4r (~> 2.0)
|
|
96
|
-
rack (2.2.2)
|
|
92
|
+
rack (2.2.3)
|
|
97
93
|
rack-protection (2.0.8.1)
|
|
98
94
|
rack
|
|
99
95
|
rainbow (3.0.0)
|
|
100
96
|
rake (13.0.1)
|
|
97
|
+
regexp_parser (1.7.1)
|
|
101
98
|
rest-client (2.1.0)
|
|
102
99
|
http-accept (>= 1.7.0, < 2.0)
|
|
103
100
|
http-cookie (>= 1.0.2, < 2.0)
|
|
104
101
|
mime-types (>= 1.16, < 4.0)
|
|
105
102
|
netrc (~> 0.8)
|
|
106
|
-
reverse_markdown (
|
|
103
|
+
reverse_markdown (2.0.0)
|
|
107
104
|
nokogiri
|
|
108
105
|
rexml (3.2.4)
|
|
109
106
|
rspec (3.9.0)
|
|
@@ -124,18 +121,22 @@ GEM
|
|
|
124
121
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
125
122
|
rspec-support (~> 3.9.0)
|
|
126
123
|
rspec-support (3.9.3)
|
|
127
|
-
rubocop (0.
|
|
124
|
+
rubocop (0.86.0)
|
|
128
125
|
parallel (~> 1.10)
|
|
129
126
|
parser (>= 2.7.0.1)
|
|
130
127
|
rainbow (>= 2.2.2, < 4.0)
|
|
128
|
+
regexp_parser (>= 1.7)
|
|
131
129
|
rexml
|
|
130
|
+
rubocop-ast (>= 0.0.3, < 1.0)
|
|
132
131
|
ruby-progressbar (~> 1.7)
|
|
133
132
|
unicode-display_width (>= 1.4.0, < 2.0)
|
|
133
|
+
rubocop-ast (0.1.0)
|
|
134
|
+
parser (>= 2.7.0.1)
|
|
134
135
|
ruby-progressbar (1.10.1)
|
|
135
136
|
ruby2_keywords (0.0.2)
|
|
136
137
|
ruby_parser (3.14.2)
|
|
137
138
|
sexp_processor (~> 4.9)
|
|
138
|
-
sexp_processor (4.
|
|
139
|
+
sexp_processor (4.15.0)
|
|
139
140
|
simplecov (0.17.1)
|
|
140
141
|
docile (~> 1.1)
|
|
141
142
|
json (>= 1.8, < 3)
|
|
@@ -146,7 +147,7 @@ GEM
|
|
|
146
147
|
rack (~> 2.0)
|
|
147
148
|
rack-protection (= 2.0.8.1)
|
|
148
149
|
tilt (~> 2.0)
|
|
149
|
-
solargraph (0.39.
|
|
150
|
+
solargraph (0.39.11)
|
|
150
151
|
backport (~> 1.1)
|
|
151
152
|
benchmark
|
|
152
153
|
bundler (>= 1.17.2)
|
|
@@ -155,7 +156,7 @@ GEM
|
|
|
155
156
|
maruku (~> 0.7, >= 0.7.3)
|
|
156
157
|
nokogiri (~> 1.9, >= 1.9.1)
|
|
157
158
|
parser (~> 2.3)
|
|
158
|
-
reverse_markdown (
|
|
159
|
+
reverse_markdown (>= 1.0.5, < 3)
|
|
159
160
|
rubocop (~> 0.52)
|
|
160
161
|
thor (~> 1.0)
|
|
161
162
|
tilt (~> 2.0)
|
|
@@ -163,7 +164,7 @@ GEM
|
|
|
163
164
|
sync (0.5.0)
|
|
164
165
|
thor (1.0.1)
|
|
165
166
|
tilt (2.0.10)
|
|
166
|
-
tins (1.
|
|
167
|
+
tins (1.25.0)
|
|
167
168
|
sync
|
|
168
169
|
tty-color (0.5.1)
|
|
169
170
|
tty-cursor (0.7.1)
|
|
@@ -185,7 +186,7 @@ DEPENDENCIES
|
|
|
185
186
|
grpc-tools (~> 1.28)
|
|
186
187
|
nonnative!
|
|
187
188
|
rake (~> 13.0, >= 13.0.1)
|
|
188
|
-
rubocop (~> 0.
|
|
189
|
+
rubocop (~> 0.86.0)
|
|
189
190
|
simplecov (~> 0.17.1)
|
|
190
191
|
solargraph (~> 0.39.7)
|
|
191
192
|
|
data/README.md
CHANGED
|
@@ -38,13 +38,11 @@ Configure nonnative with the following:
|
|
|
38
38
|
- Port to verify.
|
|
39
39
|
- The class for servers.
|
|
40
40
|
- The file you want STDOUT to be logged to for processes.
|
|
41
|
-
- The strategy
|
|
41
|
+
- The strategy for processes/servers.
|
|
42
|
+
* Startup will start the process once.
|
|
43
|
+
* Before will hook into cucumbers Before and After.
|
|
42
44
|
|
|
43
|
-
###
|
|
44
|
-
|
|
45
|
-
We can start a process, server or both.
|
|
46
|
-
|
|
47
|
-
#### Processes
|
|
45
|
+
### Processes
|
|
48
46
|
|
|
49
47
|
Setup it up programmatically:
|
|
50
48
|
|
|
@@ -55,13 +53,16 @@ Nonnative.configure do |config|
|
|
|
55
53
|
config.strategy = :startup or :before or :manual
|
|
56
54
|
|
|
57
55
|
config.process do |d|
|
|
56
|
+
d.name = 'start_1'
|
|
58
57
|
d.command = 'features/support/bin/start 12_321'
|
|
59
58
|
d.timeout = 0.5
|
|
60
59
|
d.port = 12_321
|
|
61
60
|
d.file = 'features/logs/12_321.log'
|
|
61
|
+
d.signal = 'INT' # Possible values are described in Signal.list.keys
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
config.process do |d|
|
|
65
|
+
d.name = 'start_2'
|
|
65
66
|
d.command = 'features/support/bin/start 12_322'
|
|
66
67
|
d.timeout = 0.5
|
|
67
68
|
d.port = 12_322
|
|
@@ -77,11 +78,14 @@ version: 1.0
|
|
|
77
78
|
strategy: manual
|
|
78
79
|
processes:
|
|
79
80
|
-
|
|
81
|
+
name: start_1
|
|
80
82
|
command: features/support/bin/start 12_321
|
|
81
83
|
timeout: 5
|
|
82
84
|
port: 12321
|
|
83
85
|
file: features/logs/12_321.log
|
|
86
|
+
signal: INT # Possible values are described in Signal.list.keys
|
|
84
87
|
-
|
|
88
|
+
name: start_2
|
|
85
89
|
command: features/support/bin/start 12_322
|
|
86
90
|
timeout: 5
|
|
87
91
|
port: 12322
|
|
@@ -96,7 +100,7 @@ require 'nonnative'
|
|
|
96
100
|
Nonnative.load_configuration('configuration.yml')
|
|
97
101
|
```
|
|
98
102
|
|
|
99
|
-
|
|
103
|
+
### Servers
|
|
100
104
|
|
|
101
105
|
Define your server:
|
|
102
106
|
|
|
@@ -130,12 +134,14 @@ Nonnative.configure do |config|
|
|
|
130
134
|
config.strategy = :manual
|
|
131
135
|
|
|
132
136
|
config.server do |d|
|
|
137
|
+
d.name = 'server_1'
|
|
133
138
|
d.klass = Nonnative::EchoServer
|
|
134
139
|
d.timeout = 1
|
|
135
140
|
d.port = 12_323
|
|
136
141
|
end
|
|
137
142
|
|
|
138
143
|
config.server do |d|
|
|
144
|
+
d.name = 'server_2'
|
|
139
145
|
d.klass = Nonnative::EchoServer
|
|
140
146
|
d.timeout = 1
|
|
141
147
|
d.port = 12_324
|
|
@@ -150,10 +156,12 @@ version: 1.0
|
|
|
150
156
|
strategy: manual
|
|
151
157
|
servers:
|
|
152
158
|
-
|
|
159
|
+
name: server_1
|
|
153
160
|
klass: Nonnative::EchoServer
|
|
154
161
|
timeout: 1
|
|
155
162
|
port: 12323
|
|
156
163
|
-
|
|
164
|
+
name: server_2
|
|
157
165
|
klass: Nonnative::EchoServer
|
|
158
166
|
timeout: 1
|
|
159
167
|
port: 12324
|
|
@@ -167,26 +175,22 @@ require 'nonnative'
|
|
|
167
175
|
Nonnative.load_configuration('configuration.yml')
|
|
168
176
|
```
|
|
169
177
|
|
|
170
|
-
|
|
178
|
+
#### HTTP
|
|
171
179
|
|
|
172
180
|
Define your server:
|
|
173
181
|
|
|
174
182
|
```ruby
|
|
175
183
|
module Nonnative
|
|
176
184
|
module Features
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
app.get '/hello' do
|
|
181
|
-
'Hello World!'
|
|
182
|
-
end
|
|
183
|
-
end
|
|
185
|
+
class Application < Sinatra::Base
|
|
186
|
+
get '/hello' do
|
|
187
|
+
'Hello World!'
|
|
184
188
|
end
|
|
185
189
|
end
|
|
186
190
|
|
|
187
191
|
class HTTPServer < Nonnative::HTTPServer
|
|
188
|
-
def
|
|
189
|
-
|
|
192
|
+
def app
|
|
193
|
+
Application.new
|
|
190
194
|
end
|
|
191
195
|
end
|
|
192
196
|
end
|
|
@@ -202,6 +206,7 @@ Nonnative.configure do |config|
|
|
|
202
206
|
config.strategy = :manual
|
|
203
207
|
|
|
204
208
|
config.server do |d|
|
|
209
|
+
d.name = 'http_server_1'
|
|
205
210
|
d.klass = Nonnative::Features::HTTPServer
|
|
206
211
|
d.timeout = 1
|
|
207
212
|
d.port = 4567
|
|
@@ -216,6 +221,7 @@ version: 1.0
|
|
|
216
221
|
strategy: manual
|
|
217
222
|
servers:
|
|
218
223
|
-
|
|
224
|
+
name: http_server_1
|
|
219
225
|
klass: Nonnative::Features::HTTPServer
|
|
220
226
|
timeout: 1
|
|
221
227
|
port: 4567
|
|
@@ -229,7 +235,7 @@ require 'nonnative'
|
|
|
229
235
|
Nonnative.load_configuration('configuration.yml')
|
|
230
236
|
```
|
|
231
237
|
|
|
232
|
-
|
|
238
|
+
#### gRPC
|
|
233
239
|
|
|
234
240
|
Define your server:
|
|
235
241
|
|
|
@@ -260,6 +266,7 @@ Nonnative.configure do |config|
|
|
|
260
266
|
config.strategy = :manual
|
|
261
267
|
|
|
262
268
|
config.server do |d|
|
|
269
|
+
d.name = 'grpc_server_1'
|
|
263
270
|
d.klass = Nonnative::Features::GRPCServer
|
|
264
271
|
d.timeout = 1
|
|
265
272
|
d.port = 9002
|
|
@@ -274,6 +281,7 @@ version: 1.0
|
|
|
274
281
|
strategy: manual
|
|
275
282
|
servers:
|
|
276
283
|
-
|
|
284
|
+
name: grpc_server_1
|
|
277
285
|
klass: Nonnative::Features::GRPCServer
|
|
278
286
|
timeout: 1
|
|
279
287
|
port: 9002
|
|
@@ -286,3 +294,35 @@ require 'nonnative'
|
|
|
286
294
|
|
|
287
295
|
Nonnative.load_configuration('configuration.yml')
|
|
288
296
|
```
|
|
297
|
+
#### Proxies
|
|
298
|
+
|
|
299
|
+
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
|
|
302
|
+
|
|
303
|
+
Setup it up programmatically:
|
|
304
|
+
|
|
305
|
+
```ruby
|
|
306
|
+
require 'nonnative'
|
|
307
|
+
|
|
308
|
+
Nonnative.configure do |config|
|
|
309
|
+
config.strategy = :manual
|
|
310
|
+
|
|
311
|
+
config.server do |d|
|
|
312
|
+
d.proxy.type = 'chaos'
|
|
313
|
+
d.proxy.port = 20_000
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Setup it up through configuration:
|
|
319
|
+
|
|
320
|
+
```yaml
|
|
321
|
+
version: 1.0
|
|
322
|
+
strategy: manual
|
|
323
|
+
servers:
|
|
324
|
+
-
|
|
325
|
+
proxy:
|
|
326
|
+
type: chaos
|
|
327
|
+
port: 20000
|
|
328
|
+
```
|
data/lib/nonnative.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'socket'
|
|
|
4
4
|
require 'timeout'
|
|
5
5
|
require 'thwait'
|
|
6
6
|
require 'yaml'
|
|
7
|
+
require 'webrick'
|
|
7
8
|
|
|
8
9
|
require 'grpc'
|
|
9
10
|
require 'sinatra'
|
|
@@ -18,6 +19,8 @@ require 'nonnative/port'
|
|
|
18
19
|
require 'nonnative/configuration'
|
|
19
20
|
require 'nonnative/configuration_process'
|
|
20
21
|
require 'nonnative/configuration_server'
|
|
22
|
+
require 'nonnative/configuration_proxy'
|
|
23
|
+
require 'nonnative/service'
|
|
21
24
|
require 'nonnative/command'
|
|
22
25
|
require 'nonnative/pool'
|
|
23
26
|
require 'nonnative/server'
|
|
@@ -26,6 +29,12 @@ require 'nonnative/http_server'
|
|
|
26
29
|
require 'nonnative/grpc_server'
|
|
27
30
|
require 'nonnative/grpc_server'
|
|
28
31
|
require 'nonnative/observability'
|
|
32
|
+
require 'nonnative/proxy_factory'
|
|
33
|
+
require 'nonnative/proxy'
|
|
34
|
+
require 'nonnative/no_proxy'
|
|
35
|
+
require 'nonnative/chaos_proxy'
|
|
36
|
+
|
|
37
|
+
Thread.abort_on_exception = true
|
|
29
38
|
|
|
30
39
|
module Nonnative
|
|
31
40
|
class << self
|
|
@@ -38,25 +47,32 @@ module Nonnative
|
|
|
38
47
|
end
|
|
39
48
|
|
|
40
49
|
def configure
|
|
41
|
-
yield configuration
|
|
50
|
+
yield configuration
|
|
42
51
|
|
|
43
52
|
require "nonnative/#{configuration.strategy}"
|
|
44
53
|
end
|
|
45
54
|
|
|
46
55
|
def start
|
|
47
56
|
@pool ||= Nonnative::Pool.new(configuration)
|
|
57
|
+
errors = []
|
|
48
58
|
|
|
49
59
|
@pool.start do |name, id, result|
|
|
50
|
-
|
|
60
|
+
errors << "Started #{name} with id #{id}, though did respond in time" unless result
|
|
51
61
|
end
|
|
62
|
+
|
|
63
|
+
raise Nonnative::StartError, errors.join("\n") unless errors.empty?
|
|
52
64
|
end
|
|
53
65
|
|
|
54
66
|
def stop
|
|
55
67
|
return if @pool.nil?
|
|
56
68
|
|
|
69
|
+
errors = []
|
|
70
|
+
|
|
57
71
|
@pool.stop do |name, id, result|
|
|
58
|
-
|
|
72
|
+
errors << "Stopped #{name} with id #{id}, though did respond in time" unless result
|
|
59
73
|
end
|
|
74
|
+
|
|
75
|
+
raise Nonnative::StopError, errors.join("\n") unless errors.empty?
|
|
60
76
|
end
|
|
61
77
|
|
|
62
78
|
def clear
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nonnative
|
|
4
|
+
class ChaosProxy < Nonnative::Proxy
|
|
5
|
+
def start
|
|
6
|
+
@tcp_server = ::TCPServer.new('0.0.0.0', service.port)
|
|
7
|
+
@thread = Thread.new { perform_start }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def stop
|
|
11
|
+
thread.terminate
|
|
12
|
+
tcp_server.close
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def port
|
|
16
|
+
service.proxy.port
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
attr_reader :tcp_server, :thread
|
|
22
|
+
|
|
23
|
+
def perform_start
|
|
24
|
+
loop do
|
|
25
|
+
Thread.start(tcp_server.accept) { |local_socket| connect(local_socket) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def connect(local_socket)
|
|
30
|
+
remote_socket = create_remote_socket
|
|
31
|
+
return unless remote_socket
|
|
32
|
+
|
|
33
|
+
loop do
|
|
34
|
+
ready = select([local_socket, remote_socket], nil, nil)
|
|
35
|
+
|
|
36
|
+
break if write(ready, local_socket, remote_socket)
|
|
37
|
+
break if write(ready, remote_socket, local_socket)
|
|
38
|
+
end
|
|
39
|
+
ensure
|
|
40
|
+
local_socket.close
|
|
41
|
+
remote_socket&.close
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def create_remote_socket
|
|
45
|
+
timeout.perform do
|
|
46
|
+
::TCPSocket.new('0.0.0.0', port)
|
|
47
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
|
48
|
+
sleep 0.01
|
|
49
|
+
retry
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def write(ready, socket1, socket2)
|
|
54
|
+
if ready[0].include?(socket1)
|
|
55
|
+
data = socket1.recv(1024)
|
|
56
|
+
return true if data.empty?
|
|
57
|
+
|
|
58
|
+
socket2.write(data)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
false
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
data/lib/nonnative/command.rb
CHANGED
|
@@ -1,36 +1,54 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Nonnative
|
|
4
|
-
class Command
|
|
5
|
-
def initialize(process)
|
|
6
|
-
@process = process
|
|
7
|
-
@started = false
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def name
|
|
11
|
-
process.command
|
|
12
|
-
end
|
|
13
|
-
|
|
4
|
+
class Command < Nonnative::Service
|
|
14
5
|
def start
|
|
15
|
-
unless
|
|
16
|
-
@pid =
|
|
17
|
-
|
|
6
|
+
unless command_exists?
|
|
7
|
+
@pid = command_spawn
|
|
8
|
+
wait_start
|
|
18
9
|
end
|
|
19
10
|
|
|
20
11
|
pid
|
|
21
12
|
end
|
|
22
13
|
|
|
23
14
|
def stop
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
15
|
+
if command_exists?
|
|
16
|
+
command_kill
|
|
17
|
+
wait_stop
|
|
18
|
+
end
|
|
28
19
|
|
|
29
20
|
pid
|
|
30
21
|
end
|
|
31
22
|
|
|
23
|
+
protected
|
|
24
|
+
|
|
25
|
+
def wait_stop
|
|
26
|
+
timeout.perform do
|
|
27
|
+
Process.waitpid2(pid)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
32
31
|
private
|
|
33
32
|
|
|
34
|
-
attr_reader :
|
|
33
|
+
attr_reader :pid
|
|
34
|
+
|
|
35
|
+
def command_kill
|
|
36
|
+
signal = Signal.list[service.signal || 'INT'] || Signal.list['INT']
|
|
37
|
+
Process.kill(signal, pid)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def command_spawn
|
|
41
|
+
spawn(service.command, %i[out err] => [service.file, 'a'])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def command_exists?
|
|
45
|
+
return false if pid.nil?
|
|
46
|
+
|
|
47
|
+
signal = Signal.list['EXIT']
|
|
48
|
+
Process.kill(signal, pid)
|
|
49
|
+
true
|
|
50
|
+
rescue Errno::ESRCH
|
|
51
|
+
false
|
|
52
|
+
end
|
|
35
53
|
end
|
|
36
54
|
end
|
|
@@ -20,10 +20,12 @@ module Nonnative
|
|
|
20
20
|
processes = file['processes'] || []
|
|
21
21
|
processes.each do |fd|
|
|
22
22
|
config.process do |d|
|
|
23
|
+
d.name = fd['name']
|
|
23
24
|
d.command = fd['command']
|
|
24
25
|
d.timeout = fd['timeout']
|
|
25
26
|
d.port = fd['port']
|
|
26
27
|
d.file = fd['file']
|
|
28
|
+
d.signal = fd['signal']
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
end
|
|
@@ -32,9 +34,17 @@ module Nonnative
|
|
|
32
34
|
servers = file['servers'] || []
|
|
33
35
|
servers.each do |fd|
|
|
34
36
|
config.server do |s|
|
|
37
|
+
s.name = fd['name']
|
|
35
38
|
s.klass = Object.const_get(fd['klass'])
|
|
36
39
|
s.timeout = fd['timeout']
|
|
37
40
|
s.port = fd['port']
|
|
41
|
+
|
|
42
|
+
proxy = fd['proxy']
|
|
43
|
+
|
|
44
|
+
if proxy
|
|
45
|
+
s.proxy.type = proxy['type']
|
|
46
|
+
s.proxy.port = proxy['port']
|
|
47
|
+
end
|
|
38
48
|
end
|
|
39
49
|
end
|
|
40
50
|
end
|
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
module Nonnative
|
|
4
4
|
class ConfigurationServer
|
|
5
|
+
attr_accessor :name
|
|
5
6
|
attr_accessor :klass
|
|
6
7
|
attr_accessor :timeout
|
|
7
8
|
attr_accessor :port
|
|
9
|
+
attr_accessor :proxy
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
self.proxy = Nonnative::ConfigurationProxy.new
|
|
13
|
+
end
|
|
8
14
|
end
|
|
9
15
|
end
|
|
@@ -2,20 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
module Nonnative
|
|
4
4
|
class GRPCServer < Nonnative::Server
|
|
5
|
-
def initialize(
|
|
5
|
+
def initialize(service)
|
|
6
6
|
@server = GRPC::RpcServer.new
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
configure server
|
|
10
|
-
|
|
11
|
-
super port
|
|
8
|
+
super service
|
|
12
9
|
end
|
|
13
10
|
|
|
14
|
-
def configure(
|
|
11
|
+
def configure(server)
|
|
15
12
|
# Classes will add configuration
|
|
16
13
|
end
|
|
17
14
|
|
|
15
|
+
protected
|
|
16
|
+
|
|
18
17
|
def perform_start
|
|
18
|
+
server.add_http2_port("0.0.0.0:#{proxy.port}", :this_port_is_insecure)
|
|
19
|
+
configure server
|
|
20
|
+
|
|
19
21
|
server.run
|
|
20
22
|
end
|
|
21
23
|
|
|
@@ -23,6 +25,10 @@ module Nonnative
|
|
|
23
25
|
server.stop
|
|
24
26
|
end
|
|
25
27
|
|
|
28
|
+
def wait_start
|
|
29
|
+
server.wait_till_running(service.timeout)
|
|
30
|
+
end
|
|
31
|
+
|
|
26
32
|
private
|
|
27
33
|
|
|
28
34
|
attr_reader :server
|
|
@@ -22,6 +22,20 @@ module Nonnative
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def delete(pathname, headers = {})
|
|
26
|
+
with_exception do
|
|
27
|
+
uri = URI.join(host, pathname)
|
|
28
|
+
RestClient.delete(uri.to_s, headers)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def put(pathname, payload, headers = {})
|
|
33
|
+
with_exception do
|
|
34
|
+
uri = URI.join(host, pathname)
|
|
35
|
+
RestClient.put(uri.to_s, payload.to_json, headers)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
25
39
|
private
|
|
26
40
|
|
|
27
41
|
attr_reader :host
|
|
@@ -2,30 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
module Nonnative
|
|
4
4
|
class HTTPServer < Nonnative::Server
|
|
5
|
-
|
|
6
|
-
Application.set :port, port
|
|
7
|
-
configure Application
|
|
8
|
-
|
|
9
|
-
super port
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def configure(http)
|
|
13
|
-
# Classes will add configuration
|
|
14
|
-
end
|
|
5
|
+
protected
|
|
15
6
|
|
|
16
7
|
def perform_start
|
|
17
|
-
|
|
8
|
+
options = {
|
|
9
|
+
Host: '0.0.0.0',
|
|
10
|
+
Port: proxy.port,
|
|
11
|
+
Logger: ::WEBrick::Log.new('/dev/null'),
|
|
12
|
+
AccessLog: []
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
Rack::Handler::WEBrick.run(app, options) do |server|
|
|
16
|
+
@server = server
|
|
17
|
+
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def perform_stop
|
|
21
|
-
|
|
21
|
+
server.shutdown
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
set :logging, false
|
|
28
|
-
set :quiet, true
|
|
29
|
-
end
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
attr_reader :queue, :server
|
|
30
27
|
end
|
|
31
28
|
end
|
data/lib/nonnative/pool.rb
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nonnative
|
|
4
|
+
class ProxyFactory
|
|
5
|
+
class << self
|
|
6
|
+
def create(service)
|
|
7
|
+
case service.proxy.type
|
|
8
|
+
when 'chaos'
|
|
9
|
+
ChaosProxy.new(service)
|
|
10
|
+
else
|
|
11
|
+
# By default we want no proxy.
|
|
12
|
+
NoProxy.new(service)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/nonnative/server.rb
CHANGED
|
@@ -1,29 +1,44 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Nonnative
|
|
4
|
-
class Server <
|
|
5
|
-
def initialize(
|
|
6
|
-
@
|
|
7
|
-
|
|
4
|
+
class Server < Nonnative::Service
|
|
5
|
+
def initialize(service)
|
|
6
|
+
@id = SecureRandom.hex(5)
|
|
7
|
+
@proxy = Nonnative::ProxyFactory.create(service)
|
|
8
8
|
|
|
9
|
-
super
|
|
10
|
-
perform_start
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def name
|
|
15
|
-
self.class.to_s
|
|
9
|
+
super service
|
|
16
10
|
end
|
|
17
11
|
|
|
18
12
|
def start
|
|
19
|
-
|
|
13
|
+
unless thread
|
|
14
|
+
proxy.start
|
|
15
|
+
@thread = Thread.new { perform_start }
|
|
16
|
+
|
|
17
|
+
wait_start
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
id
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
def stop
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
if thread
|
|
25
|
+
perform_stop
|
|
26
|
+
thread.terminate
|
|
27
|
+
proxy.stop
|
|
28
|
+
|
|
29
|
+
@thread = nil
|
|
30
|
+
wait_stop
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
id
|
|
25
34
|
end
|
|
26
35
|
|
|
27
|
-
|
|
36
|
+
protected
|
|
37
|
+
|
|
38
|
+
attr_reader :id
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
attr_reader :proxy, :thread
|
|
28
43
|
end
|
|
29
44
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nonnative
|
|
4
|
+
class Service
|
|
5
|
+
def initialize(service)
|
|
6
|
+
@service = service
|
|
7
|
+
@timeout = Nonnative::Timeout.new(service.timeout)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def name
|
|
11
|
+
service.name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
attr_reader :service, :timeout
|
|
17
|
+
|
|
18
|
+
def wait_start
|
|
19
|
+
sleep 0.2
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def wait_stop
|
|
23
|
+
sleep 0.2
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/nonnative/startup.rb
CHANGED
data/lib/nonnative/version.rb
CHANGED
data/nonnative.gemspec
CHANGED
|
@@ -26,7 +26,6 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
|
|
27
27
|
spec.add_dependency 'cucumber', '~> 3.1', '>= 3.1.2'
|
|
28
28
|
spec.add_dependency 'grpc', '~> 1.28'
|
|
29
|
-
spec.add_dependency 'puma', '~> 4.3', '>= 4.3.3'
|
|
30
29
|
spec.add_dependency 'rest-client', '~> 2.1'
|
|
31
30
|
spec.add_dependency 'rspec-benchmark', '~> 0.6.0'
|
|
32
31
|
spec.add_dependency 'rspec-expectations', '~> 3.9', '>= 3.9.2'
|
|
@@ -36,7 +35,7 @@ Gem::Specification.new do |spec|
|
|
|
36
35
|
spec.add_development_dependency 'chutney', '~> 2.0', '>= 2.0.3.1'
|
|
37
36
|
spec.add_development_dependency 'grpc-tools', '~> 1.28'
|
|
38
37
|
spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.1'
|
|
39
|
-
spec.add_development_dependency 'rubocop', '~> 0.
|
|
38
|
+
spec.add_development_dependency 'rubocop', '~> 0.86.0'
|
|
40
39
|
spec.add_development_dependency 'simplecov', '~> 0.17.1'
|
|
41
40
|
spec.add_development_dependency 'solargraph', '~> 0.39.7'
|
|
42
41
|
end
|
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.15.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-
|
|
11
|
+
date: 2020-07-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cucumber
|
|
@@ -44,26 +44,6 @@ dependencies:
|
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
46
|
version: '1.28'
|
|
47
|
-
- !ruby/object:Gem::Dependency
|
|
48
|
-
name: puma
|
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - "~>"
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '4.3'
|
|
54
|
-
- - ">="
|
|
55
|
-
- !ruby/object:Gem::Version
|
|
56
|
-
version: 4.3.3
|
|
57
|
-
type: :runtime
|
|
58
|
-
prerelease: false
|
|
59
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
60
|
-
requirements:
|
|
61
|
-
- - "~>"
|
|
62
|
-
- !ruby/object:Gem::Version
|
|
63
|
-
version: '4.3'
|
|
64
|
-
- - ">="
|
|
65
|
-
- !ruby/object:Gem::Version
|
|
66
|
-
version: 4.3.3
|
|
67
47
|
- !ruby/object:Gem::Dependency
|
|
68
48
|
name: rest-client
|
|
69
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -212,14 +192,14 @@ dependencies:
|
|
|
212
192
|
requirements:
|
|
213
193
|
- - "~>"
|
|
214
194
|
- !ruby/object:Gem::Version
|
|
215
|
-
version: 0.
|
|
195
|
+
version: 0.86.0
|
|
216
196
|
type: :development
|
|
217
197
|
prerelease: false
|
|
218
198
|
version_requirements: !ruby/object:Gem::Requirement
|
|
219
199
|
requirements:
|
|
220
200
|
- - "~>"
|
|
221
201
|
- !ruby/object:Gem::Version
|
|
222
|
-
version: 0.
|
|
202
|
+
version: 0.86.0
|
|
223
203
|
- !ruby/object:Gem::Dependency
|
|
224
204
|
name: simplecov
|
|
225
205
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -271,19 +251,25 @@ files:
|
|
|
271
251
|
- bin/setup
|
|
272
252
|
- lib/nonnative.rb
|
|
273
253
|
- lib/nonnative/before.rb
|
|
254
|
+
- lib/nonnative/chaos_proxy.rb
|
|
274
255
|
- lib/nonnative/command.rb
|
|
275
256
|
- lib/nonnative/configuration.rb
|
|
276
257
|
- lib/nonnative/configuration_process.rb
|
|
258
|
+
- lib/nonnative/configuration_proxy.rb
|
|
277
259
|
- lib/nonnative/configuration_server.rb
|
|
278
260
|
- lib/nonnative/error.rb
|
|
279
261
|
- lib/nonnative/grpc_server.rb
|
|
280
262
|
- lib/nonnative/http_client.rb
|
|
281
263
|
- lib/nonnative/http_server.rb
|
|
282
264
|
- lib/nonnative/manual.rb
|
|
265
|
+
- lib/nonnative/no_proxy.rb
|
|
283
266
|
- lib/nonnative/observability.rb
|
|
284
267
|
- lib/nonnative/pool.rb
|
|
285
268
|
- lib/nonnative/port.rb
|
|
269
|
+
- lib/nonnative/proxy.rb
|
|
270
|
+
- lib/nonnative/proxy_factory.rb
|
|
286
271
|
- lib/nonnative/server.rb
|
|
272
|
+
- lib/nonnative/service.rb
|
|
287
273
|
- lib/nonnative/start_error.rb
|
|
288
274
|
- lib/nonnative/startup.rb
|
|
289
275
|
- lib/nonnative/stop_error.rb
|
|
@@ -295,7 +281,7 @@ homepage: https://github.com/alexfalkowski/nonnative
|
|
|
295
281
|
licenses:
|
|
296
282
|
- Unlicense
|
|
297
283
|
metadata: {}
|
|
298
|
-
post_install_message:
|
|
284
|
+
post_install_message:
|
|
299
285
|
rdoc_options: []
|
|
300
286
|
require_paths:
|
|
301
287
|
- lib
|
|
@@ -311,7 +297,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
311
297
|
version: '0'
|
|
312
298
|
requirements: []
|
|
313
299
|
rubygems_version: 3.0.3
|
|
314
|
-
signing_key:
|
|
300
|
+
signing_key:
|
|
315
301
|
specification_version: 4
|
|
316
302
|
summary: Allows you to keep using the power of ruby to test other systems
|
|
317
303
|
test_files: []
|