nonnative 2.1.0 → 2.10.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: b47a9f615e36880cdb7d6c7c3de9b716813467b25dd60cff0d2b15662a14e81d
4
- data.tar.gz: 59e26bb9aca2094793348170e2f72eec55309619f00131b742728f03c1515e57
3
+ metadata.gz: 8220ca25997b624a13ebf5f3f6a046af6bf05ee7428b21b96454d7c23ad42bef
4
+ data.tar.gz: 5a1884b26d92f57b54631ef22a4c2d6b3f16690c81364353ecb3e2d941b39638
5
5
  SHA512:
6
- metadata.gz: 4de8fc01b094bd20f45fae35b89b8d44367672cce238e03f28155f82dc661ba973293c02c3b7e47c1ff57621f7b0751f6c8ba1a67fe7eeab909505264521576b
7
- data.tar.gz: 384b6bfe7d122e6ae44b8902655091e4967b8a04c9ecf15a35316250ee474918a30402bbd725a81c6252bfa1b16864354ffd8bfc1668c148844ad358f82a5925
6
+ metadata.gz: d026441a2ed85facab82a48a8967e246d6c717c00c5c0039fb434feb585fe35fb23fbfa06732f85ec5491d0febcdda056d1cf4264a014efe432b87dfc705275f
7
+ data.tar.gz: 2cc84560c80a27144d3176b3e019a6ab9c86e32c2215e774d97d5a58927c34dda006a3da8f3b5b356b19bc7e2e96fb863b2bc168c9f4ac3e7a91f7181f08c57d
data/.circleci/config.yml CHANGED
@@ -3,7 +3,7 @@ version: 2.1
3
3
  jobs:
4
4
  build:
5
5
  docker:
6
- - image: alexfalkowski/ruby:2.0
6
+ - image: alexfalkowski/ruby:2.4
7
7
  working_directory: ~/nonnative
8
8
  steps:
9
9
  - checkout:
@@ -24,7 +24,9 @@ jobs:
24
24
  paths:
25
25
  - vendor
26
26
  - run: make lint
27
- - run: make features
27
+ - run: make sec
28
+ - run: COVERAGE_NAME="Cucumber Features" make features
29
+ - run: COVERAGE_NAME="Cucumber Benchmarks" make benchmarks
28
30
  - store_test_results:
29
31
  path: test/reports
30
32
  - store_artifacts:
@@ -33,7 +35,7 @@ jobs:
33
35
  resource_class: arm.large
34
36
  sync:
35
37
  docker:
36
- - image: alexfalkowski/release:7.0
38
+ - image: alexfalkowski/release:7.5
37
39
  working_directory: ~/nonnative
38
40
  steps:
39
41
  - checkout:
@@ -44,7 +46,7 @@ jobs:
44
46
  resource_class: arm.large
45
47
  version:
46
48
  docker:
47
- - image: alexfalkowski/release:7.0
49
+ - image: alexfalkowski/release:7.5
48
50
  working_directory: ~/nonnative
49
51
  steps:
50
52
  - checkout:
@@ -56,7 +58,7 @@ jobs:
56
58
  resource_class: arm.large
57
59
  wait-all:
58
60
  docker:
59
- - image: alexfalkowski/ruby:2.0
61
+ - image: alexfalkowski/ruby:2.4
60
62
  steps:
61
63
  - run: echo "all applicable jobs finished"
62
64
  resource_class: arm.large
data/AGENTS.md CHANGED
@@ -1,248 +1,147 @@
1
1
  # AGENTS.md
2
2
 
3
- This repository is the **`nonnative` Ruby gem**. It provides a Ruby-first harness for end-to-end testing of services implemented in other languages by **starting processes/servers/services**, waiting for readiness (port checks), and optionally running **fault-injection proxies**.
3
+ This repo is the `nonnative` Ruby gem: a Ruby-first harness for end-to-end testing of systems implemented in other languages by starting processes/servers/services, waiting on TCP port readiness, and optionally putting fault-injection proxies in front of them.
4
4
 
5
- Everything below is based on the files currently in this repo (no assumptions).
5
+ ## Quick map
6
6
 
