nonnative 2.1.0 → 2.8.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: b7370ea5a582e82e738d71cbffc4a3ad847e8050165b02d33f1c18301212ace2
4
+ data.tar.gz: d3c139dd5cb598c013196f8362b38929783910e38fd4c45227e0093e28626eb8
5
5
  SHA512:
6
- metadata.gz: 4de8fc01b094bd20f45fae35b89b8d44367672cce238e03f28155f82dc661ba973293c02c3b7e47c1ff57621f7b0751f6c8ba1a67fe7eeab909505264521576b
7
- data.tar.gz: 384b6bfe7d122e6ae44b8902655091e4967b8a04c9ecf15a35316250ee474918a30402bbd725a81c6252bfa1b16864354ffd8bfc1668c148844ad358f82a5925
6
+ metadata.gz: 171e964df36ea5434a138fa0f01bfede21b7ad4b7708246b395e22eb3b373c9dda61299d72a663a759cd200572432d4ee7787f50de224808fd8a01c32315aa4e
7
+ data.tar.gz: 780c202b553579a078bdbcc0370d3d8641ea2c7a6268c7ab53182db970f1a299b8853fa8cf5ed6fd59ccd15bb46d63826c2adc5ef69bb010b661e4aba10a6971
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,6 +24,7 @@ jobs:
24
24
  paths:
25
25
  - vendor
26
26
  - run: make lint
27
+ - run: make sec
27
28
  - run: make features
28
29
  - store_test_results:
29
30
  path: test/reports
@@ -33,7 +34,7 @@ jobs:
33
34
  resource_class: arm.large
34
35
  sync:
35
36
  docker:
36
- - image: alexfalkowski/release:7.0
37
+ - image: alexfalkowski/release:7.5
37
38
  working_directory: ~/nonnative
38
39
  steps:
39
40
  - checkout:
@@ -44,7 +45,7 @@ jobs:
44
45
  resource_class: arm.large
45
46
  version:
46
47
  docker:
47
- - image: alexfalkowski/release:7.0
48
+ - image: alexfalkowski/release:7.5
48
49
  working_directory: ~/nonnative
49
50
  steps:
50
51
  - checkout:
@@ -56,7 +57,7 @@ jobs:
56
57
  resource_class: arm.large
57
58
  wait-all:
58
59
  docker:
59
- - image: alexfalkowski/ruby:2.0
60
+ - image: alexfalkowski/ruby:2.4
60
61
  steps:
61
62
  - run: echo "all applicable jobs finished"
62
63
  resource_class: arm.large
data/AGENTS.md CHANGED
@@ -1,248 +1,132 @@
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
+ Supported tags:
61
63
 
62
- ```sh
63
- make lint
64
- ```
64
+ - `@startup`: start before scenario, stop after scenario
65
+ - `@manual`: scenario starts manually, stop after scenario
66
+ - `@clear`: call `Nonnative.clear` before scenario
67
+ - `@reset`: reset proxies after scenario
65
68
 
66
- Runs RuboCop:
69
+ `Nonnative.clear` now clears:
67
70
 
68
- - `bundler exec rubocop` (`bin/build/make/ruby.mak:4-5`)
69
- - Config: `.rubocop.yml` (TargetRubyVersion 3.4; max line length 150)
71
+ - configuration
72
+ - logger
73
+ - observability client
74
+ - pool
70
75
 
71
- Auto-fix:
76
+ `require 'nonnative'` still loads the Cucumber integration, but hook/step registration is lazy, so plain `require 'nonnative'` is safe outside a booted Cucumber runtime.
72
77
 
73
- ```sh
74
- make fix-lint
75
- # or
76
- make format
77
- ```
78
+ For “start once per test run”, use `require 'nonnative/startup'`.
78
79
 
79
- ### Run acceptance tests (Cucumber)
80
+ ## Proxy wiring
80
81
 
81
- ```sh
82
- make features
83
- ```
82
+ This is the easiest thing to get wrong.
84
83
 
