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 Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.last_command_uuidString

Records the previous command UUID sent to the test fixture

Returns:

  • (String)

    The UUID of the last command sent



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

def last_command_uuid
  @last_command_uuid
end

Class Method Details

.buildsRequestList

A list of build requests received

Returns:



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

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:



187
188
189
# File 'lib/maze/server.rb', line 187

def commands
  @commands ||= RequestList.new
end

.errorsRequestList

A list of error requests received

Returns:



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

def errors
  @errors ||= RequestList.new
end

.ignored_requestsObject



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

def ignored_requests
  @ignored_requests ||= 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:



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

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



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/maze/server.rb', line 81

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 'ignored', 'ignored requests'
    ignored_requests
  when 'invalid', 'invalid requests'
    invalid_requests
  else
    raise "Invalid request type '#{type}'"
  end
end

.logsRequestList

A list of log requests received

Returns:



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

def logs
  @logs ||= RequestList.new
end

.metricsRequestList

A list of metric requests received

Returns:



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

def metrics
  @metrics ||= RequestList.new
end

.reflectionsRequestList

A list of reflection requests received

Returns:



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

def reflections
  @reflections ||= RequestList.new
end

.reset!Object



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/maze/server.rb', line 290

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
  ignored_requests.clear
  invalid_requests.clear
  reflections.clear
end

.response_delay_msObject



73
74
75
# File 'lib/maze/server.rb', line 73

def response_delay_ms
  @response_delay_generator.next
end

.running?Boolean

Whether the server thread is running

Returns:

  • (Boolean)

    If the server is running



208
209
210
# File 'lib/maze/server.rb', line 208

def running?
  @thread&.alive?
end

.sampling_probabilityObject



69
70
71
# File 'lib/maze/server.rb', line 69

def sampling_probability
  @sampling_probability_generator.next
end

.sampling_requestsRequestList

A list of sampling requests received

Returns:



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

def sampling_requests
  @sampling_requests ||= RequestList.new
end

.sessionsRequestList

A list of session requests received

Returns:



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

def sessions
  @sessions ||= RequestList.new
end

.set_response_delay_generator(generator) ⇒ Object

Sets the response delay generator.

Parameters:



27
28
29
30
# File 'lib/maze/server.rb', line 27

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:



35
36
37
38
# File 'lib/maze/server.rb', line 35

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



45
46
47
48
49
50
51
52
53
54
# File 'lib/maze/server.rb', line 45

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:



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

def sourcemaps
  @sourcemaps ||= RequestList.new
end

.startObject

Starts the WEBrick server in a separate thread



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
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/maze/server.rb', line 213

def start
  attempts = 0
  loop do

    @thread = Thread.new do

      options = {
        Port: Maze.config.port,
        Logger: $logger,
        AccessLog: []
      }
      # SSL config if enabled
      if Maze.config.https
        cert_name = [
          %w[CN localhost],
        ]
        options[:SSLEnable] = true
        options[:SSLCertName] = cert_name
      end
      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.mount '/docs', WEBrick::HTTPServlet::FileHandler, Maze.config.document_server_root unless Maze.config.document_server_root.nil?

      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



61
62
63
64
65
66
67
# File 'lib/maze/server.rb', line 61

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



285
286
287
288
# File 'lib/maze/server.rb', line 285

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

.tracesRequestList

A list of trace requests received

Returns:



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

def traces
  @traces ||= RequestList.new
end

.uploadsRequestList

A list of upload requests received

Returns:



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

def uploads
  @uploads ||= RequestList.new
end