7
- ## Recent documentation updates (important for future sessions)
7
+ - Library code: `lib/nonnative/**/*.rb`
8
+ - Acceptance tests: `features/**/*.feature`, `features/support/**/*.rb`, `features/step_definitions/**/*.rb`
9
+ - Generated gRPC Ruby stubs for tests: `test/grpc/**/*`
10
+ - Test proto files: `test/nonnative/v1/*.proto`
11
+ - Build wiring: root `Makefile` includes `bin/build/make/*.mak`
8
12
 
9
- - **Public API RDoc pass started**:
10
- - Added/expanded RDoc for the module entry point (`Nonnative`) and core configuration/error types.
11
- - Goal: document *public APIs only* (gem consumers), not internal/private helpers.
12
- - **README accuracy pass started**:
13
- - Fixed incorrect examples around **services**:
14
- - Programmatic example incorrectly used `p.port` inside a `config.service do |s| ... end` block; corrected to `s.host`/`s.port`.
15
- - YAML example incorrectly used `processes:` for services; corrected to `services:`.
16
- - Removed/avoided implying non-existent config fields (e.g. there is no top-level `config.wait`; `wait` is per-runner).
13
+ ## Key repo dependency
17
14
 
18
- These changes were made to align docs/examples with the actual runtime/config objects under `lib/nonnative/**/*.rb`.
15
+ This repo depends on the `bin/` git submodule.
19
16
 
20
- ## Quick orientation
17
+ - `.gitmodules` points to `git@github.com:alexfalkowski/bin.git`
18
+ - CI runs `git submodule sync && git submodule update --init`
19
+ - If `bin/` is missing or you do not have SSH access, `make` targets will fail
21
20
 
22
- - **Library code**: `lib/nonnative/**/*.rb`
23
- - **Acceptance tests**: `features/**/*.feature` + `features/support/**/*.rb` + `features/step_definitions/**/*.rb` (Cucumber)
24
- - **Generated gRPC Ruby stubs for tests**: `test/grpc/**/*` (excluded from RuboCop)
25
- - **Proto definitions for test fixtures**: `test/nonnative/v1/*.proto`
26
- - **Build system**: `Makefile` includes make fragments from the `bin/` submodule (`bin/build/make/*.mak`).
21
+ ## Core commands
27
22
 
28
- ## Important repo dependency: `bin/` submodule
23
+ - Install deps: `make dep`
24
+ - Lint: `make lint`
25
+ - Run features: `make features`
26
+ - Run benchmarks only: `make benchmarks`
27
+ - Clean deps: `make clean-dep`
28
+ - Clean reports: `make clean-reports`
29
29
 
30
- This repo uses a git submodule at `bin/`:
30
+ ## Runtime model
31
31
 
32
- - `.gitmodules` points to `git@github.com:alexfalkowski/bin.git`.
33
- - CI runs `git submodule sync && git submodule update --init` before running `make` targets (`.circleci/config.yml`).
32
+ Public entry point is `lib/nonnative.rb`.
34
33
 
35
- If you don’t have SSH access to that repo, `make` targets that include `bin/build/make/*.mak` will fail.
34
+ Main module API:
36
35
 
37
- ### Submodule commands
36
+ - `configure`
37
+ - `start`
38
+ - `stop`
39
+ - `clear`
40
+ - `reset`
41
+ - `pool`
38
42
 
39
- ```sh
40
- git submodule sync
41
- git submodule update --init
42
- ```
43
+ Configuration lives in `Nonnative::Configuration` and is built either:
43
44
 
44
- ## Essential commands (from Makefiles)
45
+ - programmatically with `config.process`, `config.server`, `config.service`
46
+ - from YAML with `config.load_file(...)`
45
47
 
46
- ### Ruby version
48
+ Runtime runners:
47
49
 
48
- - `nonnative.gemspec` requires Ruby `>= 3.4.0` and `< 4.0.0`.
50
+ - `Nonnative::Process`: manages an OS process
51
+ - `Nonnative::Server`: manages an in-process Ruby server thread
52
+ - `Nonnative::Service`: manages only proxy lifecycle for an externally managed dependency
49
53
 
50
- ### Install deps
54
+ `Nonnative::Pool` starts services first, then servers/processes, and stops in the reverse direction.
51
55
 