85
- This calls `bin/quality/ruby/feature`, which runs:
84
+ - Runner `host` / `port` are the client-facing endpoint and the values used by readiness/shutdown checks
85
+ - For `fault_injection`, nested `proxy.host` / `proxy.port` are the upstream target behind the proxy
86
+ - Clients should connect to the runner `host` / `port` when a proxy is enabled
86
87
 
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`
88
+ Available proxy kinds:
91
89
 
92
- Run only benchmarks:
90
+ - `none`
91
+ - `fault_injection`
93
92
 
94
- ```sh
95
- make benchmarks
96
- ```
93
+ Fault injection states:
97
94
 
98
- ### Coverage
95
+ - `none`
96
+ - `close_all`
97
+ - `delay`
98
+ - `invalid_data`
99
99
 
100
- Cucumber loads SimpleCov via `features/support/env.rb` and writes coverage output under `test/reports/`.
100
+ ## Config gotchas
101
101
 
102
- Codecov config exists in `.codecov.yml` and CI uploads coverage in `.circleci/config.yml`.
102
+ - Services must be declared under `services:` in YAML, not `processes:`
103
+ - There is no top-level `config.wait`; `wait` is per runner
104
+ - Service configs use `config.service do |s| ... end`, so use `s.host` / `s.port`
105
+ - Proxy examples need both sides of the split:
106
+ - runner `host` / `port` = proxy endpoint
107
+ - nested `proxy.host` / `proxy.port` = upstream target
103
108
 
104
- Local upload target:
109
+ ## Test fixtures worth knowing
105
110
 
106
- ```sh
107
- make codecov-upload
108
- ```
111
+ - Local process fixture: `features/support/bin/start`
112
+ - HTTP fixtures: `features/support/http_server.rb`, `features/support/http_proxy_server.rb`
113
+ - TCP fixture: `features/support/tcp_server.rb`
114
+ - gRPC fixtures: `features/support/grpc_server.rb`, plus generated stubs under `test/grpc/`
109
115
 
110
- ### Clean deps / reports
116
+ ## Important limitations / gotchas
111
117
 
112
- ```sh
113
- make clean-dep
114
- make clean-reports
115
- ```
118
+ - Ruby version is constrained by `nonnative.gemspec` to `>= 3.4.0` and `< 4.0.0`
119
+ - The `grpc` Ruby library uses a global logger; per-server gRPC loggers are not really supported
120
+ - `make` depends on the `bin/` submodule being present
121
+ - Local Ruby/Bundler mismatches can break native extensions on macOS
122
+ - Coverage output and Cucumber reports are written under `test/reports`
123
+ - Port checks can be flaky if tests reuse ports unexpectedly
116
124
 
117
- ## Testing patterns and hooks
118
-
119
- ### Cucumber hooks and tags
120
-
121
- Cucumber integration lives in `lib/nonnative/cucumber.rb`:
122
-
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.
127
-
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
125
+ ## Where to look first
243
126
 
244
127
  - Lifecycle orchestration: `lib/nonnative.rb`, `lib/nonnative/pool.rb`
245
128
  - Readiness / timeouts: `lib/nonnative/port.rb`, `lib/nonnative/timeout.rb`
246
- - Process management: `lib/nonnative/process.rb`
129
+ - Process lifecycle: `lib/nonnative/process.rb`
247
130
  - Proxies / fault injection: `lib/nonnative/fault_injection_proxy.rb`, `lib/nonnative/socket_pair_factory.rb`
248
131
  - Cucumber integration: `lib/nonnative/cucumber.rb`, `lib/nonnative/startup.rb`, `features/support/env.rb`
132
+ - 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.8.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,21 @@ 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
+ Requiring `nonnative` is enough; the Cucumber hooks and step definitions are installed lazily once Cucumber’s Ruby DSL is ready.
68
+
65
69
  If you want “start once per test run”, require:
66
70
 
67
71
  ```ruby
@@ -516,9 +520,11 @@ We allow different proxies to be configured. These proxies can be used to simula
516
520
  - `none` (this is the default)
517
521
  - `fault_injection`
518
522
 
523
+ 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.
524
+
519
525
  ##### Proxies Processes
520
526
 
521
- Setup it up programmatically:
527
+ Add this to an existing process configuration:
522
528
 
