Class: Maze::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/maze/server.rb

Overview

Receives and stores requests through a WEBrick HTTPServer

Constant Summary collapse

ALLOWED_HTTP_VERBS =
%w[OPTIONS GET POST PUT DELETE HEAD TRACE PATCH CONNECT]
DEFAULT_RESPONSE_DELAY =
0
DEFAULT_SAMPLING_PROBABILITY =
1
DEFAULT_STATUS_CODE =
200

Class Method Summary collapse

Class Method Details

.buildsRequestList

A list of build requests received

Returns:



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

def builds
  @builds ||= RequestList.new
end

.commandsRequestList

A list of commands for a test fixture to perform. Strictly speaking these are responses to HTTP requests, but the list behavior is all we need.

Returns:



179
180
181
# File 'lib/maze/server.rb', line 179

def commands
  @commands ||= RequestList.new
end

.errorsRequestList

A list of error requests received

Returns:



108
109
110
# File 'lib/maze/server.rb', line 108

def errors
  @errors ||= RequestList.new
end

.invalid_requestsRequestList

Whether the server thread is running An array of any invalid requests received. Each request is hash consisting of:

request: The original HTTPRequest object
reason: Reason for being considered invalid. Examples include invalid JSON and missing/invalid digest.

Returns:



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

def invalid_requests
  @invalid_requests ||= RequestList.new
end

.list_for(type) ⇒ Object

Provides dynamic access to request lists by name

Parameters:

  • type (String, Symbol)

    Request type

Returns:

  • Request list for the type given



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/maze/server.rb', line 75

def list_for(type)
  type = type.to_s
  case type
  when 'error', 'errors'
    errors
  when 'session', 'sessions'
    sessions
  when 'build', 'builds'
    builds
  when 'log', 'logs'
    logs
  when 'metric', 'metrics'
    metrics
  when 'sampling request', 'sampling requests'
    sampling_requests
  when 'trace', 'traces'
    traces
  when 'upload', 'uploads'
    uploads
  when 'sourcemap', 'sourcemaps'
    sourcemaps
  when 'reflect', 'reflects', 'reflection', 'reflections'
    reflections
  when 'invalid', 'invalid requests'
    invalid_requests
  else
    raise "Invalid request type '#{type}'"
  end
end

.logsRequestList

A list of log requests received

Returns:



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

def logs
  @logs ||= RequestList.new
end

.metricsRequestList

A list of metric requests received

Returns:



164
165
166
# File 'lib/maze/server.rb', line 164

def metrics
  @metrics ||= RequestList.new
end

.reflectionsRequestList

A list of reflection requests received

Returns:



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

def reflections
  @reflections ||= RequestList.new
end

.reset!Object



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/maze/server.rb', line 267

def reset!
  # Reset generators
  set_response_delay_generator(Maze::Generator.new [DEFAULT_RESPONSE_DELAY].cycle)
  set_status_code_generator(Maze::Generator.new [DEFAULT_STATUS_CODE].cycle)
  set_sampling_probability_generator(Maze::Generator.new [DEFAULT_SAMPLING_PROBABILITY].cycle)

  # Clear request lists
  commands.clear
  errors.clear
  sessions.clear
  builds.clear
  uploads.clear
  sourcemaps.clear
  sampling_requests.clear
  traces.clear
  logs.clear
  invalid_requests.clear
  reflections.clear
end

.response_delay_msObject



67
68
69
# File 'lib/maze/server.rb', line 67

def response_delay_ms
  @response_delay_generator.next
end

.running?Boolean

Whether the server thread is running

Returns:

  • (Boolean)

    If the server is running



196
197
198
# File 'lib/maze/server.rb', line 196

def running?
  @thread&.alive?
end

.sampling_probabilityObject



63
64
65
# File 'lib/maze/server.rb', line 63

def sampling_probability
  @sampling_probability_generator.next
end

.sampling_requestsRequestList

A list of sampling requests received

Returns:



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

def sampling_requests
  @sampling_requests ||= RequestList.new
end

.sessionsRequestList

A list of session requests received

Returns:



115
116
117
# File 'lib/maze/server.rb', line 115

def sessions
  @sessions ||= RequestList.new
end

.set_response_delay_generator(generator) ⇒ Object

Sets the response delay generator.

Parameters:



21
22
23
24
# File 'lib/maze/server.rb', line 21

def set_response_delay_generator(generator)
  @response_delay_generator&.close
  @response_delay_generator = generator
end

.set_sampling_probability_generator(generator) ⇒ Object

Sets the sampling probability generator.

Parameters:



29
30
31
32
# File 'lib/maze/server.rb', line 29