52
- Ruby deps are managed by Bundler and installed into `vendor/bundle`:
56
+ Readiness and shutdown checks are TCP-only via `Nonnative::Port#open?` and `#closed?`.
53
57
 
54
- ```sh
55
- make dep
56
- ```
58
+ ## Cucumber integration
57
59
 
58
- Implementation lives in `bin/build/make/ruby.mak` (included by root `Makefile`).
60
+ Cucumber integration lives in `lib/nonnative/cucumber.rb`.
59
61
 
60
- ### Lint
62
+ Treat `lib/nonnative/cucumber.rb` as a public compatibility surface for library consumers.
63
+ Existing hooks and step text should not be removed or renamed unless the user explicitly wants a breaking change.
61
64
 
62
- ```sh
63
- make lint
64
- ```
65
+ Supported tags:
65
66
 
66
- Runs RuboCop:
67
+ - `@startup`: start before scenario, stop after scenario
68
+ - `@manual`: scenario starts manually, stop after scenario
69
+ - `@clear`: call `Nonnative.clear` before scenario
70
+ - `@reset`: reset proxies after scenario
67
71
 
68
- - `bundler exec rubocop` (`bin/build/make/ruby.mak:4-5`)
69
- - Config: `.rubocop.yml` (TargetRubyVersion 3.4; max line length 150)
72
+ Repo-owned feature files also use suite taxonomy tags:
70
73
 
71
- Auto-fix:
74
+ - `@acceptance`: end-to-end runner and client flows
75
+ - `@contract`: lower-level lifecycle / command coverage
76
+ - `@proxy`: proxy-specific coverage
77
+ - `@config`: scenarios or example sets that load YAML/configuration
78
+ - `@service`: coverage centered on external services
79
+ - `@benchmark`: benchmark-only scenarios
80
+ - `@slow`: slower-running scenarios, currently benchmarks
72
81
 
73
- ```sh
74
- make fix-lint
75
- # or
76
- make format
77
- ```
82
+ `make features` excludes `@benchmark`; `make benchmarks` runs only `@benchmark`.
78
83
 
79
- ### Run acceptance tests (Cucumber)
84
+ `Nonnative.clear` now clears:
80
85
 
81
- ```sh
82
- make features
83
- ```
86
+ - configuration
87
+ - logger
88
+ - observability client
89
+ - pool
84
90
 
85
- This calls `bin/quality/ruby/feature`, which runs:
91
+ `require 'nonnative'` still loads the Cucumber integration, but hook/step registration is lazy, so plain `require 'nonnative'` is safe outside a booted Cucumber runtime.
86
92
 
87
- - `bundler exec cucumber --profile report ... --tags "not @benchmark" ...`
88
- - Cucumber profile `report` is defined in `.config/cucumber.yml` and writes:
89
- - JUnit XML to `test/reports`
90
- - HTML report to `test/reports/index.html`
93
+ For “start once per test run”, use `require 'nonnative/startup'`.
91
94
 
92
- Run only benchmarks:
95
+ ## Proxy wiring
93
96
 
94
- ```sh
95
- make benchmarks
96
- ```
97
+ This is the easiest thing to get wrong.
97
98
 
98
- ### Coverage
99
+ - Runner `host` / `port` are the client-facing endpoint and the values used by readiness/shutdown checks
100
+ - For `fault_injection`, nested `proxy.host` / `proxy.port` are the upstream target behind the proxy
101
+ - Clients should connect to the runner `host` / `port` when a proxy is enabled
99
102
 
100
- Cucumber loads SimpleCov via `features/support/env.rb` and writes coverage output under `test/reports/`.
103
+ Available proxy kinds:
101
104
 
102
- Codecov config exists in `.codecov.yml` and CI uploads coverage in `.circleci/config.yml`.
105
+ - `none`
106
+ - `fault_injection`
103
107
 
104
- Local upload target:
108
+ Fault injection states:
105
109
 
106
- ```sh
107
- make codecov-upload
108
- ```
110
+ - `none`
111
+ - `close_all`
112
+ - `delay`
113
+ - `invalid_data`
109
114
 
