Module: Nonnative

Defined in:
lib/nonnative.rb,
lib/nonnative/pool.rb,
lib/nonnative/port.rb,
lib/nonnative/error.rb,
lib/nonnative/ports.rb,
lib/nonnative/proxy.rb,
lib/nonnative/token.rb,
lib/nonnative/header.rb,
lib/nonnative/runner.rb,
lib/nonnative/server.rb,
lib/nonnative/process.rb,
lib/nonnative/service.rb,
lib/nonnative/timeout.rb,
lib/nonnative/version.rb,
lib/nonnative/cucumber.rb,
lib/nonnative/no_proxy.rb,
lib/nonnative/jwt_token.rb,
lib/nonnative/tcp_probe.rb,
lib/nonnative/grpc_probe.rb,
lib/nonnative/http_probe.rb,
lib/nonnative/stop_error.rb,
lib/nonnative/ed25519_key.rb,
lib/nonnative/grpc_health.rb,
lib/nonnative/grpc_server.rb,
lib/nonnative/http_client.rb,
lib/nonnative/http_server.rb,
lib/nonnative/socket_pair.rb,
lib/nonnative/start_error.rb,
lib/nonnative/http_service.rb,
lib/nonnative/configuration.rb,
lib/nonnative/go_executable.rb,
lib/nonnative/observability.rb,
lib/nonnative/proxy_factory.rb,
lib/nonnative/not_found_error.rb,
lib/nonnative/delay_socket_pair.rb,
lib/nonnative/flaky_socket_pair.rb,
lib/nonnative/http_proxy_server.rb,
lib/nonnative/configuration_file.rb,
lib/nonnative/slicer_socket_pair.rb,
lib/nonnative/configuration_proxy.rb,
lib/nonnative/socket_pair_factory.rb,
lib/nonnative/timeout_socket_pair.rb,
lib/nonnative/configuration_runner.rb,
lib/nonnative/configuration_server.rb,
lib/nonnative/bandwidth_socket_pair.rb,
lib/nonnative/close_all_socket_pair.rb,
lib/nonnative/configuration_process.rb,
lib/nonnative/configuration_service.rb,
lib/nonnative/fault_injection_proxy.rb,
lib/nonnative/limit_data_socket_pair.rb,
lib/nonnative/reset_peer_socket_pair.rb,
lib/nonnative/configuration_readiness.rb,
lib/nonnative/invalid_data_socket_pair.rb,
lib/nonnative/configuration_service_readiness.rb

Overview

Sinatra-based HTTP forward proxy server used as an in-process Nonnative server.

The proxy receives inbound HTTP requests and forwards them to an upstream host, defaulting to HTTPS on the scheme's default port but configurable to HTTP and/or a non-default port. It returns the upstream response status, body, and safe end-to-end response headers. Hop-by-hop, connection-nominated, proxy-authentication, framing, and deferred response headers are not forwarded.

This file defines two classes:

Notes:

See Also:

Defined Under Namespace

Modules: Cucumber Classes: BandwidthSocketPair, CloseAllSocketPair, Configuration, ConfigurationFile, ConfigurationProcess, ConfigurationProxy, ConfigurationReadiness, ConfigurationRunner, ConfigurationServer, ConfigurationService, ConfigurationServiceReadiness, DelaySocketPair, Ed25519Key, Error, FaultInjectionProxy, FlakySocketPair, GRPCHealth, GRPCProbe, GRPCServer, GoExecutable, HTTPClient, HTTPProbe, HTTPProxy, HTTPProxyServer, HTTPServer, HTTPService, Header, InvalidDataSocketPair, JwtToken, LimitDataSocketPair, NoProxy, NotFoundError, Observability, Pool, Port, Ports, Process, Proxy, ProxyFactory, ResetPeerSocketPair, Runner, Server, Service, SlicerSocketPair, SocketPair, SocketPairFactory, StartError, StopError, TCPProbe, Timeout, TimeoutSocketPair, Token

Constant Summary collapse

VERSION =

The current gem version.

Returns:

  • (String)
'3.48.0'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.poolNonnative::Pool?

Returns or overrides the current runner pool (created on start).

Returns:



140
141
142
# File 'lib/nonnative.rb', line 140

def pool
  @pool
