Class: Nonnative::FaultInjectionProxy

Inherits:
Proxy
  • Object
show all
Defined in:
lib/nonnative/fault_injection_proxy.rb

Overview

Fault-injection proxy for TCP services.

This proxy accepts incoming TCP connections and forwards traffic to the configured upstream (‘service.proxy.host` / `service.proxy.port`) via a socket-pair implementation. It can also inject failures to help validate client resilience.

This class exposes a small public control surface for tests:

  • #close_all: close connections immediately on accept

  • #delay: delay reads by a configured duration (default: 2 seconds)

  • #invalid_data: corrupt outbound data by shuffling characters

  • #reset: return to healthy pass-through behavior

State changes terminate any active connections so new connections observe the new behavior.

## Wiring

When enabled, your test/client should connect to the runner ‘host` / `port` (the proxy endpoint), and the proxy will forward traffic to the upstream target exposed by #host:#port.

## Configuration

The proxy is configured via the runner’s ‘proxy` hash:

  • ‘kind`: `“fault_injection”`

  • ‘host` / `port`: upstream target behind the proxy (exposed via #host/#port)

  • ‘log`: file path used by this proxy’s internal logger

  • ‘wait`: sleep interval (seconds) applied after state changes

  • ‘options`:

    • ‘delay`: delay duration in seconds used by #delay

Defined Under Namespace

Classes: Connection

Instance Method Summary collapse

Constructor Details

#initialize(service) ⇒ FaultInjectionProxy

Returns a new instance of FaultInjectionProxy.

Parameters:



54
55
56
57
58
59
60
61
# File 'lib/nonnative/fault_injection_proxy.rb', line 54

def initialize(service)
  @connections = Concurrent::Hash.new
  @logger = Logger.new(service.proxy.log)
  @mutex = Mutex.new
  @state = :none

  super
end

Instance Method Details

#close_allvoid

This method returns an undefined value.

Forces new connections to be closed immediately.



98
99
100
# File 'lib/nonnative/fault_injection_proxy.rb', line 98

def close_all
  apply_state :close_all
end

#delayvoid

This method returns an undefined value.

Delays reads before forwarding.

The delay duration is controlled by ‘service.proxy.options` and defaults to 2 seconds.



107
108
109
# File 'lib/nonnative/fault_injection_proxy.rb', line 107

def delay
  apply_state :delay
end

#hostString

Returns the upstream host behind this proxy.

Returns:

  • (String)


128
129
130
# File 'lib/nonnative/fault_injection_proxy.rb', line 128

def host
  service.proxy.host
end

#invalid_datavoid

This method returns an undefined value.

Corrupts forwarded data by shuffling characters.



114
115
116
# File 'lib/nonnative/fault_injection_proxy.rb', line 114

def invalid_data
  apply_state :invalid_data
end

#portInteger

Returns the upstream port behind this proxy.

Returns:

  • (Integer)


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

def port
  service.proxy.port
end

#resetvoid

This method returns an undefined value.

Resets the proxy back to healthy pass-through behavior.



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

def reset
  apply_state :none
end

#startvoid

This method returns an undefined value.

Starts the proxy accept loop in a background thread.

This binds a TCP server on the underlying runner’s ‘service.host` / `service.port`. Clients connect to that runner endpoint, while upstream traffic is forwarded to #host:#port.



69
70
71
72
73
74
# File 'lib/nonnative/fault_injection_proxy.rb', line 69

def start
  @tcp_server = ::TCPServer.new(service.host, service.port)
  @thread = Thread.new { perform_start }

  Nonnative.logger.info "started with host '#{service.host}' and port '#{service.port}' for proxy 'fault_injection'"
end

#stopvoid

This method returns an undefined value.

Stops the proxy, closes active connections, and closes its listening socket.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/nonnative/fault_injection_proxy.rb', line 79

def stop
  mutex.synchronize do
    close_connections
  end

  server = @tcp_server
  @tcp_server = nil
  server&.close

  listener_thread = @thread
  @thread = nil
  listener_thread&.join

  Nonnative.logger.info "stopped with host '#{service.host}' and port '#{service.port}' for proxy 'fault_injection'"
end