110
- ### Clean deps / reports
115
+ ## Config gotchas
111
116
 
112
- ```sh
113
- make clean-dep
114
- make clean-reports
115
- ```
117
+ - Services must be declared under `services:` in YAML, not `processes:`
118
+ - There is no top-level `config.wait`; `wait` is per runner
119
+ - Service configs use `config.service do |s| ... end`, so use `s.host` / `s.port`
120
+ - Proxy examples need both sides of the split:
121
+ - runner `host` / `port` = proxy endpoint
122
+ - nested `proxy.host` / `proxy.port` = upstream target
116
123
 
117
- ## Testing patterns and hooks
124
+ ## Test fixtures worth knowing
118
125
 
119
- ### Cucumber hooks and tags
126
+ - Local process fixture: `features/support/bin/start`
127
+ - HTTP fixtures: `features/support/http_server.rb`, `features/support/http_proxy_server.rb`
128
+ - TCP fixture: `features/support/tcp_server.rb`
129
+ - gRPC fixtures: `features/support/grpc_server.rb`, plus generated stubs under `test/grpc/`
120
130
 
121
- Cucumber integration lives in `lib/nonnative/cucumber.rb`:
131
+ ## Important limitations / gotchas
122
132
 
123
- - `@startup`: starts and stops Nonnative around each scenario.
124
- - `@manual`: only stops after scenario (start is expected to be triggered manually in steps).
125
- - `@clear`: calls `Nonnative.clear` before scenario.
126
- - `@reset`: resets proxies after scenario.
133
+ - Ruby version is constrained by `nonnative.gemspec` to `>= 4.0.0` and `< 5.0.0`
134
+ - The `grpc` Ruby library uses a global logger; per-server gRPC loggers are not really supported
135
+ - `make` depends on the `bin/` submodule being present
136
+ - Local Ruby/Bundler mismatches can break native extensions on macOS
137
+ - Coverage output and Cucumber reports are written under `test/reports`
138
+ - Port checks can be flaky if tests reuse ports unexpectedly
127
139
 
