nonnative 2.13.1 → 2.15.1
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/.circleci/config.yml +4 -4
- data/AGENTS.md +64 -111
- data/Gemfile.lock +2 -2
- data/README.md +18 -4
- data/lib/nonnative/configuration_proxy.rb +2 -2
- data/lib/nonnative/configuration_runner.rb +2 -2
- data/lib/nonnative/cucumber.rb +18 -3
- data/lib/nonnative/version.rb +1 -1
- data/lib/nonnative.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: df0fc1bbc0cd9de5368098691bb6c4b812029d70a3d8df236b587874b96e9baf
|
|
4
|
+
data.tar.gz: 431042c13689b0dec97b2064c130a1b104a167fafecda20f6e90aff2e9c22190
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5dd146af474ac19e1173b38701a75383dd5650e6a182b529c20d2290c44a037072025eee23cc0f6bd06326fc91690d6da83ff746be5cac443609703d5da59075
|
|
7
|
+
data.tar.gz: 7d7dcbebffa532f5dfe93b4c80ff563d4b0bd5c329a092fc69fcbe1930cd8dac1f191cc04a9ff2dd0de15447b3f446ea134bd9708993e20e7bac780c41122d99
|
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.
|
|
6
|
+
- image: alexfalkowski/ruby:2.15
|
|
7
7
|
working_directory: ~/nonnative
|
|
8
8
|
steps:
|
|
9
9
|
- checkout:
|
|
@@ -35,7 +35,7 @@ jobs:
|
|
|
35
35
|
resource_class: arm.large
|
|
36
36
|
sync:
|
|
37
37
|
docker:
|
|
38
|
-
- image: alexfalkowski/release:7.
|
|
38
|
+
- image: alexfalkowski/release:7.16
|
|
39
39
|
working_directory: ~/nonnative
|
|
40
40
|
steps:
|
|
41
41
|
- checkout:
|
|
@@ -46,7 +46,7 @@ jobs:
|
|
|
46
46
|
resource_class: arm.large
|
|
47
47
|
version:
|
|
48
48
|
docker:
|
|
49
|
-
- image: alexfalkowski/release:7.
|
|
49
|
+
- image: alexfalkowski/release:7.16
|
|
50
50
|
working_directory: ~/nonnative
|
|
51
51
|
steps:
|
|
52
52
|
- checkout:
|
|
@@ -58,7 +58,7 @@ jobs:
|
|
|
58
58
|
resource_class: arm.large
|
|
59
59
|
wait-all:
|
|
60
60
|
docker:
|
|
61
|
-
- image: alexfalkowski/ruby:2.
|
|
61
|
+
- image: alexfalkowski/ruby:2.15
|
|
62
62
|
steps:
|
|
63
63
|
- run: echo "all applicable jobs finished"
|
|
64
64
|
resource_class: arm.large
|
data/AGENTS.md
CHANGED
|
@@ -1,154 +1,107 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`nonnative` is a Ruby gem for end-to-end testing systems implemented in other
|
|
4
|
+
languages. It starts processes, in-process servers, and proxy-only services,
|
|
5
|
+
waits on TCP readiness/shutdown, and can place fault-injection proxies in front
|
|
6
|
+
of dependencies.
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
Use `./bin/skills/coding-standards` for shared coding, review, testing,
|
|
9
|
+
documentation, and PR conventions. This file only adds repo-specific context.
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
for cross-repository coding, review, testing, documentation, and PR
|
|
9
|
-
conventions. Treat this `AGENTS.md` as the repo-specific companion to that
|
|
10
|
-
skill.
|
|
11
|
+
## Map And Commands
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
- Generated gRPC Ruby stubs for tests: `test/grpc/**/*`
|
|
17
|
-
- Test proto files: `test/nonnative/v1/*.proto`
|
|
13
|
+
- Library: `lib/nonnative/**/*.rb`
|
|
14
|
+
- Cucumber features/support: `features/**/*.feature`, `features/support/**/*.rb`, `features/step_definitions/**/*.rb`
|
|
15
|
+
- Generated gRPC test stubs: `test/grpc/**/*`
|
|
16
|
+
- Test protos: `test/nonnative/v1/*.proto`
|
|
18
17
|
- Build wiring: root `Makefile` includes `bin/build/make/*.mak`
|
|
19
|
-
|
|
20
|
-
## Key repo dependency
|
|
21
|
-
|
|
22
|
-
This repo depends on the `bin/` git submodule.
|
|
23
|
-
|
|
24
|
-
- `.gitmodules` points to `git@github.com:alexfalkowski/bin.git`
|
|
25
|
-
- CI runs `git submodule sync && git submodule update --init`
|
|
26
|
-
- If `bin/` is missing or you do not have SSH access, `make` targets will fail
|
|
27
|
-
|
|
28
|
-
## Core commands
|
|
29
|
-
|
|
18
|
+
- Required submodule: `bin/` from `git@github.com:alexfalkowski/bin.git`; missing SSH/submodule setup breaks `make`
|
|
30
19
|
- Install deps: `make dep`
|
|
31
20
|
- Lint: `make lint`
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
- Clean reports: `make clean-reports`
|
|
36
|
-
|
|
37
|
-
## Runtime model
|
|
38
|
-
|
|
39
|
-
Public entry point is `lib/nonnative.rb`.
|
|
40
|
-
|
|
41
|
-
Main module API:
|
|
42
|
-
|
|
43
|
-
- `configure`
|
|
44
|
-
- `start`
|
|
45
|
-
- `stop`
|
|
46
|
-
- `clear`
|
|
47
|
-
- `reset`
|
|
48
|
-
- `pool`
|
|
21
|
+
- Features: `make features`
|
|
22
|
+
- Benchmarks only: `make benchmarks`
|
|
23
|
+
- Cleanup: `make clean-dep`, `make clean-reports`
|
|
49
24
|
|
|
50
|
-
|
|
25
|
+
## Runtime Model
|
|
51
26
|
|
|
52
|
-
|
|
53
|
-
- from YAML with `config.load_file(...)`
|
|
27
|
+
Public entry point: `lib/nonnative.rb`.
|
|
54
28
|
|
|
55
|
-
|
|
29
|
+
Main API: `configure`, `start`, `stop`, `clear`, `reset`, `pool`.
|
|
56
30
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
31
|
+
Configuration is `Nonnative::Configuration`, built with
|
|
32
|
+
`config.process`, `config.server`, `config.service`, or
|
|
33
|
+
`config.load_file(...)`.
|
|
60
34
|
|
|
61
|
-
|
|
35
|
+
Runners:
|
|
62
36
|
|
|
63
|
-
|
|
37
|
+
- `Nonnative::Process`: OS process
|
|
38
|
+
- `Nonnative::Server`: in-process Ruby server thread
|
|
39
|
+
- `Nonnative::Service`: proxy lifecycle for an externally managed dependency
|
|
64
40
|
|
|
65
|
-
|
|
41
|
+
`Nonnative::Pool` starts services first, then servers/processes, and stops in
|
|
42
|
+
reverse. Readiness and shutdown checks are TCP-only via
|
|
43
|
+
`Nonnative::Port#open?` and `#closed?`.
|
|
66
44
|
|
|
67
|
-
Cucumber
|
|
45
|
+
## Cucumber Surface
|
|
68
46
|
|
|
69
|
-
|
|
70
|
-
|
|
47
|
+
`lib/nonnative/cucumber.rb` is public compatibility surface. Do not remove or
|
|
48
|
+
rename hooks/step text unless the user explicitly requests a breaking change.
|
|
71
49
|
|
|
72
|
-
|
|
50
|
+
Lifecycle tags:
|
|
73
51
|
|
|
74
52
|
- `@startup`: start before scenario, stop after scenario
|
|
75
53
|
- `@manual`: scenario starts manually, stop after scenario
|
|
76
54
|
- `@clear`: call `Nonnative.clear` before scenario
|
|
77
55
|
- `@reset`: reset proxies after scenario
|
|
78
56
|
|
|
79
|
-
|
|
57
|
+
Suite taxonomy tags: `@acceptance`, `@contract`, `@proxy`, `@config`,
|
|
58
|
+
`@service`, `@benchmark`, `@slow`. `make features` excludes `@benchmark`;
|
|
59
|
+
`make benchmarks` runs only `@benchmark`.
|
|
80
60
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- `@service`: coverage centered on external services
|
|
86
|
-
- `@benchmark`: benchmark-only scenarios
|
|
87
|
-
- `@slow`: slower-running scenarios, currently benchmarks
|
|
61
|
+
`Nonnative.clear` clears configuration, logger, observability client, and pool.
|
|
62
|
+
`require 'nonnative'` loads Cucumber integration lazily and is safe outside a
|
|
63
|
+
booted Cucumber runtime. For start-once-per-test-run, use
|
|
64
|
+
`require 'nonnative/startup'`.
|
|
88
65
|
|
|
89
|
-
|
|
66
|
+
## Proxy And Config Gotchas
|
|
90
67
|
|
|
91
|
-
|
|
68
|
+
Proxy wiring is the easiest mistake:
|
|
92
69
|
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
- pool
|
|
70
|
+
- Runner `host` / `port` are client-facing and used for readiness/shutdown
|
|
71
|
+
- For `fault_injection`, nested `proxy.host` / `proxy.port` are the upstream target
|
|
72
|
+
- Clients connect to runner `host` / `port` when a proxy is enabled
|
|
97
73
|
|
|
98
|
-
|
|
74
|
+
Proxy kinds: `none`, `fault_injection`.
|
|
75
|
+
Fault-injection states: `none`, `close_all`, `delay`, `invalid_data`.
|
|
99
76
|
|
|
100
|
-
|
|
77
|
+
Config rules:
|
|
101
78
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
This is the easiest thing to get wrong.
|
|
105
|
-
|
|
106
|
-
- Runner `host` / `port` are the client-facing endpoint and the values used by readiness/shutdown checks
|
|
107
|
-
- For `fault_injection`, nested `proxy.host` / `proxy.port` are the upstream target behind the proxy
|
|
108
|
-
- Clients should connect to the runner `host` / `port` when a proxy is enabled
|
|
109
|
-
|
|
110
|
-
Available proxy kinds:
|
|
111
|
-
|
|
112
|
-
- `none`
|
|
113
|
-
- `fault_injection`
|
|
114
|
-
|
|
115
|
-
Fault injection states:
|
|
116
|
-
|
|
117
|
-
- `none`
|
|
118
|
-
- `close_all`
|
|
119
|
-
- `delay`
|
|
120
|
-
- `invalid_data`
|
|
121
|
-
|
|
122
|
-
## Config gotchas
|
|
123
|
-
|
|
124
|
-
- Services must be declared under `services:` in YAML, not `processes:`
|
|
79
|
+
- YAML services belong under `services:`, not `processes:`
|
|
125
80
|
- There is no top-level `config.wait`; `wait` is per runner
|
|
126
|
-
-
|
|
127
|
-
- Proxy examples need both sides
|
|
128
|
-
|
|
129
|
-
|
|
81
|
+
- Programmatic service config uses `config.service do |s| ... end`, so use `s.host` / `s.port`
|
|
82
|
+
- Proxy examples need both endpoint sides: runner `host` / `port` for the proxy, nested `proxy.host` / `proxy.port` for upstream
|
|
83
|
+
|
|
84
|
+
## Fixtures And Limitations
|
|
130
85
|
|
|
131
|
-
|
|
86
|
+
Useful fixtures:
|
|
132
87
|
|
|
133
|
-
-
|
|
134
|
-
- HTTP
|
|
135
|
-
- TCP
|
|
136
|
-
- gRPC
|
|
88
|
+
- Process: `features/support/bin/start`
|
|
89
|
+
- HTTP: `features/support/http_server.rb`, `features/support/http_proxy_server.rb`
|
|
90
|
+
- TCP: `features/support/tcp_server.rb`
|
|
91
|
+
- gRPC: `features/support/grpc_server.rb`, generated stubs in `test/grpc/`
|
|
137
92
|
|
|
138
|
-
|
|
93
|
+
Limitations:
|
|
139
94
|
|
|
140
|
-
- Ruby version is constrained by `nonnative.gemspec` to `>= 4.0.0` and `< 5.0.0`
|
|
141
95
|
- The `grpc` Ruby library uses a global logger; per-server gRPC loggers are not really supported
|
|
142
|
-
- `make` depends on the `bin/` submodule being present
|
|
143
96
|
- Local Ruby/Bundler mismatches can break native extensions on macOS
|
|
144
|
-
- Coverage
|
|
97
|
+
- Coverage and Cucumber reports go under `test/reports`
|
|
145
98
|
- Port checks can be flaky if tests reuse ports unexpectedly
|
|
146
99
|
|
|
147
|
-
##
|
|
100
|
+
## Look First
|
|
148
101
|
|
|
149
|
-
- Lifecycle
|
|
150
|
-
- Readiness
|
|
102
|
+
- Lifecycle: `lib/nonnative.rb`, `lib/nonnative/pool.rb`
|
|
103
|
+
- Readiness/timeouts: `lib/nonnative/port.rb`, `lib/nonnative/timeout.rb`
|
|
151
104
|
- Process lifecycle: `lib/nonnative/process.rb`
|
|
152
|
-
- Proxies
|
|
153
|
-
- Cucumber
|
|
105
|
+
- Proxies: `lib/nonnative/fault_injection_proxy.rb`, `lib/nonnative/socket_pair_factory.rb`
|
|
106
|
+
- Cucumber: `lib/nonnative/cucumber.rb`, `lib/nonnative/startup.rb`, `features/support/env.rb`
|
|
154
107
|
- Config loading: `lib/nonnative/configuration.rb`, `lib/nonnative/configuration_runner.rb`, `lib/nonnative/configuration_proxy.rb`
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -547,9 +547,13 @@ Nonnative.configure do |config|
|
|
|
547
547
|
config.log = 'nonnative.log'
|
|
548
548
|
|
|
549
549
|
config.process do |p|
|
|
550
|
+
p.host = '127.0.0.1'
|
|
551
|
+
p.port = 20_000
|
|
552
|
+
|
|
550
553
|
p.proxy = {
|
|
551
554
|
kind: 'fault_injection',
|
|
552
|
-
|
|
555
|
+
host: '127.0.0.1',
|
|
556
|
+
port: 12_321,
|
|
553
557
|
log: 'proxy_server.log',
|
|
554
558
|
wait: 1,
|
|
555
559
|
options: {
|
|
@@ -569,9 +573,12 @@ url: http://localhost:4567
|
|
|
569
573
|
log: nonnative.log
|
|
570
574
|
processes:
|
|
571
575
|
-
|
|
576
|
+
host: 127.0.0.1
|
|
577
|
+
port: 20000
|
|
572
578
|
proxy:
|
|
573
579
|
kind: fault_injection
|
|
574
|
-
|
|
580
|
+
host: 127.0.0.1
|
|
581
|
+
port: 12321
|
|
575
582
|
log: proxy_server.log
|
|
576
583
|
wait: 1
|
|
577
584
|
options:
|
|
@@ -592,9 +599,13 @@ Nonnative.configure do |config|
|
|
|
592
599
|
config.log = 'nonnative.log'
|
|
593
600
|
|
|
594
601
|
config.server do |s|
|
|
602
|
+
s.host = '127.0.0.1'
|
|
603
|
+
s.port = 20_000
|
|
604
|
+
|
|
595
605
|
s.proxy = {
|
|
596
606
|
kind: 'fault_injection',
|
|
597
|
-
|
|
607
|
+
host: '127.0.0.1',
|
|
608
|
+
port: 12_321,
|
|
598
609
|
log: 'proxy_server.log',
|
|
599
610
|
wait: 1,
|
|
600
611
|
options: {
|
|
@@ -614,9 +625,12 @@ url: http://localhost:4567
|
|
|
614
625
|
log: nonnative.log
|
|
615
626
|
servers:
|
|
616
627
|
-
|
|
628
|
+
host: 127.0.0.1
|
|
629
|
+
port: 20000
|
|
617
630
|
proxy:
|
|
618
631
|
kind: fault_injection
|
|
619
|
-
|
|
632
|
+
host: 127.0.0.1
|
|
633
|
+
port: 12321
|
|
620
634
|
log: proxy_server.log
|
|
621
635
|
wait: 1
|
|
622
636
|
options:
|
|
@@ -15,8 +15,8 @@ module Nonnative
|
|
|
15
15
|
# @see Nonnative.proxies
|
|
16
16
|
class ConfigurationProxy
|
|
17
17
|
# @return [String] proxy kind name (for example `"none"` or `"fault_injection"`)
|
|
18
|
-
# @return [String] proxy
|
|
19
|
-
# @return [Integer] proxy
|
|
18
|
+
# @return [String] upstream host used by proxy implementations (defaults to `"0.0.0.0"`)
|
|
19
|
+
# @return [Integer] upstream port used by proxy implementations (defaults to `0`)
|
|
20
20
|
# @return [String, nil] path to proxy log file (implementation-dependent)
|
|
21
21
|
# @return [Numeric] wait interval (seconds) after proxy state changes (defaults to `0.1`)
|
|
22
22
|
# @return [Hash] proxy implementation options (implementation-dependent)
|
|
@@ -51,8 +51,8 @@ module Nonnative
|
|
|
51
51
|
#
|
|
52
52
|
# @param value [Hash] proxy attributes
|
|
53
53
|
# @option value [String] :kind proxy kind name (for example `"fault_injection"`)
|
|
54
|
-
# @option value [String] :host
|
|
55
|
-
# @option value [Integer] :port
|
|
54
|
+
# @option value [String] :host upstream host behind the proxy (optional)
|
|
55
|
+
# @option value [Integer] :port upstream port behind the proxy
|
|
56
56
|
# @option value [String] :log proxy log file path
|
|
57
57
|
# @option value [Numeric] :wait wait interval (seconds) after state changes (optional)
|
|
58
58
|
# @option value [Hash] :options proxy implementation specific options
|
data/lib/nonnative/cucumber.rb
CHANGED
|
@@ -32,6 +32,13 @@ module Nonnative
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
module ProxySteps
|
|
35
|
+
PROXY_OPERATIONS = {
|
|
36
|
+
'close_all' => :close_all,
|
|
37
|
+
'delay' => :delay,
|
|
38
|
+
'invalid_data' => :invalid_data,
|
|
39
|
+
'reset' => :reset
|
|
40
|
+
}.freeze
|
|
41
|
+
|
|
35
42
|
def install_proxy_steps
|
|
36
43
|
install_proxy_mutation_steps
|
|
37
44
|
install_proxy_reset_steps
|
|
@@ -40,17 +47,17 @@ module Nonnative
|
|
|
40
47
|
def install_proxy_mutation_steps
|
|
41
48
|
Given('I set the proxy for process {string} to {string}') do |name, operation|
|
|
42
49
|
process = Nonnative.pool.process_by_name(name)
|
|
43
|
-
process.proxy
|
|
50
|
+
Nonnative::Cucumber::Registration.apply_proxy_operation(process.proxy, operation)
|
|
44
51
|
end
|
|
45
52
|
|
|
46
53
|
Given('I set the proxy for server {string} to {string}') do |name, operation|
|
|
47
54
|
server = Nonnative.pool.server_by_name(name)
|
|
48
|
-
server.proxy
|
|
55
|
+
Nonnative::Cucumber::Registration.apply_proxy_operation(server.proxy, operation)
|
|
49
56
|
end
|
|
50
57
|
|
|
51
58
|
Given('I set the proxy for service {string} to {string}') do |name, operation|
|
|
52
59
|
service = Nonnative.pool.service_by_name(name)
|
|
53
|
-
service.proxy
|
|
60
|
+
Nonnative::Cucumber::Registration.apply_proxy_operation(service.proxy, operation)
|
|
54
61
|
end
|
|
55
62
|
end
|
|
56
63
|
|
|
@@ -70,6 +77,14 @@ module Nonnative
|
|
|
70
77
|
service.proxy.reset
|
|
71
78
|
end
|
|
72
79
|
end
|
|
80
|
+
|
|
81
|
+
def apply_proxy_operation(proxy, operation)
|
|
82
|
+
method = PROXY_OPERATIONS.fetch(operation) do
|
|
83
|
+
raise ArgumentError, "Unsupported proxy operation '#{operation}'"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
proxy.public_send(method)
|
|
87
|
+
end
|
|
73
88
|
end
|
|
74
89
|
|
|
75
90
|
module LifecycleSteps
|
data/lib/nonnative/version.rb
CHANGED
data/lib/nonnative.rb
CHANGED
|
@@ -189,7 +189,7 @@ module Nonnative
|
|
|
189
189
|
#
|
|
190
190
|
# @return [Hash{String=>Class}]
|
|
191
191
|
def proxies
|
|
192
|
-
@proxies ||= { 'fault_injection' => Nonnative::FaultInjectionProxy }
|
|
192
|
+
@proxies ||= { 'fault_injection' => Nonnative::FaultInjectionProxy }
|
|
193
193
|
end
|
|
194
194
|
|
|
195
195
|
# Resolves a proxy implementation for a configured kind.
|
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: 2.
|
|
4
|
+
version: 2.15.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alejandro Falkowski
|
|
@@ -345,7 +345,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
345
345
|
- !ruby/object:Gem::Version
|
|
346
346
|
version: '0'
|
|
347
347
|
requirements: []
|
|
348
|
-
rubygems_version: 4.0.
|
|
348
|
+
rubygems_version: 4.0.10
|
|
349
349
|
specification_version: 4
|
|
350
350
|
summary: Allows you to keep using the power of ruby to test other systems
|
|
351
351
|
test_files: []
|