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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abced57dc4a0e8f7019a4910f512a90d7e4e3eadc7a0ddd5ac89b7af0e90fdf6
4
- data.tar.gz: ea1cfc833c0448b8d5e90db251b1ef5c88f9ecc69f08e9e04c2cd68eb6395dbe
3
+ metadata.gz: 9da36cc51d6dd5d1a440767c808455d81dacbf9aa425c185b6d3c3cba24ba949
4
+ data.tar.gz: b5f13df29130761c28cf96f277392ab7b7a9f0a479ed7539d54b3ffc207687bf
5
5
  SHA512:
6
- metadata.gz: 266f8adf8b7d05ee37c603e4e748ed76bec1ae9bd42a3e41ad4d3519b7ed9b32f80085a690d74687c536d152acd748cfee2503d8c18650ce034ae8bec36dff3b
7
- data.tar.gz: '018a25432a012bb70e0989dc273483356171785aa966e908fdf07ebb7aac51148e1772b20b246f04388d0469ab82922dccac3a5e14155a918f2b16ec86e58628'
6
+ metadata.gz: 7a7efe67bb02696eec25e19ff231199219a4e709fb74b746d3d7326358131331f7cb6300e9ec466eec1a7d644d31968d9015ca2a94187d8870fa5c8e6fdf20a1
7
+ data.tar.gz: 2ef73fa52844639694efa346214f95f6705ffbfeea2b8ab6a1476948cd485a7aaf7269150be72b43dd7d660021c77beb8c61a875a10782061557963824c30e03
@@ -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
@@ -1,10 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nonnative (1.10.0)
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.0)
18
+ ast (2.4.1)
20
19
  backport (1.1.2)
21
- backports (3.17.1)
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.1.2)
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.3)
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.11.4)
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.2)
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.1)
87
- parser (2.7.1.2)
88
- ast (~> 2.4.0)
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
- puma (4.3.3)
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 (1.4.0)
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.83.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.14.1)
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.7)
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 (~> 1.0, >= 1.0.5)
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.24.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.83.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 (Startup will start the process once and before will hook into cucumbers Before and After) for processes.
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
- ### Ruby
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
- #### Servers
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
- ##### HTTP
178
+ #### HTTP
171
179
 
172
180
  Define your server:
173
181
 
174
182
  ```ruby
175
183
  module Nonnative
176
184
  module Features
177
- module Hello
178
- class << self
179
- def registered(app)
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 configure(http)
189
- http.register(Hello)
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
- ##### gRPC
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
+ ```
@@ -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 if block_given?
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
- raise Nonnative::StartError, "Started #{name} with id #{id}, though did respond in time" unless result
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
- raise Nonnative::StopError, "Stopped #{name} with id #{id}, though did respond in time" unless result
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
@@ -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 started
16
- @pid = spawn(process.command, %i[out err] => [process.file, 'a'])
17
- @started = true
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
- raise Nonnative::Error, "Can't stop a process that has not started" unless started
25
-
26
- ::Process.kill('SIGINT', pid)
27
- @started = false
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 :process, :pid, :started
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,9 +2,11 @@
2
2
 
3
3
  module Nonnative
4
4
  class ConfigurationProcess
5
+ attr_accessor :name
5
6
  attr_accessor :command
6
7
  attr_accessor :timeout
7
8
  attr_accessor :port
8
9
  attr_accessor :file
10
+ attr_accessor :signal
9
11
  end
10
12
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nonnative
4
+ class ConfigurationProxy
5
+ attr_accessor :type
6
+ attr_accessor :port
7
+
8
+ def initialize
9
+ self.type = 'none'
10
+ self.port = 0
11
+ end
12
+ end
13
+ 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(port)
5
+ def initialize(service)
6
6
  @server = GRPC::RpcServer.new
7
7
 
8
- server.add_http2_port("0.0.0.0:#{port}", :this_port_is_insecure)
9
- configure server
10
-
11
- super port
8
+ super service
12
9
  end
13
10
 
14
- def configure(grpc)
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
- def initialize(port)
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
- Application.start!
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
- Application.stop!
21
+ server.shutdown
22
22
  end
23
23
 
24
- class Application < Sinatra::Application
25
- set :bind, '0.0.0.0'
26
- set :server, :puma
27
- set :logging, false
28
- set :quiet, true
29
- end
24
+ private
25
+
26
+ attr_reader :queue, :server
30
27
  end
31
28
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nonnative
4
+ class NoProxy < Proxy
5
+ def start
6
+ # Do nothing.
7
+ end
8
+
9
+ def stop
10
+ # Do nothing.
11
+ end
12
+
13
+ def port
14
+ service.port
15
+ end
16
+ end
17
+ end
@@ -28,7 +28,7 @@ module Nonnative
28
28
 
29
29
  def servers
30
30
  @servers ||= configuration.servers.map do |d|
31
- [d.klass.new(d.port), Nonnative::Port.new(d)]
31
+ [d.klass.new(d), Nonnative::Port.new(d)]
32
32
  end
33
33
  end
34
34
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nonnative
4
+ class Proxy
5
+ def initialize(service)
6
+ @service = service
7
+ @timeout = Nonnative::Timeout.new(service.timeout)
8
+ end
9
+
10
+ protected
11
+
12
+ attr_reader :service, :timeout
13
+ end
14
+ end
@@ -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
@@ -1,29 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nonnative
4
- class Server < Thread
5
- def initialize(port)
6
- @port = port
7
- self.abort_on_exception = true
4
+ class Server < Nonnative::Service
5
+ def initialize(service)
6
+ @id = SecureRandom.hex(5)
7
+ @proxy = Nonnative::ProxyFactory.create(service)
8
8
 
9
- super do
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
- object_id
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
- perform_stop
24
- object_id
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
- attr_reader :port
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Nonnative.start
4
-
5
3
  at_exit do
6
4
  Nonnative.stop
7
5
  end
6
+
7
+ Nonnative.start
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nonnative
4
- VERSION = '1.10.0'
4
+ VERSION = '1.15.0'
5
5
  end
@@ -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.83.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.10.0
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-05-14 00:00:00.000000000 Z
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.83.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.83.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: []