def set_sampling_probability_generator(generator)
  @sampling_probability_generator&.close
  @sampling_probability_generator = generator
end

.set_status_code_generator(generator, verb = nil) ⇒ Object

Sets the status code generator for the HTTP verb given. If no verb is given then the generator will be shared across all allowable HTTP verbs.

Parameters:

  • generator (Maze::Generator)

    The new generator

  • verb (String) (defaults to: nil)

    HTTP verb



39
40
41
42
43
44
45
46
47
48
# File 'lib/maze/server.rb', line 39

def set_status_code_generator(generator, verb = nil)
  @status_code_generators ||= {}
  Array(verb || ALLOWED_HTTP_VERBS).each do |verb|
    old = @status_code_generators[verb]
    @status_code_generators[verb] = generator

    # Close the old generator unless it's still being used by another verb
    old&.close unless @status_code_generators.value?(old)
  end
end

.sourcemapsRequestList

A list of sourcemap requests received

Returns:



150
151
152
# File 'lib/maze/server.rb', line 150

def sourcemaps
  @sourcemaps ||= RequestList.new
end

.startObject

Starts the WEBrick server in a separate thread



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/maze/server.rb', line 201

def start
  attempts = 0
  loop do

    @thread = Thread.new do
      options = {
          Port: Maze.config.port,
          Logger: $logger,
          AccessLog: []
      }
      options[:BindAddress] = Maze.config.bind_address unless Maze.config.bind_address.nil?
      server = WEBrick::HTTPServer.new(options)

      # Mount a block to respond to all requests with status:200
      server.mount_proc '/' do |_request, response|
        $logger.trace 'Received request on server root, responding with 200'
        response.header['Access-Control-Allow-Origin'] = '*'
        response.body = 'Maze runner received request'
        response.status = 200
      end

      # When adding more endpoints, be sure to update the 'I should receive no requests' step
      server.mount '/notify', Servlets::Servlet, :errors
      server.mount '/sessions', Servlets::Servlet, :sessions
      server.mount '/builds', Servlets::Servlet, :builds
      server.mount '/uploads', Servlets::Servlet, :uploads
      server.mount '/traces', Servlets::TraceServlet, :traces, Maze::Schemas::TRACE_SCHEMA
      server.mount '/sourcemap', Servlets::Servlet, :sourcemaps
      server.mount '/react-native-source-map', Servlets::Servlet, :sourcemaps
      server.mount '/dart-symbol', Servlets::Servlet, :sourcemaps
      server.mount '/ndk-symbol', Servlets::Servlet, :sourcemaps
      server.mount '/proguard', Servlets::Servlet, :sourcemaps
      server.mount '/dsym', Servlets::Servlet, :sourcemaps
      server.mount '/command', Servlets::CommandServlet
      server.mount '/commands', Servlets::AllCommandsServlet
      server.mount '/logs', Servlets::LogServlet
      server.mount '/metrics', Servlets::Servlet, :metrics
      server.mount '/reflect', Servlets::ReflectiveServlet
      server.start
    rescue StandardError => e
      Bugsnag.notify e
      $logger.warn "Failed to start mock server: #{e.message}"
    ensure
      server&.shutdown
    end

    # Need a short sleep here as a dying thread is still alive momentarily
    sleep 1
    break if running?

    # Bail out after 3 attempts
    attempts += 1
    raise 'Too many failed attempts to start mock server' if attempts == 3

    # Failed to start - sleep before retrying
    $logger.info 'Retrying in 5 seconds'
    sleep 5
  end
end

.status_code(verb) ⇒ Integer

The intended HTTP status code on a successful request

Parameters:

  • verb (String)

    HTTP verb for which the status code is wanted

Returns:

  • (Integer)

    The HTTP status code for the verb given



55
56
57
58
59
60
61
# File 'lib/maze/server.rb', line 55

def status_code(verb)
  if @status_code_generators[verb].nil? || @status_code_generators[verb].closed?
    DEFAULT_STATUS_CODE
  else
    @status_code_generators[verb].next
  end
end

.stopObject

Stops the WEBrick server thread if it’s running



262
263
264
265
# File 'lib/maze/server.rb', line 262

def stop
  @thread&.kill if @thread&.alive?
  @thread = nil
end

.tracesRequestList

A list of trace requests received

Returns:



129
130
131
# File 'lib/maze/server.rb', line 129

def traces
  @traces ||= RequestList.new
end

.uploadsRequestList

A list of upload requests received

Returns:



143
144
145
# File 'lib/maze/server.rb', line 143

def uploads
  @uploads ||= RequestList.new
end