128
- The “start once per test run” strategy is implemented by requiring `nonnative/startup`:
129
-
130
- - `lib/nonnative/startup.rb` calls `Nonnative.start` and registers an `at_exit` stop.
131
-
132
- ### README gotchas that matter in practice
133
-
134
- - **Service vs process YAML keys**:
135
- - Services must be declared under `services:` in YAML (not `processes:`). Code reads `cfg.services` and maps them to `Nonnative::ConfigurationService`.
136
- - **No top-level `wait`**:
137
- - `wait` is defined on runner configurations (`ConfigurationRunner#wait`) and is per process/server/service.
138
- - **Proxy wiring is easy to misunderstand**:
139
- - When a proxy kind like `fault_injection` is enabled, the proxy binds to `service.proxy.host`/`service.proxy.port`.
140
- - Readiness checks and traffic should typically target the **proxy host/port**, not the underlying service host/port.
141
-
142
- ### Feature support code
143
-
144
- `features/support/` contains small servers/clients used by cucumber scenarios (HTTP/TCP/gRPC). Example:
145
-
146
- - `features/support/http_server.rb` defines a Sinatra app for `/hello` and health endpoints.
147
-
148
- ### Process fixture
149
-
150
- Scenarios start a local process via `features/support/bin/start` (referenced in step definitions and YAML configs like `features/configs/processes.yml`).
151
-
152
- ## Library architecture (high level)
153
-
154
- ### Entry point and global state
155
-
156
- - `lib/nonnative.rb` defines the `Nonnative` module singleton API:
157
- - `configure { |config| ... }`
158
- - `start` / `stop`
159
- - `clear`, `reset`
160
- - `pool` is created on `start` (`Nonnative::Pool.new(configuration)`).
161
-
162
- ### Configuration objects
163
-
164
- - `Nonnative::Configuration` (`lib/nonnative/configuration.rb`) holds arrays of:
165
- - `processes` (`Nonnative::ConfigurationProcess`)
166
- - `servers` (`Nonnative::ConfigurationServer`)
167
- - `services` (`Nonnative::ConfigurationService`)
168
-
169
- It can be populated either:
170
-
171
- - programmatically via `config.process { ... }`, `config.server { ... }`, `config.service { ... }`
172
- - via YAML using `config.load_file(path)` which calls `Config.load_files(...)` (the `config` gem)
173
-
174
- Proxies are configured via `ConfigurationProxy` (`lib/nonnative/configuration_proxy.rb`) and attached to runners as a hash.
175
-
176
- ### Runners and lifecycle
177
-
178
- There are three runtime “runner” types, all subclassing `Runner` (`lib/nonnative/runner.rb`):
179
-
180
- - `Nonnative::Process` (`lib/nonnative/process.rb`): `spawn(...)` + `Process.kill` / `waitpid2`.
181
- - `Nonnative::Server` (`lib/nonnative/server.rb`): `Thread.new { perform_start }` + `perform_stop`.
182
- - `Nonnative::Service` (`lib/nonnative/service.rb`): no process management; proxy only.
183
-
184
- `Nonnative::Pool` (`lib/nonnative/pool.rb`) owns collections of runners and orchestrates start/stop:
185
-
186
- - starts **services first**, then servers/processes
187
- - stops **processes/servers first**, then services
188
- - readiness is determined via `Nonnative::Port#open?` / `#closed?` (`lib/nonnative/port.rb`) which repeatedly tries `TCPSocket.new(host, port)` inside a timeout.
189
-
190
- ### Proxies
191
-
192
- Proxy selection is keyed by `kind`:
193
-
194
- - mapping: `Nonnative.proxies` in `lib/nonnative.rb`
195
- - default proxy config values: `ConfigurationProxy#initialize` sets kind `none`, host `0.0.0.0`, wait `0.1`, etc.
196
-
197
- Implemented proxies:
198
-
199
- - `Nonnative::NoProxy` (`lib/nonnative/no_proxy.rb`)
200
- - `Nonnative::FaultInjectionProxy` (`lib/nonnative/fault_injection_proxy.rb`)
201
- - states: `:none`, `:close_all`, `:delay`, `:invalid_data`
202
- - delegates behavior to socket-pair classes via `SocketPairFactory` (`lib/nonnative/socket_pair_factory.rb`).
203
-
204
- ### Go executable helper
205
-
206
- There is a helper for building a Go *test binary* command line with optional profiling/trace/coverage flags:
207
-
208
- - `Nonnative.go_executable` in `lib/nonnative.rb`
209
- - `Nonnative::GoCommand` in `lib/nonnative/go_command.rb`
210
-
211
- This is used when YAML process config has a `go:` section (see `Configuration#command` in `lib/nonnative/configuration.rb`).
212
-
213
- ## Style and conventions
214
-
215
- - Ruby style is enforced by RuboCop (`.rubocop.yml`):
216
- - Target Ruby 3.4
217
- - Line length 150
218
- - `Style/Documentation` disabled
219
- - `.editorconfig`:
220
- - `indent_size = 2` for most files
221
- - **Makefiles use tabs**
222
- - Many Ruby files use `# frozen_string_literal: true`.
223
-
224
- ## CI notes
225
-
226
- CircleCI runs (see `.circleci/config.yml`):
227
-
228
- - `make source-key` (defined in `bin/build/make/git.mak`) to generate `.source-key` used for caching
229
- - `make dep`, `make clean-dep`
230
- - `make lint`, `make features`
231
- - uploads `test/reports` artifacts
232
-
233
- ## Common gotchas
234
-
235
- - **Submodule required**: root `Makefile` only includes `bin/...` make fragments; without `bin/` present/updated, `make` won’t work.
236
- - **SSH-only submodule URL**: `.gitmodules` uses `git@github.com:...`; CI or local environments without SSH keys will fail to init the submodule.
237
- - **Local Ruby/Bundler mismatch can break native extensions**: on macOS, `make lint`/`bundle exec ...` may fail if the Ruby used to install gems differs from the Ruby used to run them (example error seen: `prism.bundle` missing `libruby.3.4.dylib`).
238
- - **Requiring `nonnative` loads Cucumber DSL**: `lib/nonnative.rb` requires `lib/nonnative/cucumber.rb`, which calls `World(...)`. Outside a Cucumber runtime this can raise (example error seen: `Cucumber::Glue::Dsl.build_rb_world_factory`).
239
- - **Reports directory**: Cucumber report profile writes into `test/reports/` and the repo keeps a `test/reports/.keep` file.
240
- - **Port checks can be flaky if ports are reused**: readiness is purely `TCPSocket`-based (`lib/nonnative/port.rb`), so ensure test fixtures bind expected ports.
241
-
242
- ## Where to look first when changing behavior
140
+ ## Where to look first
243
141
 
