nonnative 3.10.0 → 3.11.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/Gemfile.lock +1 -1
- data/README.md +46 -11
- data/lib/nonnative/configuration_readiness.rb +10 -1
- data/lib/nonnative/cucumber.rb +2 -1
- data/lib/nonnative/http_probe.rb +1 -1
- data/lib/nonnative/no_proxy.rb +4 -4
- data/lib/nonnative/startup.rb +5 -0
- data/lib/nonnative/version.rb +1 -1
- data/lib/nonnative.rb +5 -0
- data/nonnative.gemspec +2 -2
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a7d0e5ea6dab1d00eedd363fc81d05d2dd3e4401a97729043bcd3132a071432
|
|
4
|
+
data.tar.gz: 53c589eda9e895f3c815446003c97e77859ccec3b0c021182dc1437d0632b267
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: be0b0b0d4cf1f606fe973f7bb6e38b3f2679b8445d6f24f7f05c4ca37eea62fc36f8910f6d0bcf44c1329b71d6638625d7d4a0d3226a14912662d91980523c1e
|
|
7
|
+
data.tar.gz: 15caeabfe50acdf2513ac2519bc953fb70effcc662c948c293be646d949bdb60c570359fb0817a6eb528207004f6a7cadfd440628026b58a0e9375003f650389
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -38,6 +38,18 @@ Or install it yourself as:
|
|
|
38
38
|
gem install nonnative
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
## 🛠️ Contributor Bootstrap
|
|
42
|
+
|
|
43
|
+
Fresh clones need the shared `bin/` submodule before Make targets can load:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git submodule sync && git submodule update --init
|
|
47
|
+
make help
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Use `make dep` before local validation when dependencies are missing. The CI-parity checks are
|
|
51
|
+
`make lint`, `make sec`, `make features`, and `make benchmarks`.
|
|
52
|
+
|
|
41
53
|
## 🚀 Usage
|
|
42
54
|
|
|
43
55
|
Nonnative is configured via `Nonnative.configure` (programmatic) or `config.load_file(...)` (YAML).
|
|
@@ -67,12 +79,12 @@ Process/server fields:
|
|
|
67
79
|
- `log`: per-runner log file used by process output redirection or server implementations.
|
|
68
80
|
|
|
69
81
|
Process-only fields:
|
|
70
|
-
- `readiness`: optional HTTP startup readiness check with explicit `port` and `path`.
|
|
82
|
+
- `readiness`: optional HTTP startup readiness check with explicit `port` and path-only `path`.
|
|
71
83
|
|
|
72
84
|
Service fields:
|
|
73
85
|
- `port`: client-facing service port. Services do not get TCP readiness/shutdown checks from Nonnative.
|
|
74
86
|
|
|
75
|
-
Nonnative readiness and shutdown checks are TCP port checks by default. Configure process/server ports that are dedicated to the test run; if another process is already listening on the same endpoint, results are undefined. Processes can also opt into an HTTP readiness check that runs after TCP readiness succeeds.
|
|
87
|
+
Nonnative readiness and shutdown checks are TCP port checks by default. Configure process/server ports that are dedicated to the test run; if another process is already listening on the same endpoint, results are undefined. Processes can also opt into an HTTP readiness check that runs after TCP readiness succeeds. HTTP readiness paths must be path-only values, such as `/test/readyz`; absolute URLs and scheme-relative URLs are rejected.
|
|
76
88
|
|
|
77
89
|
> [!WARNING]
|
|
78
90
|
> TCP readiness and shutdown checks only prove that a TCP port opened or closed. HTTP readiness is process-only, checks for a 2xx response, and does not verify gRPC health, schema readiness, migrations, or other application-specific health.
|
|
@@ -98,6 +110,37 @@ Nonnative.stop
|
|
|
98
110
|
> Call `Nonnative.clear` before reconfiguring Nonnative or starting a new lifecycle in the same Ruby process.
|
|
99
111
|
> `Nonnative.clear` clears memoized configuration, logger, observability client, and pool.
|
|
100
112
|
|
|
113
|
+
### 🧩 Test framework setup
|
|
114
|
+
|
|
115
|
+
For Cucumber, load and configure Nonnative in `features/support/env.rb`, then use lifecycle tags on scenarios:
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
require 'nonnative'
|
|
119
|
+
|
|
120
|
+
Nonnative.configure do |config|
|
|
121
|
+
config.load_file('configuration.yml')
|
|
122
|
+
end
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```cucumber
|
|
126
|
+
@startup
|
|
127
|
+
Scenario: run with Nonnative around this scenario
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
For RSpec or another suite that should start Nonnative once per test run, configure first and then require the startup integration:
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
require 'nonnative'
|
|
134
|
+
|
|
135
|
+
Nonnative.configure do |config|
|
|
136
|
+
config.load_file('configuration.yml')
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
require 'nonnative/startup'
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`nonnative/startup` calls `Nonnative.start` immediately and registers an `at_exit` stop, so load configuration before requiring it.
|
|
143
|
+
|
|
101
144
|
### 📈 Observability
|
|
102
145
|
|
|
103
146
|
`Nonnative.observability` is an HTTP client for common service endpoints under the configured `name` and `url`:
|
|
@@ -123,7 +166,7 @@ expect(response.code).to eq(200)
|
|
|
123
166
|
|
|
124
167
|
Nonnative ships Cucumber hooks (when loaded) that support these tags/strategies:
|
|
125
168
|
- `@startup`: start before scenario; stop after scenario
|
|
126
|
-
- `@manual`: stop after scenario
|
|
169
|
+
- `@manual`: stop after scenario; use `When I start the system` to start manually
|
|
127
170
|
- `@clear`: clears memoized configuration, logger, observability client, and pool before scenario
|
|
128
171
|
- `@reset`: resets proxies after scenario
|
|
129
172
|
|
|
@@ -140,14 +183,6 @@ The repo’s own Cucumber suite also uses taxonomy tags to classify coverage:
|
|
|
140
183
|
|
|
141
184
|
Requiring `nonnative` is enough; the Cucumber hooks and step definitions are installed lazily once Cucumber’s Ruby DSL is ready.
|
|
142
185
|
|
|
143
|
-
If you want "start once per test run", require:
|
|
144
|
-
|
|
145
|
-
```ruby
|
|
146
|
-
require 'nonnative/startup'
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
This calls `Nonnative.start` immediately and registers an `at_exit` stop.
|
|
150
|
-
|
|
151
186
|
### ⚙️ Processes
|
|
152
187
|
|
|
153
188
|
A process is some sort of command that you would run locally.
|
|
@@ -9,7 +9,7 @@ module Nonnative
|
|
|
9
9
|
# @return [Integer] process HTTP readiness port
|
|
10
10
|
attr_accessor :port
|
|
11
11
|
|
|
12
|
-
# @return [String] HTTP readiness path
|
|
12
|
+
# @return [String] path-only HTTP readiness path
|
|
13
13
|
attr_accessor :path
|
|
14
14
|
|
|
15
15
|
# @param value [Hash, #to_h] readiness attributes
|
|
@@ -30,6 +30,15 @@ module Nonnative
|
|
|
30
30
|
def validate!
|
|
31
31
|
raise ArgumentError, "Process readiness requires 'port'" if port.nil?
|
|
32
32
|
raise ArgumentError, "Process readiness requires 'path'" if path.nil?
|
|
33
|
+
raise ArgumentError, 'Process readiness path must be path-only' unless path_only?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def path_only?
|
|
37
|
+
uri = URI.parse(path.to_s)
|
|
38
|
+
|
|
39
|
+
uri.scheme.nil? && uri.host.nil?
|
|
40
|
+
rescue URI::InvalidURIError
|
|
41
|
+
false
|
|
33
42
|
end
|
|
34
43
|
end
|
|
35
44
|
end
|
data/lib/nonnative/cucumber.rb
CHANGED
|
@@ -43,10 +43,11 @@ module Nonnative
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def install_hooks
|
|
46
|
+
# Register @clear before startup hooks so combined tags reset stale state before creating a pool.
|
|
47
|
+
Before('@clear') { Nonnative.clear }
|
|
46
48
|
Before('@startup') { Nonnative.start }
|
|
47
49
|
After('@startup') { Nonnative.stop }
|
|
48
50
|
After('@manual') { Nonnative.stop }
|
|
49
|
-
Before('@clear') { Nonnative.clear }
|
|
50
51
|
After('@reset') { Nonnative.reset }
|
|
51
52
|
end
|
|
52
53
|
end
|
data/lib/nonnative/http_probe.rb
CHANGED
data/lib/nonnative/no_proxy.rb
CHANGED
|
@@ -4,8 +4,8 @@ module Nonnative
|
|
|
4
4
|
# No-op proxy implementation.
|
|
5
5
|
#
|
|
6
6
|
# This is the default proxy when `service.proxy.kind` is `"none"`.
|
|
7
|
-
# It does not bind/listen or alter traffic; it simply exposes the
|
|
8
|
-
# `host` and
|
|
7
|
+
# It does not bind/listen or alter traffic; it simply exposes the service configuration's
|
|
8
|
+
# client-facing `host` and `port`.
|
|
9
9
|
#
|
|
10
10
|
# Services can always call `start`, `stop`, and `reset` safely on this proxy.
|
|
11
11
|
#
|
|
@@ -41,7 +41,7 @@ module Nonnative
|
|
|
41
41
|
|
|
42
42
|
# Returns the host clients should connect to.
|
|
43
43
|
#
|
|
44
|
-
# For {NoProxy}, this is the
|
|
44
|
+
# For {NoProxy}, this is the service configuration's client-facing `host`.
|
|
45
45
|
#
|
|
46
46
|
# @return [String]
|
|
47
47
|
def host
|
|
@@ -50,7 +50,7 @@ module Nonnative
|
|
|
50
50
|
|
|
51
51
|
# Returns the port clients should connect to.
|
|
52
52
|
#
|
|
53
|
-
# For {NoProxy}, this is the
|
|
53
|
+
# For {NoProxy}, this is the service configuration's client-facing `port`.
|
|
54
54
|
#
|
|
55
55
|
# @return [Integer]
|
|
56
56
|
def port
|
data/lib/nonnative/startup.rb
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Starts the configured Nonnative pool immediately and registers an `at_exit` stop hook.
|
|
4
|
+
#
|
|
5
|
+
# Configure Nonnative before requiring this file; it is intended for suites that keep one
|
|
6
|
+
# Nonnative lifecycle open for the whole Ruby process.
|
|
7
|
+
|
|
3
8
|
at_exit do
|
|
4
9
|
Nonnative.stop
|
|
5
10
|
end
|
data/lib/nonnative/version.rb
CHANGED
data/lib/nonnative.rb
CHANGED
|
@@ -48,6 +48,7 @@ require 'yaml'
|
|
|
48
48
|
require 'open3'
|
|
49
49
|
require 'securerandom'
|
|
50
50
|
require 'shellwords'
|
|
51
|
+
require 'uri'
|
|
51
52
|
|
|
52
53
|
require 'grpc'
|
|
53
54
|
require 'sinatra'
|
|
@@ -204,8 +205,12 @@ module Nonnative
|
|
|
204
205
|
|
|
205
206
|
# Resolves a proxy implementation for a configured kind.
|
|
206
207
|
#
|
|
208
|
+
# `nil` and `"none"` resolve to {Nonnative::NoProxy}; any other kind must be registered in
|
|
209
|
+
# {Nonnative.proxies}.
|
|
210
|
+
#
|
|
207
211
|
# @param kind [String] proxy kind name (for example `"fault_injection"`)
|
|
208
212
|
# @return [Class] a subclass of {Nonnative::Proxy}
|
|
213
|
+
# @raise [ArgumentError] if the kind is not `"none"` and has not been registered
|
|
209
214
|
def proxy(kind)
|
|
210
215
|
kind.nil? || kind == 'none' ? NoProxy : proxies.fetch(kind) { raise ArgumentError, "Unsupported proxy kind '#{kind}'" }
|
|
211
216
|
end
|
data/nonnative.gemspec
CHANGED
|
@@ -11,8 +11,8 @@ Gem::Specification.new do |spec|
|
|
|
11
11
|
spec.authors = ['Alejandro Falkowski']
|
|
12
12
|
spec.email = ['alexrfalkowski@gmail.com']
|
|
13
13
|
|
|
14
|
-
spec.summary = '
|
|
15
|
-
spec.description =
|
|
14
|
+
spec.summary = 'Ruby-first end-to-end harness for testing systems implemented in other languages'
|
|
15
|
+
spec.description = 'Starts OS processes, in-process Ruby servers, and proxy-only services with TCP readiness checks and fault-injection proxies.'
|
|
16
16
|
spec.homepage = 'https://github.com/alexfalkowski/nonnative'
|
|
17
17
|
spec.license = 'MIT'
|
|
18
18
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nonnative
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alejandro Falkowski
|
|
@@ -263,7 +263,8 @@ dependencies:
|
|
|
263
263
|
- - "<"
|
|
264
264
|
- !ruby/object:Gem::Version
|
|
265
265
|
version: '5'
|
|
266
|
-
description:
|
|
266
|
+
description: Starts OS processes, in-process Ruby servers, and proxy-only services
|
|
267
|
+
with TCP readiness checks and fault-injection proxies.
|
|
267
268
|
email:
|
|
268
269
|
- alexrfalkowski@gmail.com
|
|
269
270
|
executables: []
|
|
@@ -351,5 +352,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
351
352
|
requirements: []
|
|
352
353
|
rubygems_version: 4.0.11
|
|
353
354
|
specification_version: 4
|
|
354
|
-
summary:
|
|
355
|
+
summary: Ruby-first end-to-end harness for testing systems implemented in other languages
|
|
355
356
|
test_files: []
|