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/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/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, ConfigurationRunner, ConfigurationServer, ConfigurationService, DelaySocketPair, Error, FaultInjectionProxy, GRPCServer, GoExecutable, HTTPClient, 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.2.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



117
118
119
# File 'lib/nonnative.rb', line 117

def pool
  @pool
end

Class Method Details

.clearvoid

This method returns an undefined value.

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



287
288
289
290
291
292
# File 'lib/nonnative.rb', line 287

def clear
  clear_logger
  clear_observability
  clear_configuration
  clear_pool
end

.clear_configurationvoid

This method returns an undefined value.

Clears the memoized configuration instance.



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

def clear_configuration
  @configuration = nil
end

.clear_loggervoid

This method returns an undefined value.

Closes and clears the memoized logger instance.



264
265
266
267
268
# File 'lib/nonnative.rb', line 264

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

.clear_observabilityvoid

This method returns an undefined value.

Clears the memoized observability client.



273
274
275
# File 'lib/nonnative.rb', line 273

def clear_observability
  @observability = nil
end

.clear_poolvoid

This method returns an undefined value.

Clears the memoized pool instance.



280
281
282
# File 'lib/nonnative.rb', line 280

def clear_pool
  @pool = nil
end

.configurationNonnative::Configuration

Returns the current configuration (memoized).



122
123
124
# File 'lib/nonnative.rb', line 122

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:



136
137
138
# File 'lib/nonnative.rb', line 136

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



182
183
184
# File 'lib/nonnative.rb', line 182

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



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

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



154
155
156
# File 'lib/nonnative.rb', line 154

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)


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

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

.observabilityNonnative::Observability

Returns an HTTP client for common health/readiness endpoints.



189
190
191
# File 'lib/nonnative.rb', line 189

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


198
199
200
# File 'lib/nonnative.rb', line 198

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



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

def proxy(kind)
  Nonnative.proxies[kind] || Nonnative::NoProxy
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)



298
299
300
# File 'lib/nonnative.rb', line 298

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:



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

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



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/nonnative.rb', line 238

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

  errors.concat(@pool.stop do |name, values, result|
    id, stopped = Array(values).then { |v| [v.first, v.fetch(1, true)] }
    errors << "Stopped #{name} with id #{id}, though did not respond in time" 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