nonnative 3.19.0 → 3.22.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/README.md +11 -1
- data/lib/nonnative/bandwidth_socket_pair.rb +42 -0
- data/lib/nonnative/cucumber.rb +1 -0
- data/lib/nonnative/delay_socket_pair.rb +19 -3
- data/lib/nonnative/fault_injection_proxy.rb +13 -0
- data/lib/nonnative/jwt_token.rb +8 -5
- data/lib/nonnative/paseto_token.rb +7 -4
- data/lib/nonnative/socket_pair_factory.rb +5 -1
- data/lib/nonnative/ssh_token.rb +16 -5
- data/lib/nonnative/token.rb +11 -2
- data/lib/nonnative/version.rb +1 -1
- data/lib/nonnative.rb +1 -0
- metadata +2 -17
- data/.circleci/config.yml +0 -97
- data/.claude/skills +0 -1
- data/.codecov.yml +0 -6
- data/.config/cucumber.yml +0 -1
- data/.editorconfig +0 -13
- data/.github/dependabot.yml +0 -20
- data/.gitignore +0 -18
- data/.gitmodules +0 -3
- data/.goreleaser.yml +0 -17
- data/.rubocop.yml +0 -35
- data/AGENTS.md +0 -208
- data/CLAUDE.md +0 -4
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -232
- data/Makefile +0 -4
- data/nonnative.gemspec +0 -46
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6fa10a31c57c45551a417924990d2d870e137d7561c1581577a6e965099472cc
|
|
4
|
+
data.tar.gz: dcd07b46e9ce599562c9c0f517ff7b6f46b529dfcf70c8f462cef3fd548704eb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cb3cf0ffe148327fb056ad6a16851156b060373d69a06dc13b615197bb6a3aec5cb70faf412c4f31a68f8e92ce297646201fd3151c068758cc22017f5c1a745f
|
|
7
|
+
data.tar.gz: 8caa697ae5eb5c0b005da119b5ff518f68407c52cf876ca065a522147bc98d3064fff7899e54da1897408b9b963b87124ba1f62fd729913c073e3e1de8016dab
|
data/README.md
CHANGED
|
@@ -211,6 +211,15 @@ Nonnative::Token.http_audience('GET', '/v1/things') # => "GET /v1/things"
|
|
|
211
211
|
Nonnative::Token.grpc_audience('/health.v1.Health/Check') # => "/health.v1.Health/Check"
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
+
By default the time claims are pinned to the current time (`iat`/`nbf` at now, `exp` at `now + expiration`). To write negative auth tests, `generate` accepts optional absolute `Time` overrides — `issued_at`, `not_before`, and `expires_at` — for minting not-yet-valid or clock-skewed tokens:
|
|
215
|
+
|
|
216
|
+
```ruby
|
|
217
|
+
# a token that is not valid until an hour from now
|
|
218
|
+
token.generate(aud: 'GET /v1/things', sub: 'user-1', not_before: Time.now + 3600)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
`ssh` tokens have no `nbf` claim, so passing `not_before` for the `ssh` kind raises `ArgumentError`.
|
|
222
|
+
|
|
214
223
|
### 🔁 Lifecycle strategies (Cucumber integration)
|
|
215
224
|
|
|
216
225
|
Nonnative ships Cucumber hooks (when loaded) that support these tags/strategies:
|
|
@@ -789,9 +798,10 @@ Clients connect to the service `host`/`port`, while the proxy forwards traffic t
|
|
|
789
798
|
|
|
790
799
|
- `close_all` - Closes the socket as soon as it connects.
|
|
791
800
|
- `reset_peer` - Resets the socket as soon as it connects, so clients observe a TCP reset (`Errno::ECONNRESET`) rather than the graceful close performed by `close_all`.
|
|
792
|
-
- `delay` - Delays traffic on the connection. Defaults to 2 seconds and can be configured through options.
|
|
801
|
+
- `delay` - Delays traffic on the connection. Defaults to 2 seconds and can be configured through `options.delay`. An optional `options.jitter` (seconds) adds a random offset in `-jitter..jitter` to each delay (a negative value uses its magnitude), so clients see variable, tail-latency-like timing instead of a flat value.
|
|
793
802
|
- `timeout` - Accepts the connection and stalls traffic until reset or stop closes the connection, so clients exercise their own read timeout behavior.
|
|
794
803
|
- `invalid_data` - Forwards client requests unchanged, then corrupts upstream responses before they reach the client.
|
|
804
|
+
- `bandwidth` - Throttles forwarded throughput to `options.rate` kilobytes per second (1 KB = 1024 bytes) by sleeping in proportion to the bytes read, in both directions, so clients see a slow-but-alive dependency. When `rate` is absent or not positive, traffic forwards at full speed.
|
|
795
805
|
|
|
796
806
|
###### 🧩 Fault Injection Services
|
|
797
807
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nonnative
|
|
4
|
+
# Socket-pair variant used by the fault-injection proxy to simulate a bandwidth-limited link.
|
|
5
|
+
#
|
|
6
|
+
# When active, each forwarded read is throttled so throughput does not exceed
|
|
7
|
+
# `proxy.options[:rate]` kilobytes per second (1 KB = 1024 bytes), by sleeping in proportion to the
|
|
8
|
+
# bytes read. Both directions are throttled, so a client under test sees a slow-but-alive
|
|
9
|
+
# dependency. When `rate` is absent or not positive the connection forwards at full speed.
|
|
10
|
+
#
|
|
11
|
+
# This behavior is enabled by calling {Nonnative::FaultInjectionProxy#bandwidth}.
|
|
12
|
+
#
|
|
13
|
+
# @see Nonnative::FaultInjectionProxy
|
|
14
|
+
# @see Nonnative::SocketPairFactory
|
|
15
|
+
# @see Nonnative::SocketPair
|
|
16
|
+
class BandwidthSocketPair < SocketPair
|
|
17
|
+
# One kilobyte in bytes; `proxy.options[:rate]` is expressed in KB/s.
|
|
18
|
+
KILOBYTE = 1024
|
|
19
|
+
|
|
20
|
+
# Reads from the socket, then sleeps so the forwarded throughput stays within the configured rate.
|
|
21
|
+
#
|
|
22
|
+
# @param socket [IO] the socket to read from
|
|
23
|
+
# @return [String] the bytes read from the socket
|
|
24
|
+
def read(socket)
|
|
25
|
+
super.tap { |data| throttle(data.bytesize) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
# Sleeps in proportion to the bytes read so throughput does not exceed `rate` KB/s. A missing or
|
|
31
|
+
# non-positive rate (or an empty read) forwards at full speed.
|
|
32
|
+
#
|
|
33
|
+
# @param bytes [Integer] the number of bytes just read
|
|
34
|
+
# @return [void]
|
|
35
|
+
def throttle(bytes)
|
|
36
|
+
rate = proxy.options[:rate]
|
|
37
|
+
return if rate.nil? || rate <= 0 || bytes.zero?
|
|
38
|
+
|
|
39
|
+
sleep(bytes / (rate * KILOBYTE.to_f))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/nonnative/cucumber.rb
CHANGED
|
@@ -5,7 +5,11 @@ module Nonnative
|
|
|
5
5
|
#
|
|
6
6
|
# When active, reads from the socket are delayed by a configured duration before being forwarded.
|
|
7
7
|
#
|
|
8
|
-
# The delay duration is controlled by `proxy.options[:delay]` and defaults to 2 seconds.
|
|
8
|
+
# The delay duration is controlled by `proxy.options[:delay]` and defaults to 2 seconds. An
|
|
9
|
+
# optional `proxy.options[:jitter]` (seconds) adds a random offset in `-jitter..jitter` to each
|
|
10
|
+
# delay so clients see variable, tail-latency-like timing instead of a flat value; a negative
|
|
11
|
+
# jitter uses its magnitude and the resulting delay is never negative. When `jitter` is absent the
|
|
12
|
+
# delay is the flat duration.
|
|
9
13
|
#
|
|
10
14
|
# This behavior is enabled by calling {Nonnative::FaultInjectionProxy#delay}.
|
|
11
15
|
#
|
|
@@ -20,10 +24,22 @@ module Nonnative
|
|
|
20
24
|
def read(socket)
|
|
21
25
|
Nonnative.logger.info "delaying socket '#{socket.inspect}' for 'delay' pair"
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
sleep duration
|
|
27
|
+
sleep delay_duration
|
|
25
28
|
|
|
26
29
|
super
|
|
27
30
|
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# The delay applied before a read, optionally jittered by `proxy.options[:jitter]`.
|
|
35
|
+
#
|
|
36
|
+
# @return [Numeric] seconds to sleep (never negative)
|
|
37
|
+
def delay_duration
|
|
38
|
+
duration = proxy.options[:delay] || 2
|
|
39
|
+
jitter = proxy.options[:jitter]&.abs
|
|
40
|
+
return duration unless jitter
|
|
41
|
+
|
|
42
|
+
[duration + rand(-jitter..jitter), 0].max
|
|
43
|
+
end
|
|
28
44
|
end
|
|
29
45
|
end
|
|
@@ -14,6 +14,7 @@ module Nonnative
|
|
|
14
14
|
# - {#delay}: delay reads by a configured duration (default: 2 seconds)
|
|
15
15
|
# - {#timeout}: accept connections and keep them silent until clients time out
|
|
16
16
|
# - {#invalid_data}: forward requests unchanged and mutate upstream responses before they reach clients
|
|
17
|
+
# - {#bandwidth}: throttle forwarded throughput to a configured rate (KB/s)
|
|
17
18
|
# - {#reset}: return to healthy pass-through behavior
|
|
18
19
|
#
|
|
19
20
|
# State changes terminate any active connections so new connections observe the new behavior.
|
|
@@ -33,6 +34,8 @@ module Nonnative
|
|
|
33
34
|
# - `wait`: sleep interval (seconds) applied after state changes
|
|
34
35
|
# - `options`:
|
|
35
36
|
# - `delay`: delay duration in seconds used by {#delay}
|
|
37
|
+
# - `jitter`: optional random offset (seconds) added in `-jitter..jitter` to each `delay` (a
|
|
38
|
+
# negative value uses its magnitude), so clients see variable latency instead of a flat value
|
|
36
39
|
#
|
|
37
40
|
# @see Nonnative::Proxy
|
|
38
41
|
# @see Nonnative::SocketPairFactory
|
|
@@ -137,6 +140,16 @@ module Nonnative
|
|
|
137
140
|
apply_state :invalid_data
|
|
138
141
|
end
|
|
139
142
|
|
|
143
|
+
# Throttles forwarded throughput to a configured rate.
|
|
144
|
+
#
|
|
145
|
+
# The rate is controlled by `service.proxy.options[:rate]` (kilobytes per second); when it is
|
|
146
|
+
# absent or not positive the connection forwards at full speed.
|
|
147
|
+
#
|
|
148
|
+
# @return [void]
|
|
149
|
+
def bandwidth
|
|
150
|
+
apply_state :bandwidth
|
|
151
|
+
end
|
|
152
|
+
|
|
140
153
|
# Resets the proxy back to healthy pass-through behavior.
|
|
141
154
|
#
|
|
142
155
|
# @return [void]
|
data/lib/nonnative/jwt_token.rb
CHANGED
|
@@ -27,16 +27,19 @@ module Nonnative
|
|
|
27
27
|
#
|
|
28
28
|
# @param aud [String] the `aud` claim (for example `"GET /v1/things"` or a gRPC full method)
|
|
29
29
|
# @param sub [String] the `sub` claim
|
|
30
|
+
# @param issued_at [Time, nil] overrides the `iat` claim (default: now)
|
|
31
|
+
# @param not_before [Time, nil] overrides the `nbf` claim (default: `issued_at`)
|
|
32
|
+
# @param expires_at [Time, nil] overrides the `exp` claim (default: `issued_at` plus `expiration`)
|
|
30
33
|
# @return [String] the signed JWT
|
|
31
|
-
def generate(aud:, sub:)
|
|
32
|
-
now = Time.now
|
|
34
|
+
def generate(aud:, sub:, issued_at: nil, not_before: nil, expires_at: nil)
|
|
35
|
+
now = issued_at || Time.now
|
|
33
36
|
payload = {
|
|
34
37
|
iss: @issuer,
|
|
35
38
|
aud: aud,
|
|
36
39
|
sub: sub,
|
|
37
|
-
iat: now,
|
|
38
|
-
nbf: now,
|
|
39
|
-
exp: now + @expiration,
|
|
40
|
+
iat: now.to_i,
|
|
41
|
+
nbf: (not_before || now).to_i,
|
|
42
|
+
exp: (expires_at || (now + @expiration)).to_i,
|
|
40
43
|
jti: SecureRandom.uuid
|
|
41
44
|
}
|
|
42
45
|
|
|
@@ -28,18 +28,21 @@ module Nonnative
|
|
|
28
28
|
#
|
|
29
29
|
# @param aud [String] the `aud` claim (for example `"GET /v1/things"` or a gRPC full method)
|
|
30
30
|
# @param sub [String] the `sub` claim
|
|
31
|
+
# @param issued_at [Time, nil] overrides the `iat` claim (default: now)
|
|
32
|
+
# @param not_before [Time, nil] overrides the `nbf` claim (default: `issued_at`)
|
|
33
|
+
# @param expires_at [Time, nil] overrides the `exp` claim (default: `issued_at` plus `expiration`)
|
|
31
34
|
# @return [String] the signed PASETO token
|
|
32
|
-
def generate(aud:, sub:)
|
|
35
|
+
def generate(aud:, sub:, issued_at: nil, not_before: nil, expires_at: nil)
|
|
33
36
|
load_dependencies!
|
|
34
37
|
|
|
35
|
-
now = Time.now.utc
|
|
38
|
+
now = (issued_at || Time.now).utc
|
|
36
39
|
claims = {
|
|
37
40
|
'iss' => @issuer,
|
|
38
41
|
'aud' => aud,
|
|
39
42
|
'sub' => sub,
|
|
40
43
|
'iat' => now.iso8601,
|
|
41
|
-
'nbf' => now.iso8601,
|
|
42
|
-
'exp' => (now + @expiration).iso8601,
|
|
44
|
+
'nbf' => (not_before || now).utc.iso8601,
|
|
45
|
+
'exp' => (expires_at || (now + @expiration)).utc.iso8601,
|
|
43
46
|
'jti' => SecureRandom.uuid
|
|
44
47
|
}
|
|
45
48
|
|
|
@@ -13,6 +13,7 @@ module Nonnative
|
|
|
13
13
|
# - `:delay` -> {Nonnative::DelaySocketPair}
|
|
14
14
|
# - `:timeout` -> {Nonnative::TimeoutSocketPair}
|
|
15
15
|
# - `:invalid_data` -> {Nonnative::InvalidDataSocketPair}
|
|
16
|
+
# - `:bandwidth` -> {Nonnative::BandwidthSocketPair}
|
|
16
17
|
#
|
|
17
18
|
# @see Nonnative::FaultInjectionProxy
|
|
18
19
|
# @see Nonnative::SocketPair
|
|
@@ -21,11 +22,12 @@ module Nonnative
|
|
|
21
22
|
# @see Nonnative::DelaySocketPair
|
|
22
23
|
# @see Nonnative::TimeoutSocketPair
|
|
23
24
|
# @see Nonnative::InvalidDataSocketPair
|
|
25
|
+
# @see Nonnative::BandwidthSocketPair
|
|
24
26
|
class SocketPairFactory
|
|
25
27
|
class << self
|
|
26
28
|
# Creates a socket-pair instance for the given proxy state.
|
|
27
29
|
#
|
|
28
|
-
# @param kind [Symbol] proxy state (e.g. `:none`, `:close_all`, `:reset_peer`, `:delay`, `:timeout`, `:invalid_data`)
|
|
30
|
+
# @param kind [Symbol] proxy state (e.g. `:none`, `:close_all`, `:reset_peer`, `:delay`, `:timeout`, `:invalid_data`, `:bandwidth`)
|
|
29
31
|
# @param proxy [Nonnative::ConfigurationProxy] proxy configuration (host/port/options)
|
|
30
32
|
# @return [Nonnative::SocketPair] a socket-pair implementation instance
|
|
31
33
|
def create(kind, proxy)
|
|
@@ -40,6 +42,8 @@ module Nonnative
|
|
|
40
42
|
TimeoutSocketPair
|
|
41
43
|
when :invalid_data
|
|
42
44
|
InvalidDataSocketPair
|
|
45
|
+
when :bandwidth
|
|
46
|
+
BandwidthSocketPair
|
|
43
47
|
else
|
|
44
48
|
SocketPair
|
|
45
49
|
end
|
data/lib/nonnative/ssh_token.rb
CHANGED
|
@@ -30,18 +30,25 @@ module Nonnative
|
|
|
30
30
|
|
|
31
31
|
# Generates a signed SSH token.
|
|
32
32
|
#
|
|
33
|
+
# SSH tokens carry only `iat`/`exp` (in Unix nanoseconds); there is no `nbf` claim, so
|
|
34
|
+
# `not_before` is rejected.
|
|
35
|
+
#
|
|
33
36
|
# @param aud [String] the `aud` claim (for example `"GET /v1/things"` or a gRPC full method)
|
|
37
|
+
# @param issued_at [Time, nil] overrides the `iat` claim (default: now)
|
|
38
|
+
# @param expires_at [Time, nil] overrides the `exp` claim (default: `issued_at` plus `expiration`)
|
|
39
|
+
# @raise [ArgumentError] if `not_before` is given (SSH tokens have no `nbf` claim)
|
|
34
40
|
# @return [String] the token, `"<base64(claims)>.<base64(signature)>"`
|
|
35
|
-
def generate(aud:, **)
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
def generate(aud:, issued_at: nil, expires_at: nil, not_before: nil, **)
|
|
42
|
+
raise ArgumentError, "ssh tokens do not support 'not_before' (no nbf claim)" unless not_before.nil?
|
|
43
|
+
|
|
44
|
+
iat = nanoseconds(issued_at || Time.now)
|
|
38
45
|
claims = {
|
|
39
46
|
ver: TOKEN_VERSION,
|
|
40
47
|
kid: @key,
|
|
41
48
|
sub: @key,
|
|
42
49
|
aud: aud,
|
|
43
|
-
iat:
|
|
44
|
-
exp:
|
|
50
|
+
iat: iat,
|
|
51
|
+
exp: expires_at ? nanoseconds(expires_at) : iat + (@expiration * 1_000_000_000)
|
|
45
52
|
}.to_json
|
|
46
53
|
|
|
47
54
|
signature = Ed25519::SigningKey.new(seed).sign(claims)
|
|
@@ -51,6 +58,10 @@ module Nonnative
|
|
|
51
58
|
|
|
52
59
|
private
|
|
53
60
|
|
|
61
|
+
def nanoseconds(time)
|
|
62
|
+
(time.to_i * 1_000_000_000) + time.nsec
|
|
63
|
+
end
|
|
64
|
+
|
|
54
65
|
def seed
|
|
55
66
|
SSHData::PrivateKey.parse_openssh(File.read(@private_key)).first.sk[0, 32]
|
|
56
67
|
end
|
data/lib/nonnative/token.rb
CHANGED
|
@@ -54,11 +54,20 @@ module Nonnative
|
|
|
54
54
|
|
|
55
55
|
# Generates a signed token.
|
|
56
56
|
#
|
|
57
|
+
# The optional time claims default to the current time (and the constructor `expiration`), so
|
|
58
|
+
# omitting them reproduces the token's normal claims. Supply them to mint tokens with specific
|
|
59
|
+
# time claims for negative auth tests, such as a not-yet-valid (future `not_before`) or
|
|
60
|
+
# clock-skewed token. Times are absolute; the `ssh` kind has no `nbf` claim and rejects
|
|
61
|
+
# `not_before`.
|
|
62
|
+
#
|
|
57
63
|
# @param aud [String] the `aud` claim
|
|
58
64
|
# @param sub [String] the `sub` claim
|
|
65
|
+
# @param issued_at [Time, nil] overrides the `iat` claim (default: now)
|
|
66
|
+
# @param not_before [Time, nil] overrides the `nbf` claim (default: `issued_at`); unsupported by `ssh`
|
|
67
|
+
# @param expires_at [Time, nil] overrides the `exp` claim (default: `issued_at` plus `expiration`)
|
|
59
68
|
# @return [String] the signed token
|
|
60
|
-
def generate(aud:, sub:)
|
|
61
|
-
@token.generate(aud: aud, sub: sub)
|
|
69
|
+
def generate(aud:, sub:, issued_at: nil, not_before: nil, expires_at: nil)
|
|
70
|
+
@token.generate(aud: aud, sub: sub, issued_at: issued_at, not_before: not_before, expires_at: expires_at)
|
|
62
71
|
end
|
|
63
72
|
end
|
|
64
73
|
end
|
data/lib/nonnative/version.rb
CHANGED
data/lib/nonnative.rb
CHANGED
|
@@ -115,6 +115,7 @@ require 'nonnative/reset_peer_socket_pair'
|
|
|
115
115
|
require 'nonnative/delay_socket_pair'
|
|
116
116
|
require 'nonnative/timeout_socket_pair'
|
|
117
117
|
require 'nonnative/invalid_data_socket_pair'
|
|
118
|
+
require 'nonnative/bandwidth_socket_pair'
|
|
118
119
|
require 'nonnative/socket_pair_factory'
|
|
119
120
|
require 'nonnative/go_executable'
|
|
120
121
|
require 'nonnative/cucumber'
|
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.22.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alejandro Falkowski
|
|
@@ -391,24 +391,10 @@ executables: []
|
|
|
391
391
|
extensions: []
|
|
392
392
|
extra_rdoc_files: []
|
|
393
393
|
files:
|
|
394
|
-
- ".circleci/config.yml"
|
|
395
|
-
- ".claude/skills"
|
|
396
|
-
- ".codecov.yml"
|
|
397
|
-
- ".config/cucumber.yml"
|
|
398
|
-
- ".editorconfig"
|
|
399
|
-
- ".github/dependabot.yml"
|
|
400
|
-
- ".gitignore"
|
|
401
|
-
- ".gitmodules"
|
|
402
|
-
- ".goreleaser.yml"
|
|
403
|
-
- ".rubocop.yml"
|
|
404
|
-
- AGENTS.md
|
|
405
|
-
- CLAUDE.md
|
|
406
|
-
- Gemfile
|
|
407
|
-
- Gemfile.lock
|
|
408
394
|
- LICENSE
|
|
409
|
-
- Makefile
|
|
410
395
|
- README.md
|
|
411
396
|
- lib/nonnative.rb
|
|
397
|
+
- lib/nonnative/bandwidth_socket_pair.rb
|
|
412
398
|
- lib/nonnative/close_all_socket_pair.rb
|
|
413
399
|
- lib/nonnative/configuration.rb
|
|
414
400
|
- lib/nonnative/configuration_file.rb
|
|
@@ -461,7 +447,6 @@ files:
|
|
|
461
447
|
- lib/nonnative/timeout_socket_pair.rb
|
|
462
448
|
- lib/nonnative/token.rb
|
|
463
449
|
- lib/nonnative/version.rb
|
|
464
|
-
- nonnative.gemspec
|
|
465
450
|
homepage: https://github.com/alexfalkowski/nonnative
|
|
466
451
|
licenses:
|
|
467
452
|
- MIT
|
data/.circleci/config.yml
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
version: 2.1
|
|
2
|
-
|
|
3
|
-
commands:
|
|
4
|
-
sync-submodules:
|
|
5
|
-
steps:
|
|
6
|
-
- run: git submodule sync
|
|
7
|
-
- run: git submodule update --init
|
|
8
|
-
checkout-submodules:
|
|
9
|
-
steps:
|
|
10
|
-
- checkout:
|
|
11
|
-
method: blobless
|
|
12
|
-
- sync-submodules
|
|
13
|
-
|
|
14
|
-
executors:
|
|
15
|
-
ruby:
|
|
16
|
-
docker:
|
|
17
|
-
- image: alexfalkowski/ruby:3.20
|
|
18
|
-
release:
|
|
19
|
-
docker:
|
|
20
|
-
- image: alexfalkowski/release:8.22
|
|
21
|
-
alpine:
|
|
22
|
-
docker:
|
|
23
|
-
- image: alpine:latest
|
|
24
|
-
|
|
25
|
-
jobs:
|
|
26
|
-
build:
|
|
27
|
-
executor: ruby
|
|
28
|
-
working_directory: ~/nonnative
|
|
29
|
-
steps:
|
|
30
|
-
- checkout-submodules
|
|
31
|
-
- run: make source-key
|
|
32
|
-
- restore_cache:
|
|
33
|
-
name: restore deps
|
|
34
|
-
keys:
|
|
35
|
-
- nonnative-ruby-cache-{{ checksum "Gemfile.lock" }}-{{ checksum "~/.ruby-version" }}
|
|
36
|
-
- nonnative-ruby-cache-
|
|
37
|
-
- run: make dep
|
|
38
|
-
- run: make clean-dep
|
|
39
|
-
- save_cache:
|
|
40
|
-
name: save deps
|
|
41
|
-
key: nonnative-ruby-cache-{{ checksum "Gemfile.lock" }}-{{ checksum "~/.ruby-version" }}
|
|
42
|
-
paths:
|
|
43
|
-
- vendor
|
|
44
|
-
- run: make lint
|
|
45
|
-
- run: make sec
|
|
46
|
-
- run: make features
|
|
47
|
-
- run: make benchmarks
|
|
48
|
-
- store_test_results:
|
|
49
|
-
path: test/reports
|
|
50
|
-
- store_artifacts:
|
|
51
|
-
path: test/reports
|
|
52
|
-
- run: make codecov-upload
|
|
53
|
-
resource_class: arm.large
|
|
54
|
-
sync:
|
|
55
|
-
executor: release
|
|
56
|
-
working_directory: ~/nonnative
|
|
57
|
-
steps:
|
|
58
|
-
- checkout-submodules
|
|
59
|
-
- run: make sync push
|
|
60
|
-
resource_class: arm.large
|
|
61
|
-
version:
|
|
62
|
-
executor: release
|
|
63
|
-
working_directory: ~/nonnative
|
|
64
|
-
steps:
|
|
65
|
-
- checkout-submodules
|
|
66
|
-
- run: version
|
|
67
|
-
- run: package
|
|
68
|
-
resource_class: arm.large
|
|
69
|
-
wait-all:
|
|
70
|
-
executor: alpine
|
|
71
|
-
resource_class: small
|
|
72
|
-
steps:
|
|
73
|
-
- run: echo "all applicable jobs finished"
|
|
74
|
-
|
|
75
|
-
workflows:
|
|
76
|
-
nonnative:
|
|
77
|
-
jobs:
|
|
78
|
-
- build
|
|
79
|
-
- sync:
|
|
80
|
-
requires:
|
|
81
|
-
- build
|
|
82
|
-
filters:
|
|
83
|
-
branches:
|
|
84
|
-
ignore: master
|
|
85
|
-
- version:
|
|
86
|
-
context: gh
|
|
87
|
-
serial-group: << pipeline.project.slug >>/version
|
|
88
|
-
requires:
|
|
89
|
-
- build
|
|
90
|
-
filters:
|
|
91
|
-
branches:
|
|
92
|
-
only: master
|
|
93
|
-
- wait-all:
|
|
94
|
-
requires:
|
|
95
|
-
- build
|
|
96
|
-
- sync
|
|
97
|
-
- version
|
data/.claude/skills
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
../bin/skills
|
data/.codecov.yml
DELETED
data/.config/cucumber.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
report: --format junit --out test/reports --format html --out test/reports/index.html --format pretty --publish-quiet
|
data/.editorconfig
DELETED
data/.github/dependabot.yml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
version: 2
|
|
2
|
-
updates:
|
|
3
|
-
- package-ecosystem: "bundler"
|
|
4
|
-
directory: "/"
|
|
5
|
-
schedule:
|
|
6
|
-
interval: "daily"
|
|
7
|
-
commit-message:
|
|
8
|
-
prefix: "test"
|
|
9
|
-
prefix-development: "build"
|
|
10
|
-
include: "scope"
|
|
11
|
-
- package-ecosystem: "gitsubmodule"
|
|
12
|
-
directory: "/"
|
|
13
|
-
schedule:
|
|
14
|
-
interval: "daily"
|
|
15
|
-
commit-message:
|
|
16
|
-
prefix: "build"
|
|
17
|
-
prefix-development: "build"
|
|
18
|
-
include: "scope"
|
|
19
|
-
allow:
|
|
20
|
-
- dependency-name: "bin"
|
data/.gitignore
DELETED
data/.gitmodules
DELETED
data/.goreleaser.yml
DELETED
data/.rubocop.yml
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
AllCops:
|
|
2
|
-
TargetRubyVersion: 4.0
|
|
3
|
-
DisplayCopNames: true
|
|
4
|
-
NewCops: enable
|
|
5
|
-
Exclude:
|
|
6
|
-
- "bin/**/*"
|
|
7
|
-
- "vendor/**/*"
|
|
8
|
-
- "test/grpc/**/*"
|
|
9
|
-
|
|
10
|
-
Layout/LineLength:
|
|
11
|
-
Max: 150
|
|
12
|
-
|
|
13
|
-
Lint/HashCompareByIdentity:
|
|
14
|
-
Enabled: false
|
|
15
|
-
|
|
16
|
-
Metrics/MethodLength:
|
|
17
|
-
Max: 20
|
|
18
|
-
|
|
19
|
-
Metrics/BlockLength:
|
|
20
|
-
Max: 90
|
|
21
|
-
|
|
22
|
-
Metrics/AbcSize:
|
|
23
|
-
Max: 25
|
|
24
|
-
|
|
25
|
-
Metrics/ClassLength:
|
|
26
|
-
Max: 150
|
|
27
|
-
|
|
28
|
-
Style/Documentation:
|
|
29
|
-
Enabled: false
|
|
30
|
-
|
|
31
|
-
Style/NumericPredicate:
|
|
32
|
-
Enabled: false
|
|
33
|
-
|
|
34
|
-
Style/FileOpen:
|
|
35
|
-
Enabled: false
|
data/AGENTS.md
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
# AGENTS.md
|
|
2
|
-
|
|
3
|
-
## Shared guidance
|
|
4
|
-
|
|
5
|
-
Use `bin/AGENTS.md` for shared skills and cross-repository defaults.
|
|
6
|
-
|
|
7
|
-
`nonnative` is a Ruby gem for end-to-end testing systems implemented in other
|
|
8
|
-
languages. It starts processes, in-process servers, and proxy-only services,
|
|
9
|
-
waits on TCP readiness/shutdown, and can place fault-injection proxies in front
|
|
10
|
-
of dependencies.
|
|
11
|
-
|
|
12
|
-
## Map And Commands
|
|
13
|
-
|
|
14
|
-
- Library: `lib/nonnative/**/*.rb`
|
|
15
|
-
- Cucumber features/support: `features/**/*.feature`, `features/support/**/*.rb`, `features/step_definitions/**/*.rb`
|
|
16
|
-
- Generated gRPC test stubs: `test/grpc/**/*`
|
|
17
|
-
- Test protos: `test/nonnative/v1/*.proto`
|
|
18
|
-
- Build wiring: root `Makefile` includes `bin/build/make/*.mak`
|
|
19
|
-
- Required submodule: `bin/`; missing submodule setup breaks `make`
|
|
20
|
-
- Install deps: `make dep`
|
|
21
|
-
- Lint: `make lint`
|
|
22
|
-
- Security checks: `make sec`
|
|
23
|
-
- Features: `make features`
|
|
24
|
-
- Benchmarks only: `make benchmarks`
|
|
25
|
-
- Cleanup: `make clean-dep`, `make clean-reports`
|
|
26
|
-
|
|
27
|
-
## Intentional Design Choices
|
|
28
|
-
|
|
29
|
-
- The configured HTTP proxy feature intentionally uses the external
|
|
30
|
-
`www.afalkowski.com` host through `features/support/http_proxy_server.rb`.
|
|
31
|
-
Do not flag this external dependency as a code issue unless the task is
|
|
32
|
-
explicitly about making HTTP proxy fixtures fully hermetic.
|
|
33
|
-
- `test/Makefile` intentionally consumes the shared Buf make fragment as-is.
|
|
34
|
-
Do not flag its inherited `breaking` target's `subdir=api` comparison as a
|
|
35
|
-
code issue unless the task is explicitly about changing test proto breaking
|
|
36
|
-
checks.
|
|
37
|
-
- `nonnative` is a test-support gem used across many downstream projects.
|
|
38
|
-
Do not flag the absence of an isolated gem build/install smoke test as a
|
|
39
|
-
test gap unless the task is explicitly about release packaging or gem
|
|
40
|
-
publication validation.
|
|
41
|
-
- The Cucumber `@startup` lifecycle tag is exercised by downstream projects
|
|
42
|
-
that use this gem. Do not flag missing in-repository `@startup` acceptance
|
|
43
|
-
coverage as a test gap unless the task is explicitly about changing
|
|
44
|
-
Cucumber startup hook behavior.
|
|
45
|
-
- `Nonnative.go_argv` and `Nonnative.go_command` flag combinations are checked
|
|
46
|
-
by external/downstream usage. Do not flag missing in-repository exhaustive
|
|
47
|
-
`-test.*` flag or tool-filtering assertions as a test gap unless the task is
|
|
48
|
-
explicitly about changing Go command generation.
|
|
49
|
-
- Generated gRPC test stubs under `test/grpc/` are updated on demand when the
|
|
50
|
-
test proto changes. Do not flag the absence of an automatic generated-stub
|
|
51
|
-
freshness check as a test gap unless the task is explicitly about changing
|
|
52
|
-
test proto generation or generated-file validation.
|
|
53
|
-
- Generated gRPC test stubs may carry manual require-path adjustments after
|
|
54
|
-
generation. Do not treat `make -C test stale` as a required validation target
|
|
55
|
-
unless the task is explicitly about changing test proto generation; verify
|
|
56
|
-
the generated Ruby loads before accepting generator-only rewrites.
|
|
57
|
-
- Buf linting for the test-only proto module is intentionally not part of the
|
|
58
|
-
required local validation surface. Do not flag missing root-level validation
|
|
59
|
-
for `test/buf.yaml` as a test gap unless the task is explicitly about test
|
|
60
|
-
proto linting or Buf validation.
|
|
61
|
-
- The public proxy reset Cucumber steps and `@reset` hook are tested by
|
|
62
|
-
external/downstream suites. Do not flag missing in-repository direct proxy
|
|
63
|
-
reset step coverage as a test gap unless the task is explicitly about
|
|
64
|
-
changing proxy reset behavior.
|
|
65
|
-
- `Nonnative.clear` configuration and pool reset behavior is covered by
|
|
66
|
-
external/downstream suites. Do not flag missing in-repository assertions for
|
|
67
|
-
configuration or pool clearing as a test gap unless the task is explicitly
|
|
68
|
-
about changing clear/reset lifecycle behavior.
|
|
69
|
-
- Full repository validation is expected to run both regular features and
|
|
70
|
-
benchmark-tagged lifecycle scenarios. Do not flag rollback/timeout lifecycle
|
|
71
|
-
coverage living under `features/benchmark.feature` as a test gap unless the
|
|
72
|
-
task is explicitly about changing validation target composition.
|
|
73
|
-
- Service proxy round-trip behavior is validated by downstream projects that
|
|
74
|
-
use `nonnative` against real dependencies. Do not flag the in-repository
|
|
75
|
-
service proxy success scenario's connection-only assertion as a test gap
|
|
76
|
-
unless the task is explicitly about changing service proxy forwarding.
|
|
77
|
-
- `Nonnative::FaultInjectionProxy` owns its listener thread and stops it by
|
|
78
|
-
closing the owned `TCPServer`, which wakes the accept loop before joining the
|
|
79
|
-
thread. Do not flag the listener `join` as an unbounded reliability gap unless
|
|
80
|
-
the task is explicitly about proxy shutdown behavior or there is a normal-use
|
|
81
|
-
reproducer, failing CI evidence, or platform-specific hang evidence.
|
|
82
|
-
- Service readiness is intentionally TCP-only for externally managed
|
|
83
|
-
dependencies. Do not flag missing HTTP/gRPC service readiness as a feature gap
|
|
84
|
-
unless the task is explicitly about changing the `Nonnative::Service`
|
|
85
|
-
readiness model. HTTP/gRPC readiness belongs to managed processes, where the
|
|
86
|
-
user explicitly models the application health endpoints.
|
|
87
|
-
- Process runners intentionally inherit the parent working directory. Nonnative
|
|
88
|
-
is normally run from the test folder that owns `test/nonnative.yml`, relative
|
|
89
|
-
config paths, logs, and reports. Do not flag missing process cwd/chdir support
|
|
90
|
-
as a feature gap unless the task is explicitly about changing process working
|
|
91
|
-
directory behavior.
|
|
92
|
-
- Message-specific start/stop assertions and attempted-stop success assertions
|
|
93
|
-
in `features/step_definitions/lifecycle_steps.rb` are repository-local
|
|
94
|
-
Cucumber helpers. Do not flag their absence from `lib/nonnative/cucumber.rb`
|
|
95
|
-
as a feature gap unless downstream usage evidence exists or the task is
|
|
96
|
-
explicitly about expanding public lifecycle assertion steps.
|
|
97
|
-
- Liveness, readiness, and metrics endpoint assertion steps in
|
|
98
|
-
`features/step_definitions/servers_steps.rb` are repository-local Cucumber
|
|
99
|
-
helpers for testing nonnative's own framework assumptions. Do not flag their
|
|
100
|
-
absence from `lib/nonnative/cucumber.rb` as a feature gap unless downstream
|
|
101
|
-
usage evidence exists or the task is explicitly about expanding public
|
|
102
|
-
observability assertion steps.
|
|
103
|
-
- `Nonnative::Configuration` intentionally exposes `process_by_name` without
|
|
104
|
-
matching `server_by_name` or `service_by_name` helpers. Do not flag missing
|
|
105
|
-
server/service configuration lookup helpers as a feature gap unless downstream
|
|
106
|
-
usage evidence exists or the task is explicitly about changing the
|
|
107
|
-
pre-start configuration lookup API.
|
|
108
|
-
|
|
109
|
-
## Runtime Model
|
|
110
|
-
|
|
111
|
-
Public entry point: `lib/nonnative.rb`.
|
|
112
|
-
|
|
113
|
-
Main API: `configure`, `start`, `stop`, `clear`, `reset`, `pool`,
|
|
114
|
-
`go_argv`, `go_command`, `token`.
|
|
115
|
-
|
|
116
|
-
Configuration is `Nonnative::Configuration`, built with
|
|
117
|
-
`config.process`, `config.server`, `config.service`, or
|
|
118
|
-
`config.load_file(...)`.
|
|
119
|
-
|
|
120
|
-
Runners:
|
|
121
|
-
|
|
122
|
-
- `Nonnative::Process`: OS process
|
|
123
|
-
- `Nonnative::Server`: in-process Ruby server thread
|
|
124
|
-
- `Nonnative::Service`: proxy lifecycle for an externally managed dependency
|
|
125
|
-
|
|
126
|
-
`Nonnative::Pool` starts services first, then servers/processes, and stops in
|
|
127
|
-
reverse. Readiness and shutdown checks are TCP-only via
|
|
128
|
-
`Nonnative::Port#open?` and `#closed?`.
|
|
129
|
-
|
|
130
|
-
Token generation: `Nonnative.token(kind:, issuer:, key:, private_key:, expiration:)`
|
|
131
|
-
returns a `Nonnative::Token` whose `generate(aud:, sub:)` produces a signed token for
|
|
132
|
-
authenticating against services under test; it feeds `Nonnative::Header.auth_bearer`.
|
|
133
|
-
Kinds are `jwt` (EdDSA, `kid` header), `paseto` (v4.public, `kid` footer), and `ssh`
|
|
134
|
-
(go-service style raw-Ed25519 `base64(claims).base64(signature)`). All Ed25519 and
|
|
135
|
-
generation-only. `jwt`/`paseto` take a PKCS#8 PEM key; `ssh` takes an OpenSSH-format
|
|
136
|
-
key. PASETO needs system libsodium (via `rbnacl`), required lazily so `require
|
|
137
|
-
'nonnative'` works without it until a PASETO token is generated.
|
|
138
|
-
`Nonnative::Token.http_audience` / `grpc_audience` build the endpoint-scoped `aud`.
|
|
139
|
-
|
|
140
|
-
## Cucumber Surface
|
|
141
|
-
|
|
142
|
-
`lib/nonnative/cucumber.rb` is public compatibility surface. Do not remove or
|
|
143
|
-
rename hooks/step text unless the user explicitly requests a breaking change.
|
|
144
|
-
|
|
145
|
-
Lifecycle tags:
|
|
146
|
-
|
|
147
|
-
- `@startup`: start before scenario, stop after scenario
|
|
148
|
-
- `@manual`: scenario starts manually, stop after scenario
|
|
149
|
-
- `@clear`: call `Nonnative.clear` before scenario
|
|
150
|
-
- `@reset`: reset proxies after scenario
|
|
151
|
-
|
|
152
|
-
Suite taxonomy tags: `@acceptance`, `@contract`, `@proxy`, `@config`,
|
|
153
|
-
`@service`, `@benchmark`, `@slow`. `make features` excludes `@benchmark`;
|
|
154
|
-
`make benchmarks` runs only `@benchmark`.
|
|
155
|
-
|
|
156
|
-
`Nonnative.clear` clears configuration, logger, observability client, and pool.
|
|
157
|
-
`require 'nonnative'` loads Cucumber integration lazily and is safe outside a
|
|
158
|
-
booted Cucumber runtime. For start-once-per-test-run, use
|
|
159
|
-
`require 'nonnative/startup'`.
|
|
160
|
-
|
|
161
|
-
## Proxy And Config Gotchas
|
|
162
|
-
|
|
163
|
-
Proxy wiring is the easiest mistake:
|
|
164
|
-
|
|
165
|
-
- Runner `host` / `port` are client-facing and used for readiness/shutdown
|
|
166
|
-
- For `fault_injection`, nested `proxy.host` / `proxy.port` are the upstream target
|
|
167
|
-
- Clients connect to runner `host` / `port` when a proxy is enabled
|
|
168
|
-
|
|
169
|
-
Proxy kinds: `none`, `fault_injection`.
|
|
170
|
-
Fault-injection states: `none`, `close_all`, `delay`, `invalid_data`.
|
|
171
|
-
|
|
172
|
-
Config rules:
|
|
173
|
-
|
|
174
|
-
- YAML config is loaded as data only via `Nonnative::ConfigurationFile`; ERB is not evaluated and arbitrary Ruby object tags are rejected
|
|
175
|
-
- Runner `host` and nested `proxy.host` default to `127.0.0.1`; use explicit `0.0.0.0` only when external access is intended
|
|
176
|
-
- Process `command` can be a legacy shell string or an argv array; prefer argv arrays for new config, and `go:` config builds argv internally with `Nonnative.go_argv`
|
|
177
|
-
- Use `Nonnative.go_argv` for no-shell Go executable argv entries and `Nonnative.go_command` only when a caller needs Ruby shell-style command string spawning
|
|
178
|
-
- YAML services belong under `services:`, not `processes:`
|
|
179
|
-
- There is no top-level `config.wait`; `wait` is per runner
|
|
180
|
-
- Programmatic service config uses `config.service do |s| ... end`, so use `s.host` / `s.port`
|
|
181
|
-
- Proxy examples need both endpoint sides: runner `host` / `port` for the proxy, nested `proxy.host` / `proxy.port` for upstream
|
|
182
|
-
|
|
183
|
-
## Fixtures And Limitations
|
|
184
|
-
|
|
185
|
-
Useful fixtures:
|
|
186
|
-
|
|
187
|
-
- Process: `features/support/bin/start`
|
|
188
|
-
- HTTP: `features/support/http_server.rb`, `features/support/http_proxy_server.rb`
|
|
189
|
-
- TCP: `features/support/tcp_server.rb`
|
|
190
|
-
- gRPC: `features/support/grpc_server.rb`, generated stubs in `test/grpc/`
|
|
191
|
-
|
|
192
|
-
Limitations:
|
|
193
|
-
|
|
194
|
-
- The `grpc` Ruby library uses a global logger; per-server gRPC loggers are not really supported
|
|
195
|
-
- Local Ruby/Bundler mismatches can break native extensions on macOS
|
|
196
|
-
- Coverage and Cucumber reports go under `test/reports`
|
|
197
|
-
- Port checks can be flaky if tests reuse ports unexpectedly
|
|
198
|
-
|
|
199
|
-
## Look First
|
|
200
|
-
|
|
201
|
-
- Lifecycle: `lib/nonnative.rb`, `lib/nonnative/pool.rb`
|
|
202
|
-
- Readiness/timeouts: `lib/nonnative/port.rb`, `lib/nonnative/timeout.rb`
|
|
203
|
-
- Process lifecycle: `lib/nonnative/process.rb`
|
|
204
|
-
- Go executable command/argv building: `lib/nonnative/go_executable.rb`
|
|
205
|
-
- Token generation: `lib/nonnative/token.rb`, `lib/nonnative/jwt_token.rb`, `lib/nonnative/paseto_token.rb`, `lib/nonnative/ssh_token.rb`, `lib/nonnative/ed25519_key.rb`
|
|
206
|
-
- Proxies: `lib/nonnative/fault_injection_proxy.rb`, `lib/nonnative/socket_pair_factory.rb`
|
|
207
|
-
- Cucumber: `lib/nonnative/cucumber.rb`, `lib/nonnative/startup.rb`, `features/support/env.rb`
|
|
208
|
-
- Config loading: `lib/nonnative/configuration.rb`, `lib/nonnative/configuration_file.rb`, `lib/nonnative/configuration_runner.rb`, `lib/nonnative/configuration_proxy.rb`
|
data/CLAUDE.md
DELETED
data/Gemfile
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
source 'https://rubygems.org'
|
|
4
|
-
|
|
5
|
-
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
6
|
-
|
|
7
|
-
# Specify your gem's dependencies in nonnative.gemspec
|
|
8
|
-
gemspec
|
|
9
|
-
|
|
10
|
-
gem 'bundler'
|
|
11
|
-
gem 'rubocop'
|
|
12
|
-
gem 'ruby-lsp'
|
|
13
|
-
gem 'simplecov'
|
|
14
|
-
gem 'simplecov-cobertura'
|
data/Gemfile.lock
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
nonnative (3.19.0)
|
|
5
|
-
concurrent-ruby (>= 1, < 2)
|
|
6
|
-
config (>= 5, < 6)
|
|
7
|
-
cucumber (>= 7, < 12)
|
|
8
|
-
cucumber-cucumber-expressions (< 19)
|
|
9
|
-
ed25519 (>= 1, < 2)
|
|
10
|
-
get_process_mem (>= 1, < 2)
|
|
11
|
-
grpc (>= 1, < 2)
|
|
12
|
-
jwt (>= 3, < 4)
|
|
13
|
-
jwt-eddsa (>= 0, < 1)
|
|
14
|
-
puma (>= 7, < 8)
|
|
15
|
-
rbnacl (>= 7, < 8)
|
|
16
|
-
rest-client (>= 2, < 3)
|
|
17
|
-
retriable (>= 3, < 4)
|
|
18
|
-
rspec-benchmark (>= 0, < 1)
|
|
19
|
-
rspec-expectations (>= 3, < 4)
|
|
20
|
-
rspec-wait (>= 1, < 2)
|
|
21
|
-
ruby-paseto (>= 0, < 1)
|
|
22
|
-
sinatra (>= 4, < 5)
|
|
23
|
-
ssh_data (>= 1, < 2)
|
|
24
|
-
|
|
25
|
-
GEM
|
|
26
|
-
remote: https://rubygems.org/
|
|
27
|
-
specs:
|
|
28
|
-
ast (2.4.3)
|
|
29
|
-
base64 (0.3.0)
|
|
30
|
-
benchmark-malloc (0.2.0)
|
|
31
|
-
benchmark-perf (0.6.0)
|
|
32
|
-
benchmark-trend (0.4.0)
|
|
33
|
-
bigdecimal (4.1.2)
|
|
34
|
-
builder (3.3.0)
|
|
35
|
-
concurrent-ruby (1.3.7)
|
|
36
|
-
config (5.6.1)
|
|
37
|
-
deep_merge (~> 1.2, >= 1.2.1)
|
|
38
|
-
ostruct
|
|
39
|
-
cucumber (11.1.1)
|
|
40
|
-
base64 (~> 0.2)
|
|
41
|
-
builder (~> 3.2)
|
|
42
|
-
cucumber-ci-environment (> 9, < 12)
|
|
43
|
-
cucumber-core (>= 16.2.0, < 17)
|
|
44
|
-
cucumber-cucumber-expressions (> 17, < 20)
|
|
45
|
-
cucumber-html-formatter (> 21, < 24)
|
|
46
|
-
diff-lcs (~> 1.5)
|
|
47
|
-
logger (~> 1.6)
|
|
48
|
-
mini_mime (~> 1.1)
|
|
49
|
-
multi_test (~> 1.1)
|
|
50
|
-
sys-uname (~> 1.5)
|
|
51
|
-
cucumber-ci-environment (11.0.0)
|
|
52
|
-
cucumber-core (16.2.0)
|
|
53
|
-
cucumber-gherkin (> 36, < 40)
|
|
54
|
-
cucumber-messages (> 31, < 33)
|
|
55
|
-
cucumber-tag-expressions (> 6, < 9)
|
|
56
|
-
cucumber-cucumber-expressions (18.1.0)
|
|
57
|
-
bigdecimal
|
|
58
|
-
cucumber-gherkin (39.1.0)
|
|
59
|
-
cucumber-messages (>= 31, < 33)
|
|
60
|
-
cucumber-html-formatter (23.1.0)
|
|
61
|
-
cucumber-messages (> 23, < 33)
|
|
62
|
-
cucumber-messages (32.3.1)
|
|
63
|
-
cucumber-tag-expressions (8.1.0)
|
|
64
|
-
deep_merge (1.2.2)
|
|
65
|
-
diff-lcs (1.6.2)
|
|
66
|
-
docile (1.4.1)
|
|
67
|
-
domain_name (0.6.20240107)
|
|
68
|
-
ed25519 (1.4.0)
|
|
69
|
-
ffi (1.17.4-x86_64-darwin)
|
|
70
|
-
ffi (1.17.4-x86_64-linux-gnu)
|
|
71
|
-
get_process_mem (1.0.0)
|
|
72
|
-
bigdecimal (>= 2.0)
|
|
73
|
-
ffi (~> 1.0)
|
|
74
|
-
google-protobuf (4.35.1-x86_64-darwin)
|
|
75
|
-
bigdecimal
|
|
76
|
-
rake (~> 13.3)
|
|
77
|
-
google-protobuf (4.35.1-x86_64-linux-gnu)
|
|
78
|
-
bigdecimal
|
|
79
|
-
rake (~> 13.3)
|
|
80
|
-
googleapis-common-protos-types (1.23.0)
|
|
81
|
-
google-protobuf (~> 4.26)
|
|
82
|
-
grpc (1.82.0-x86_64-darwin)
|
|
83
|
-
google-protobuf (>= 3.25, < 5.0)
|
|
84
|
-
googleapis-common-protos-types (~> 1.0)
|
|
85
|
-
grpc (1.82.0-x86_64-linux-gnu)
|
|
86
|
-
google-protobuf (>= 3.25, < 5.0)
|
|
87
|
-
googleapis-common-protos-types (~> 1.0)
|
|
88
|
-
http-accept (1.7.0)
|
|
89
|
-
http-cookie (1.1.6)
|
|
90
|
-
domain_name (~> 0.5)
|
|
91
|
-
json (2.20.0)
|
|
92
|
-
jwt (3.2.0)
|
|
93
|
-
base64
|
|
94
|
-
jwt-eddsa (0.9.0)
|
|
95
|
-
base64
|
|
96
|
-
ed25519
|
|
97
|
-
jwt (>= 2.9.0)
|
|
98
|
-
language_server-protocol (3.17.0.6)
|
|
99
|
-
lint_roller (1.1.0)
|
|
100
|
-
logger (1.7.0)
|
|
101
|
-
memoist3 (1.0.0)
|
|
102
|
-
mime-types (3.7.0)
|
|
103
|
-
logger
|
|
104
|
-
mime-types-data (~> 3.2025, >= 3.2025.0507)
|
|
105
|
-
mime-types-data (3.2026.0701)
|
|
106
|
-
mini_mime (1.1.5)
|
|
107
|
-
multi_json (1.15.0)
|
|
108
|
-
multi_test (1.1.0)
|
|
109
|
-
mustermann (3.1.1)
|
|
110
|
-
netrc (0.11.0)
|
|
111
|
-
nio4r (2.7.5)
|
|
112
|
-
openssl (3.3.3)
|
|
113
|
-
ostruct (0.6.3)
|
|
114
|
-
parallel (2.1.0)
|
|
115
|
-
parser (3.3.11.1)
|
|
116
|
-
ast (~> 2.4.1)
|
|
117
|
-
racc
|
|
118
|
-
prism (1.9.0)
|
|
119
|
-
puma (7.2.1)
|
|
120
|
-
nio4r (~> 2.0)
|
|
121
|
-
racc (1.8.1)
|
|
122
|
-
rack (3.2.6)
|
|
123
|
-
rack-protection (4.2.1)
|
|
124
|
-
base64 (>= 0.1.0)
|
|
125
|
-
logger (>= 1.6.0)
|
|
126
|
-
rack (>= 3.0.0, < 4)
|
|
127
|
-
rack-session (2.1.2)
|
|
128
|
-
base64 (>= 0.1.0)
|
|
129
|
-
rack (>= 3.0.0)
|
|
130
|
-
rainbow (3.1.1)
|
|
131
|
-
rake (13.4.2)
|
|
132
|
-
rbnacl (7.1.2)
|
|
133
|
-
ffi (~> 1)
|
|
134
|
-
rbs (4.0.3)
|
|
135
|
-
logger
|
|
136
|
-
prism (>= 1.6.0)
|
|
137
|
-
tsort
|
|
138
|
-
regexp_parser (2.12.0)
|
|
139
|
-
rest-client (2.1.0)
|
|
140
|
-
http-accept (>= 1.7.0, < 2.0)
|
|
141
|
-
http-cookie (>= 1.0.2, < 2.0)
|
|
142
|
-
mime-types (>= 1.16, < 4.0)
|
|
143
|
-
netrc (~> 0.8)
|
|
144
|
-
retriable (3.8.0)
|
|
145
|
-
rexml (3.4.4)
|
|
146
|
-
rspec (3.13.2)
|
|
147
|
-
rspec-core (~> 3.13.0)
|
|
148
|
-
rspec-expectations (~> 3.13.0)
|
|
149
|
-
rspec-mocks (~> 3.13.0)
|
|
150
|
-
rspec-benchmark (0.6.0)
|
|
151
|
-
benchmark-malloc (~> 0.2)
|
|
152
|
-
benchmark-perf (~> 0.6)
|
|
153
|
-
benchmark-trend (~> 0.4)
|
|
154
|
-
rspec (>= 3.0)
|
|
155
|
-
rspec-core (3.13.6)
|
|
156
|
-
rspec-support (~> 3.13.0)
|
|
157
|
-
rspec-expectations (3.13.5)
|
|
158
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
159
|
-
rspec-support (~> 3.13.0)
|
|
160
|
-
rspec-mocks (3.13.8)
|
|
161
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
162
|
-
rspec-support (~> 3.13.0)
|
|
163
|
-
rspec-support (3.13.7)
|
|
164
|
-
rspec-wait (1.0.2)
|
|
165
|
-
rspec (>= 3.4)
|
|
166
|
-
rubocop (1.88.1)
|
|
167
|
-
json (~> 2.3)
|
|
168
|
-
language_server-protocol (~> 3.17.0.2)
|
|
169
|
-
lint_roller (~> 1.1.0)
|
|
170
|
-
parallel (>= 1.10)
|
|
171
|
-
parser (>= 3.3.0.2)
|
|
172
|
-
rainbow (>= 2.2.2, < 4.0)
|
|
173
|
-
regexp_parser (>= 2.9.3, < 3.0)
|
|
174
|
-
rubocop-ast (>= 1.49.0, < 2.0)
|
|
175
|
-
ruby-progressbar (~> 1.7)
|
|
176
|
-
unicode-display_width (>= 2.4.0, < 4.0)
|
|
177
|
-
rubocop-ast (1.50.0)
|
|
178
|
-
parser (>= 3.3.7.2)
|
|
179
|
-
prism (~> 1.7)
|
|
180
|
-
ruby-lsp (0.26.9)
|
|
181
|
-
language_server-protocol (~> 3.17.0)
|
|
182
|
-
prism (>= 1.2, < 2.0)
|
|
183
|
-
rbs (>= 3, < 5)
|
|
184
|
-
ruby-paseto (0.2.0)
|
|
185
|
-
multi_json (~> 1.15.0)
|
|
186
|
-
openssl (~> 3.3)
|
|
187
|
-
sorbet-runtime
|
|
188
|
-
zeitwerk
|
|
189
|
-
ruby-progressbar (1.13.0)
|
|
190
|
-
simplecov (0.22.0)
|
|
191
|
-
docile (~> 1.1)
|
|
192
|
-
simplecov-html (~> 0.11)
|
|
193
|
-
simplecov_json_formatter (~> 0.1)
|
|
194
|
-
simplecov-cobertura (3.2.0)
|
|
195
|
-
rexml
|
|
196
|
-
simplecov (~> 0.19)
|
|
197
|
-
simplecov-html (0.13.2)
|
|
198
|
-
simplecov_json_formatter (0.1.4)
|
|
199
|
-
sinatra (4.2.1)
|
|
200
|
-
logger (>= 1.6.0)
|
|
201
|
-
mustermann (~> 3.0)
|
|
202
|
-
rack (>= 3.0.0, < 4)
|
|
203
|
-
rack-protection (= 4.2.1)
|
|
204
|
-
rack-session (>= 2.0.0, < 3)
|
|
205
|
-
tilt (~> 2.0)
|
|
206
|
-
sorbet-runtime (0.6.13323)
|
|
207
|
-
ssh_data (1.3.0)
|
|
208
|
-
sys-uname (1.5.1)
|
|
209
|
-
ffi (~> 1.1)
|
|
210
|
-
memoist3 (~> 1.0.0)
|
|
211
|
-
tilt (2.8.0)
|
|
212
|
-
tsort (0.2.0)
|
|
213
|
-
unicode-display_width (3.2.0)
|
|
214
|
-
unicode-emoji (~> 4.1)
|
|
215
|
-
unicode-emoji (4.2.0)
|
|
216
|
-
zeitwerk (2.8.2)
|
|
217
|
-
|
|
218
|
-
PLATFORMS
|
|
219
|
-
x86_64-darwin-21
|
|
220
|
-
x86_64-darwin-23
|
|
221
|
-
x86_64-linux
|
|
222
|
-
|
|
223
|
-
DEPENDENCIES
|
|
224
|
-
bundler
|
|
225
|
-
nonnative!
|
|
226
|
-
rubocop
|
|
227
|
-
ruby-lsp
|
|
228
|
-
simplecov
|
|
229
|
-
simplecov-cobertura
|
|
230
|
-
|
|
231
|
-
BUNDLED WITH
|
|
232
|
-
4.0.11
|
data/Makefile
DELETED
data/nonnative.gemspec
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
lib = File.expand_path('lib', __dir__)
|
|
4
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
-
|
|
6
|
-
require 'nonnative/version'
|
|
7
|
-
|
|
8
|
-
Gem::Specification.new do |spec|
|
|
9
|
-
spec.name = 'nonnative'
|
|
10
|
-
spec.version = Nonnative::VERSION
|
|
11
|
-
spec.authors = ['Alejandro Falkowski']
|
|
12
|
-
spec.email = ['alexrfalkowski@gmail.com']
|
|
13
|
-
|
|
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
|
-
spec.homepage = 'https://github.com/alexfalkowski/nonnative'
|
|
17
|
-
spec.license = 'MIT'
|
|
18
|
-
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
19
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
20
|
-
end
|
|
21
|
-
spec.bindir = 'exe'
|
|
22
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
23
|
-
spec.require_paths = ['lib']
|
|
24
|
-
spec.required_ruby_version = ['>= 4.0.0', '< 5.0.0']
|
|
25
|
-
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
26
|
-
|
|
27
|
-
spec.add_dependency 'concurrent-ruby', '>= 1', '< 2'
|
|
28
|
-
spec.add_dependency 'config', '>= 5', '< 6'
|
|
29
|
-
spec.add_dependency 'cucumber', '>= 7', '< 12'
|
|
30
|
-
spec.add_dependency 'cucumber-cucumber-expressions', '< 19'
|
|
31
|
-
spec.add_dependency 'ed25519', '>= 1', '< 2'
|
|
32
|
-
spec.add_dependency 'get_process_mem', '>= 1', '< 2'
|
|
33
|
-
spec.add_dependency 'grpc', '>= 1', '< 2'
|
|
34
|
-
spec.add_dependency 'jwt', '>= 3', '< 4'
|
|
35
|
-
spec.add_dependency 'jwt-eddsa', '>= 0', '< 1'
|
|
36
|
-
spec.add_dependency 'puma', '>= 7', '< 8'
|
|
37
|
-
spec.add_dependency 'rbnacl', '>= 7', '< 8'
|
|
38
|
-
spec.add_dependency 'rest-client', '>= 2', '< 3'
|
|
39
|
-
spec.add_dependency 'retriable', '>= 3', '< 4'
|
|
40
|
-
spec.add_dependency 'rspec-benchmark', '>= 0', '< 1'
|
|
41
|
-
spec.add_dependency 'rspec-expectations', '>= 3', '< 4'
|
|
42
|
-
spec.add_dependency 'rspec-wait', '>= 1', '< 2'
|
|
43
|
-
spec.add_dependency 'ruby-paseto', '>= 0', '< 1'
|
|
44
|
-
spec.add_dependency 'sinatra', '>= 4', '< 5'
|
|
45
|
-
spec.add_dependency 'ssh_data', '>= 1', '< 2'
|
|
46
|
-
end
|