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/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/http_probe.rb,
lib/nonnative/stop_error.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/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/http_proxy_server.rb,
lib/nonnative/configuration_file.rb,
lib/nonnative/configuration_proxy.rb,
lib/nonnative/socket_pair_factory.rb,
lib/nonnative/configuration_runner.rb,
lib/nonnative/configuration_server.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/configuration_readiness.rb,
lib/nonnative/invalid_data_socket_pair.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 over HTTPS, returning the upstream response status and body.

This file defines two classes:

Notes:

See Also:

Defined Under Namespace

Modules: Cucumber Classes: CloseAllSocketPair, Configuration, ConfigurationFile, ConfigurationProcess, ConfigurationProxy, ConfigurationReadiness, ConfigurationRunner, ConfigurationServer, ConfigurationService, DelaySocketPair, Error, FaultInjectionProxy, GRPCServer, GoExecutable, HTTPClient, HTTPProbe, HTTPProxy, HTTPProxyServer, HTTPServer, Header, InvalidDataSocketPair, NoProxy, NotFoundError, Observability, Pool, Port, Ports, Process, Proxy, ProxyFactory, Runner, Server, Service, SocketPair, SocketPairFactory, StartError, StopError, Timeout

Constant Summary collapse

VERSION =

The current gem version.

Returns:

  • (String)
'3.9.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:

  • (Nonnative::Pool, nil)

    the pool instance, or ‘nil` if not started yet



120
121
122
# File 'lib/nonnative.rb', line 120

def pool
  @pool
end

Class Method Details

.clearvoid

This method returns an undefined value.

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



290
291
292
293
294
295
# File 'lib/nonnative.rb', line 290

def clear
  clear_logger
  clear_observability
  clear_configuration
  clear_pool
end

.clear_configurationvoid

This method returns an undefined value.

Clears the memoized configuration instance.



260
261
262
# File 'lib/nonnative.rb', line 260

def clear_configuration
  @configuration = nil
end

.clear_loggervoid

This method returns an undefined value.

Closes and clears the memoized logger instance.



267
268
269
270
271
# File 'lib/nonnative.rb', line 267

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

.clear_observabilityvoid

This method returns an undefined value.

Clears the memoized observability client.



276
277
278
# File 'lib/nonnative.rb', line 276

def clear_observability
  @observability = nil
end

.clear_poolvoid

This method returns an undefined value.

Clears the memoized pool instance.



283
284
285
# File 'lib/nonnative.rb', line 283

def clear_pool
  @pool = nil
end

.configurationNonnative::Configuration

Returns the current configuration (memoized).



125
126
127
# File 'lib/nonnative.rb', line 125

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:



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

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)

    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



185
186
187
# File 'lib/nonnative.rb', line 185

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)

    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



171
172
173
# File 'lib/nonnative.rb', line 171

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

.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



157
158
159
# File 'lib/nonnative.rb', line 157

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)


148
149
150
# File 'lib/nonnative.rb', line 148

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

.observabilityNonnative::Observability

Returns an HTTP client for common health/readiness endpoints.



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

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

.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})


201
202
203
# File 'lib/nonnative.rb', line 201

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

.proxy(kind) ⇒ Class

Resolves a proxy implementation for a configured kind.

Parameters:

  • kind (String)

    proxy kind name (for example ‘“fault_injection”`)

Returns:

  • (Class)

    a subclass of Proxy



209
210
211
# File 'lib/nonnative.rb', line 209

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.

Raises:

  • (NoMethodError)

    if called before start (because pool is nil)



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

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 attempting to connect to each runner’s configured host/ports.

Raises:



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/nonnative.rb', line 219

def start
  @pool ||= Nonnative::Pool.new(configuration)
  errors = []
  errors.concat(@pool.start do |name, values, result, ports|
    id, started = values
    errors << "Started #{name} with id #{id}, though did not respond in time for #{ports.description}" if !started || !result
  end)
  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:



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/nonnative.rb', line 241

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

  errors.concat(@pool.stop do |name, values, result, ports|
    id, stopped = Array(values).then { |v| [v.first, v.fetch(1, true)] }
    errors << "Stopped #{name} with id #{id}, though did not respond in time for #{ports.description}" unless result
    errors << "Stopped #{name} with id #{id}, though the process did not exit in time" unless stopped
  end)
  nil
rescue StandardError => e
  errors << unexpected_lifecycle_error(:stop, e)
ensure
  raise Nonnative::StopError, errors.join("\n") unless errors.empty?
end