end

Class Method Details

.clearvoid

This method returns an undefined value.

Clears memoized configuration, logger, observability client, and pool.

This does not stop processes, server threads, or proxies. To reconfigure in the same Ruby process, call stop, then clear, configure the next system, and call start.



338
339
340
341
342
343
# File 'lib/nonnative.rb', line 338

def clear
  clear_logger
  clear_observability
  clear_configuration
  clear_pool
end

.clear_configurationvoid

This method returns an undefined value.

Clears the memoized configuration instance.



302
303
304
# File 'lib/nonnative.rb', line 302

def clear_configuration
  @configuration = nil
end

.clear_loggervoid

This method returns an undefined value.

Closes and clears the memoized logger instance.



309
310
311
312
313
# File 'lib/nonnative.rb', line 309

def clear_logger
  @logger&.close
ensure
  @logger = nil
end

.clear_observabilityvoid

This method returns an undefined value.

Clears the memoized observability client.



318
319
320
# File 'lib/nonnative.rb', line 318

def clear_observability
  @observability = nil
end

.clear_poolvoid

This method returns an undefined value.

Clears the memoized pool instance.

This does not stop runners owned by the pool. Call stop before clearing a live pool.



327
328
329
# File 'lib/nonnative.rb', line 327

def clear_pool
  @pool = nil
end

.configurationNonnative::Configuration

Returns the current configuration (memoized).



145
146
147
# File 'lib/nonnative.rb', line 145

def configuration
  @configuration ||= Nonnative::Configuration.new
end

.configure {|config| ... } ⇒ void

This method returns an undefined value.

Yields the configuration to a block for programmatic setup.

Examples:

Nonnative.configure do |config|
  config.name = 'my-service'
  # ...
end

Yield Parameters:



159
160
161
# File 'lib/nonnative.rb', line 159

def configure
  yield configuration
end

.go_argv(tools, output, exec, cmd, *params) ⇒ Array<String>

Builds a Go test executable argv array with optional profiling/trace/coverage flags.

Use this when passing argv entries directly to spawn.

Parameters:

  • tools (Array<String>)

    enabled tool names (e.g. ["prof", "trace", "cover"])

  • output (String)

    existing writable directory where outputs should be written

  • exec (String)

    the test binary (or wrapper) to execute

  • cmd (String)

    the command argument passed to the test binary

  • params (Array<String>)

    extra parameter strings for the command

Returns:

  • (Array<String>)

    executable argv entries



205
206
207
# File 'lib/nonnative.rb', line 205

def go_argv(tools, output, exec, cmd, *params)
  Nonnative::GoExecutable.new(tools, exec, output).argv(cmd, *params)
end

.go_command(tools, output, exec, cmd, *params) ⇒ String

Builds a Go test executable command string with optional profiling/trace/coverage flags.

Use this when passing a command string directly to spawn.

Parameters:

  • tools (Array<String>)

    enabled tool names (e.g. ["prof", "trace", "cover"])

  • output (String)

    existing writable directory where outputs should be written

  • exec (String)

    the test binary (or wrapper) to execute

  • cmd (String)

    the command argument passed to the test binary

  • params (Array<String>)

    extra parameter strings for the command

Returns:

  • (String)

    executable command string



191
192
193
# File 'lib/nonnative.rb', line 191

def go_command(tools, output, exec, cmd, *params)
  Nonnative::GoExecutable.new(tools, exec, output).command(cmd, *params)
end

.grpc_health(host:, port:, service:, timeout: 1) ⇒ Nonnative::GRPCHealth

Returns a client helper for the standard gRPC health checking protocol.

Parameters:

  • host (String)

    gRPC server host

  • port (Integer)

    gRPC server port

  • service (String, nil)

    gRPC health service name, or empty/nil for overall server health

  • timeout (Numeric) (defaults to: 1)

    default call timeout in seconds

Returns:



238
# File 'lib/nonnative.rb', line 238

def grpc_health(host:, port:, service:, timeout: 1) = Nonnative::GRPCHealth.new(host: host, port: port, service: service, timeout: timeout)

.log_lines(path, predicate) ⇒ Array<String>

Reads a file and returns only lines matching the given predicate.

