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 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: []