244
142
  - Lifecycle orchestration: `lib/nonnative.rb`, `lib/nonnative/pool.rb`
245
143
  - Readiness / timeouts: `lib/nonnative/port.rb`, `lib/nonnative/timeout.rb`
246
- - Process management: `lib/nonnative/process.rb`
144
+ - Process lifecycle: `lib/nonnative/process.rb`
247
145
  - Proxies / fault injection: `lib/nonnative/fault_injection_proxy.rb`, `lib/nonnative/socket_pair_factory.rb`
248
146
  - Cucumber integration: `lib/nonnative/cucumber.rb`, `lib/nonnative/startup.rb`, `features/support/env.rb`
147
+ - Config loading: `lib/nonnative/configuration.rb`, `lib/nonnative/configuration_runner.rb`, `lib/nonnative/configuration_proxy.rb`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nonnative (2.1.0)
4
+ nonnative (2.10.0)
5
5
  concurrent-ruby (>= 1, < 2)
6
6
  config (>= 5, < 6)
7
7
  cucumber (>= 7, < 11)
@@ -24,7 +24,7 @@ GEM
24
24
  benchmark-malloc (0.2.0)
25
25
  benchmark-perf (0.6.0)
26
26
  benchmark-trend (0.4.0)
27
- bigdecimal (4.0.1)
27
+ bigdecimal (4.1.1)
28
28
  builder (3.3.0)
29
29
  concurrent-ruby (1.3.6)
30
30
  config (5.6.1)
@@ -47,7 +47,7 @@ GEM
47
47
  cucumber-gherkin (> 36, < 40)
48
48
  cucumber-messages (> 31, < 33)
49
49
  cucumber-tag-expressions (> 6, < 9)
50
- cucumber-cucumber-expressions (18.0.1)
50
+ cucumber-cucumber-expressions (18.1.0)
51
51
  bigdecimal
52
52
  cucumber-gherkin (39.0.0)
53
53
  cucumber-messages (>= 31, < 33)
@@ -59,29 +59,29 @@ GEM
59
59
  diff-lcs (1.6.2)
60
60
  docile (1.4.1)
61
61
  domain_name (0.6.20240107)
62
- ffi (1.17.3-x86_64-darwin)
63
- ffi (1.17.3-x86_64-linux-gnu)
62
+ ffi (1.17.4-x86_64-darwin)
63
+ ffi (1.17.4-x86_64-linux-gnu)
64
64
  get_process_mem (1.0.0)
65
65
  bigdecimal (>= 2.0)
66
66
  ffi (~> 1.0)
67
- google-protobuf (4.34.0-x86_64-darwin)
67
+ google-protobuf (4.34.1-x86_64-darwin)
68
68
  bigdecimal
69
69
  rake (~> 13.3)
70
- google-protobuf (4.34.0-x86_64-linux-gnu)
70
+ google-protobuf (4.34.1-x86_64-linux-gnu)
71
71
  bigdecimal
72
72
  rake (~> 13.3)
73
73
  googleapis-common-protos-types (1.22.0)
74
74
  google-protobuf (~> 4.26)
75
- grpc (1.78.1-x86_64-darwin)
75
+ grpc (1.80.0-x86_64-darwin)
76
76
  google-protobuf (>= 3.25, < 5.0)
77
77
  googleapis-common-protos-types (~> 1.0)
78
- grpc (1.78.1-x86_64-linux-gnu)
78
+ grpc (1.80.0-x86_64-linux-gnu)
79
79
  google-protobuf (>= 3.25, < 5.0)
80
80
  googleapis-common-protos-types (~> 1.0)
81
81
  http-accept (1.7.0)