523
529
  ```ruby
524
530
  require 'nonnative'
@@ -543,7 +549,7 @@ Nonnative.configure do |config|
543
549
  end
544
550
  ```
545
551
 
546
- Setup it up through configuration:
552
+ YAML fragment:
547
553
 
548
554
  ```yaml
549
555
  version: "1.0"
@@ -563,7 +569,7 @@ processes:
563
569
 
564
570
  ##### Proxies Servers
565
571
 
566
- Setup it up programmatically:
572
+ Add this to an existing server configuration:
567
573
 
568
574
  ```ruby
569
575
  require 'nonnative'
@@ -588,7 +594,7 @@ Nonnative.configure do |config|
588
594
  end
589
595
  ```
590
596
 
591
- Setup it up through configuration:
597
+ YAML fragment:
592
598
 
593
599
  ```yaml
594
600
  version: "1.0"
@@ -608,7 +614,7 @@ servers:
608
614
 
609
615
  ##### Proxies Services
610
616
 
611
- Set it up programmatically:
617
+ Add this to an existing service configuration:
612
618
 
613
619
  ```ruby
614
620
  require 'nonnative'
@@ -622,12 +628,12 @@ Nonnative.configure do |config|
622
628
  config.service do |s|
623
629
  s.name = 'redis'
624
630
  s.host = '127.0.0.1'
625
- s.port = 6379
631
+ s.port = 16_379
626
632
 
627
633
  s.proxy = {
628
634
  kind: 'fault_injection',
629
635
  host: '127.0.0.1',
630
- port: 20_000,
636
+ port: 6379,
631
637
  log: 'proxy_server.log',
632
638
  wait: 1,
633
639
  options: {
@@ -638,19 +644,22 @@ Nonnative.configure do |config|
638
644
  end
639
645
  ```
640
646
 
641
- Setup it up through configuration:
647
+ YAML fragment:
642
648
 
643
649
  ```yaml
644
650
  version: "1.0"
645
651
  name: test
646
652
  url: http://localhost:4567
647
653
  log: nonnative.log
648
- wait: 1
649
654
  services:
650
655
  -
656
+ name: redis
657
+ host: 127.0.0.1
658
+ port: 16379
651
659
  proxy:
652
660
  kind: fault_injection
653
- port: 20000
661
+ host: 127.0.0.1
662
+ port: 6379
654
663
  log: proxy_server.log
655
664
  wait: 1
656
665
  options:
@@ -124,14 +124,10 @@ module Nonnative
124
124
  processes = cfg.processes || []
125
125
  processes.each do |fd|
126
126
  process do |d|
127
- d.name = fd.name
128
127
  d.command = command(fd)
129
- d.timeout = fd.timeout
130
- d.wait = fd.wait if fd.wait
131
- d.port = fd.port
132
- d.log = fd.log
133
128
  d.signal = fd.signal
134
129
  d.environment = fd.environment
130
+ runner_attributes(d, fd)
135
131
 
136
132
  proxy d, fd.proxy
137
133
  end
@@ -154,12 +150,8 @@ module Nonnative
154
150
  servers = cfg.servers || []
155
151
  servers.each do |fd|
156
152
  server do |s|
157
- s.name = fd.name
158
153
  s.klass = Object.const_get(fd.class)
159
- s.timeout = fd.timeout
160
- s.wait = fd.wait if fd.wait
161
- s.port = fd.port
162
- s.log = fd.log
154
+ runner_attributes(s, fd)
163
155
 
164
156
  proxy s, fd.proxy
165
157
  end
@@ -179,6 +171,15 @@ module Nonnative
179
171
  end
180
172
  end
181
173
 
174
+ def runner_attributes(runner, loaded)
175
+ runner.name = loaded.name
176
+ runner.timeout = loaded.timeout
177
+ runner.wait = loaded.wait if loaded.wait
178
+ runner.host = loaded.host if loaded.host
179
+ runner.port = loaded.port
180
+ runner.log = loaded.log if loaded.respond_to?(:log)
181
+ end
182
+
182
183
  def proxy(runner, proxy)
183
184
  return unless proxy
184
185