nonnative 1.10.0 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|