82
- http-cookie (1.1.0)
82
+ http-cookie (1.1.4)
83
83
  domain_name (~> 0.5)
84
- json (2.19.2)
84
+ json (2.19.3)
85
85
  language_server-protocol (3.17.0.5)
86
86
  lint_roller (1.1.0)
87
87
  logger (1.7.0)
@@ -89,7 +89,7 @@ GEM
89
89
  mime-types (3.7.0)
90
90
  logger
91
91
  mime-types-data (~> 3.2025, >= 3.2025.0507)
92
- mime-types-data (3.2026.0303)
92
+ mime-types-data (3.2026.0407)
93
93
  mini_mime (1.1.5)
94
94
  multi_test (1.1.0)
95
95
  mustermann (3.0.4)
@@ -97,28 +97,29 @@ GEM
97
97
  netrc (0.11.0)
98
98
  nio4r (2.7.5)
99
99
  ostruct (0.6.3)
100
- parallel (1.27.0)
101
- parser (3.3.10.2)
100
+ parallel (1.28.0)
101
+ parser (3.3.11.1)
102
102
  ast (~> 2.4.1)
103
103
  racc
104
104
  prism (1.9.0)
105
105
  puma (7.2.0)
106
106
  nio4r (~> 2.0)
107
107
  racc (1.8.1)
108
- rack (3.2.5)
108
+ rack (3.2.6)
109
109
  rack-protection (4.2.1)
110
110
  base64 (>= 0.1.0)
111
111
  logger (>= 1.6.0)
112
112
  rack (>= 3.0.0, < 4)
113
- rack-session (2.1.1)
113
+ rack-session (2.1.2)
114
114
  base64 (>= 0.1.0)
115
115
  rack (>= 3.0.0)
116
116
  rainbow (3.1.1)
117
117
  rake (13.3.1)
118
- rbs (3.10.3)
118
+ rbs (4.0.2)
119
119
  logger
120
+ prism (>= 1.6.0)
120
121
  tsort
121
- regexp_parser (2.11.3)
122
+ regexp_parser (2.12.0)
122
123
  rest-client (2.1.0)
123
124
  http-accept (>= 1.7.0, < 2.0)
124
125
  http-cookie (>= 1.0.2, < 2.0)
@@ -160,7 +161,7 @@ GEM
160
161
  rubocop-ast (1.49.1)
161
162
  parser (>= 3.3.7.2)
162
163
  prism (~> 1.7)
163
- ruby-lsp (0.26.8)
164
+ ruby-lsp (0.26.9)
164
165
  language_server-protocol (~> 3.17.0)
165
166
  prism (>= 1.2, < 2.0)
166
167
  rbs (>= 3, < 5)
@@ -182,7 +183,7 @@ GEM
182
183
  rack-protection (= 4.2.1)
183
184
  rack-session (>= 2.0.0, < 3)
184
185
  tilt (~> 2.0)
185
- sys-uname (1.5.0)
186
+ sys-uname (1.5.1)
186
187
  ffi (~> 1.1)
187
188
  memoist3 (~> 1.0.0)
188
189
  tilt (2.7.0)
data/README.md CHANGED
@@ -51,17 +51,32 @@ High-level configuration fields:
51
51
  Runner fields (process/server/service):
52
52
  - `timeout`: max time (seconds) for readiness/shutdown port checks.
53
53
  - `wait`: small sleep (seconds) between lifecycle steps.
54
- - `host`/`port`: address used for port checks; when a proxy is enabled, reads happen via the proxy.
54
+ - `host`/`port`: client-facing address used for readiness/shutdown port checks. When a `fault_injection` proxy is enabled, this is the endpoint your tests/clients should hit.
55
55
  - `log`: per-runner log file (used by process output redirection or server implementations).
56
56
 
57
+ For `fault_injection`, the nested `proxy.host`/`proxy.port` describe the upstream target behind the proxy. In-process server implementations typically bind there via `proxy.host` / `proxy.port`.
58
+
57
59
  ### Lifecycle strategies (Cucumber integration)
58
60
 
59
61
  Nonnative ships Cucumber hooks (when loaded) that support these tags/strategies:
60
62
  - `@startup`: start before scenario; stop after scenario