Parameters:

  • path (String)

    file path to read

  • predicate (#call)

    callable that receives a line and returns truthy/falsey

Returns:

  • (Array<String>)

    matching lines



177
178
179
# File 'lib/nonnative.rb', line 177

def log_lines(path, predicate)
  File.readlines(path).select { |l| predicate.call(l) }
end

.loggerLogger

Returns the gem logger (memoized).

The logger writes to the path configured at Nonnative::Configuration#log.

Returns:

  • (Logger)


168
169
170
# File 'lib/nonnative.rb', line 168

def logger
  @logger ||= Logger.new(configuration.log)
end

.observabilityNonnative::Observability

Returns an HTTP client for common health/readiness endpoints.



229
# File 'lib/nonnative.rb', line 229

def observability = (@observability ||= Nonnative::Observability.new(configuration.url))

.proxiesHash{String=>Class}

Returns the configured proxy kinds mapped to proxy classes.

Consumers can extend this map to add custom proxy implementations.

Returns:

  • (Hash{String=>Class})


245
246
247
# File 'lib/nonnative.rb', line 245

def proxies
  @proxies ||= { 'fault_injection' => Nonnative::FaultInjectionProxy }
end

.proxy(kind) ⇒ Class

Resolves a proxy implementation for a configured kind.

nil and "none" resolve to NoProxy; any other kind must be registered in proxies.

Parameters:

  • kind (String)

    proxy kind name (for example "fault_injection")

Returns:

  • (Class)

    a subclass of Proxy

Raises:

  • (ArgumentError)

    if the kind is not "none" and has not been registered



257
258
259
# File 'lib/nonnative.rb', line 257

def proxy(kind)
  kind.nil? || kind == 'none' ? NoProxy : proxies.fetch(kind) { raise ArgumentError, "Unsupported proxy kind '#{kind}'" }
end

.resetvoid

This method returns an undefined value.

Resets proxies for all currently started runners.

No-op when called before start, since no pool exists yet.



350
351
352
# File 'lib/nonnative.rb', line 350

def reset
  Nonnative.pool&.reset
end

.startvoid

This method returns an undefined value.

Starts all configured services, servers, and processes, and waits for readiness.

Readiness is determined by port checks, plus optional process HTTP/gRPC readiness and optional service TCP readiness.

Raises:



268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/nonnative.rb', line 268

def start
  @pool ||= Nonnative::Pool.new(configuration)
  errors = []
  errors.concat(@pool.start)
  nil
rescue StandardError => e
  errors << unexpected_lifecycle_error(:start, e)
ensure
  if errors.any?
    errors.concat(rollback_start)

    raise Nonnative::StartError, errors.join("\n")
  end
end

.stopvoid

This method returns an undefined value.

Stops all configured processes and servers, then services, and waits for shutdown.

Raises:



287
288
289
290
291
292
293
294
295
296
297
# File 'lib/nonnative.rb', line 287

def stop
  errors = []
  return if @pool.nil?

  errors.concat(@pool.stop)
  nil
rescue StandardError => e
  errors << unexpected_lifecycle_error(:stop, e)
ensure
  raise Nonnative::StopError, errors.join("\n") unless errors.empty?
end

.token(kind:, issuer:, key:, private_key:, expiration:) ⇒ Nonnative::Token

Builds a token generator for authenticating against a service under test.

The signing parameters are passed in directly; this is not coupled to any service's configuration format. The generated token string is ready for Nonnative::Header.auth_bearer.

Examples:

token = Nonnative.token(kind: 'jwt', issuer: 'iss', key: 'key-1', private_key: 'config/ed25519.pem', expiration: 3600)
Nonnative::Header.auth_bearer(token.generate(aud: 'GET /v1/things', sub: 'user-1'))

Parameters:

  • kind (String)

    token kind, "jwt"

  • issuer (String)

    the iss claim

  • key (String)

    the key id (JWT kid header)

  • private_key (String)

    path to a PKCS#8 Ed25519 private key PEM file

  • expiration (Integer)

    token lifetime in seconds (drives exp)

Returns:



224
# File 'lib/nonnative.rb', line 224

def token(kind:, issuer:, key:, private_key:, expiration:) = Nonnative::Token.new(kind:, issuer:, key:, private_key:, expiration:)