61
63
  - `@manual`: stop after scenario (start is expected to be triggered manually in steps)
62
- - `@clear`: clears memoized configuration and pool before scenario
64
+ - `@clear`: clears memoized configuration, logger, observability client, and pool before scenario
63
65
  - `@reset`: resets proxies after scenario
64
66
 
67
+ The repo’s own Cucumber suite also uses taxonomy tags to classify coverage:
68
+ - `@acceptance`: end-to-end behavior across configured runners and clients
69
+ - `@contract`: lower-level contract and lifecycle behavior
70
+ - `@proxy`: proxy-specific behavior and failure injection
71
+ - `@config`: coverage that exercises YAML/config loading
72
+ - `@service`: scenarios centered on externally managed dependencies
73
+ - `@benchmark`: benchmark-only scenarios run by `make benchmarks`
74
+ - `@slow`: slower scenarios, currently used by benchmark coverage
75
+
76
+ `make features` excludes `@benchmark`, while `make benchmarks` runs only `@benchmark`.
77
+
78
+ Requiring `nonnative` is enough; the Cucumber hooks and step definitions are installed lazily once Cucumber’s Ruby DSL is ready.
79
+
65
80
  If you want “start once per test run”, require:
66
81
 
67
82
  ```ruby
@@ -516,9 +531,11 @@ We allow different proxies to be configured. These proxies can be used to simula
516
531
  - `none` (this is the default)
517
532
  - `fault_injection`
518
533
 
534
+ For `fault_injection`, keep the runner `host`/`port` as the client-facing endpoint and use nested `proxy.host`/`proxy.port` for the upstream target behind the proxy.
535
+
519
536
  ##### Proxies Processes
520
537
 
521
- Setup it up programmatically:
538
+ Add this to an existing process configuration:
522
539
 
523
540
  ```ruby
524
541
  require 'nonnative'
@@ -543,7 +560,7 @@ Nonnative.configure do |config|
543
560
  end
544
561
  ```
545
562
 
546
- Setup it up through configuration:
563
+ YAML fragment:
547
564
 
548
565
  ```yaml
549
566
  version: "1.0"
@@ -563,7 +580,7 @@ processes:
563
580
 
564
581
  ##### Proxies Servers
565
582
 
566
- Setup it up programmatically:
583
+ Add this to an existing server configuration:
567
584
 
568
585
  ```ruby
569
586
  require 'nonnative'
@@ -588,7 +605,7 @@ Nonnative.configure do |config|
588
605
  end
589
606
  ```
590
607
 
591
- Setup it up through configuration:
608
+ YAML fragment:
592
609
 
593
610
  ```yaml
594
611
  version: "1.0"
@@ -608,7 +625,7 @@ servers:
608
625
 
609
626
  ##### Proxies Services
610
627
 
611
- Set it up programmatically:
628
+ Add this to an existing service configuration:
612
629
 
613
630
  ```ruby
614
631
  require 'nonnative'
@@ -622,12 +639,12 @@ Nonnative.configure do |config|
622
639
  config.service do |s|
623
640
  s.name = 'redis'
624
641
  s.host = '127.0.0.1'
625
- s.port = 6379
642
+ s.port = 16_379
626
643
 
627
644
  s.proxy = {
628
645
  kind: 'fault_injection',
629
646
  host: '127.0.0.1',
630
- port: 20_000,
647
+ port: 6379,
631
648
  log: 'proxy_server.log',
632
649
  wait: 1,
633
650
  options: {
@@ -638,19 +655,22 @@ Nonnative.configure do |config|
638
655
  end
639
656
  ```
640
657
 
641
- Setup it up through configuration:
658
+ YAML fragment:
642
659
 
643
660
  ```yaml
644
661
  version: "1.0"
645
662
  name: test
646
663
  url: http://localhost:4567
647
664
  log: nonnative.log
648
- wait: 1
649
665
  services:
650
666
  -
667
+ name: redis
668
+ host: 127.0.0.1
669
+ port: 16379
651
670
  proxy:
652
671
  kind: fault_injection
653
- port: 20000
672
+ host: 127.0.0.1
673
+ port: 6379
654
674
  log: proxy_server.log
655
675
  wait: 1
656
676
  options: