Skip to content

Commit db97cc4

Browse files
authored
Merge pull request #4579 from DataDog/dry-webrick
DEBUG-3700 DRY webrick usage in test suite
2 parents bcdb08b + 852f3ae commit db97cc4

File tree

12 files changed

+138
-234
lines changed

12 files changed

+138
-234
lines changed

spec/datadog/core/crashtracking/component_spec.rb

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
require 'webrick'
55
require 'fiddle'
66

7+
# https://github.com/rubocop/rubocop-rspec/issues/2078
8+
# rubocop:disable RSpec/ScatteredLet
9+
710
RSpec.describe Datadog::Core::Crashtracking::Component, skip: !CrashtrackingHelpers.supported? do
811
let(:logger) { Logger.new($stdout) }
912

@@ -165,18 +168,10 @@
165168

166169
context 'integration testing' do
167170
shared_context 'HTTP server' do
168-
let(:server) do
169-
WEBrick::HTTPServer.new(
170-
Port: 0,
171-
Logger: log,
172-
AccessLog: access_log,
173-
StartCallback: -> { init_signal.push(1) }
174-
)
171+
http_server do |http_server|
172+
http_server.mount_proc('/', &server_proc)
175173
end
176174
let(:hostname) { '127.0.0.1' }
177-
let(:log) { WEBrick::Log.new(StringIO.new, WEBrick::Log::WARN) }
178-
let(:access_log_buffer) { StringIO.new }
179-
let(:access_log) { [[access_log_buffer, WEBrick::AccessLog::COMBINED_LOG_FORMAT]] }
180175
let(:server_proc) do
181176
proc do |req, res|
182177
messages << req.tap { req.body } # Read body, store message before socket closes.
@@ -186,30 +181,13 @@
186181
let(:init_signal) { Queue.new }
187182

188183
let(:messages) { [] }
189-
190-
before do
191-
server.mount_proc('/', &server_proc)
192-
@server_thread = Thread.new { server.start }
193-
init_signal.pop
194-
end
195-
196-
after do
197-
unless RSpec.current_example.skipped?
198-
# When the test is skipped, server has not been initialized and @server_thread would be nil; thus we only
199-
# want to touch them when the test actually run, otherwise we would cause the server to start (incorrectly)
200-
# and join to be called on a nil @server_thread
201-
server.shutdown
202-
@server_thread.join
203-
end
204-
end
205184
end
206185

207186
include_context 'HTTP server'
208187

209188
let(:request) { messages.first }
210-
let(:port) { server[:Port] }
211189

212-
let(:agent_base_url) { "http://#{hostname}:#{port}" }
190+
let(:agent_base_url) { "http://#{hostname}:#{http_server_port}" }
213191

214192
[:fiddle, :signal].each do |trigger|
215193
it "reports crashes via http when app crashes with #{trigger}" do
@@ -251,15 +229,14 @@
251229
let(:temporary_directory) { Dir.mktmpdir }
252230
let(:socket_path) { "#{temporary_directory}/rspec_unix_domain_socket" }
253231
let(:unix_domain_socket) { UNIXServer.new(socket_path) } # Closing the socket is handled by webrick
254-
let(:server) do
255-
server = WEBrick::HTTPServer.new(
232+
define_http_server do |http_server|
233+
http_server.listeners << unix_domain_socket
234+
http_server.mount_proc('/', &server_proc)
235+
end
236+
let(:http_server_options) do
237+
{
256238
DoNotListen: true,
257-
Logger: log,
258-
AccessLog: access_log,
259-
StartCallback: -> { init_signal.push(1) }
260-
)
261-
server.listeners << unix_domain_socket
262-
server
239+
}
263240
end
264241
let(:agent_base_url) { "unix://#{socket_path}" }
265242

@@ -340,3 +317,5 @@ def tear_down!
340317
described_class._native_stop
341318
end
342319
end
320+
321+
# rubocop:enable RSpec/ScatteredLet

spec/datadog/di/integration/probe_notifier_worker_spec.rb

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
require "datadog/di/spec_helper"
22
require 'datadog/di'
3-
require 'webrick'
43

54
# standard tries to wreck regular expressions in this fiel
65
# rubocop:disable Style/PercentLiteralDelimiters
@@ -23,55 +22,32 @@
2322
let(:settings) do
2423
Datadog::Core::Configuration::Settings.new.tap do |settings|
2524
settings.agent.host = 'localhost'
26-
settings.agent.port = test_port
25+
settings.agent.port = http_server_port
2726
settings.agent.use_ssl = false
2827
settings.agent.timeout_seconds = 1
2928
end
3029
end
3130

3231
let(:agent_settings) { Datadog::Core::Configuration::AgentSettingsResolver.call(settings, logger: nil) }
3332

34-
let(:test_port) { 48485 }
35-
3633
di_logger_double
3734

3835
let(:diagnostics_payloads) { [] }
3936
let(:input_payloads) { [] }
4037

41-
let(:server) do
42-
WEBrick::HTTPServer.new(
43-
Port: test_port,
44-
).tap do |server|
45-
@received_snapshot_count = 0
46-
@received_snapshot_bytes = 0
47-
48-
server.mount_proc('/debugger/v1/diagnostics') do |req, res|
49-
# This request is a multipart form post
50-
expect(req.content_type).to match(%r,^multipart/form-data;,)
51-
diagnostics_payloads << req.body
52-
end
53-
54-
server.mount_proc('/debugger/v1/input') do |req, res|
55-
payload = JSON.parse(req.body)
56-
input_payloads << payload
57-
end
58-
end
59-
end
38+
http_server do |http_server|
39+
@received_snapshot_count = 0
40+
@received_snapshot_bytes = 0
6041

61-
around do |example|
62-
@server_thread = Thread.new do
63-
server.start
42+
http_server.mount_proc('/debugger/v1/diagnostics') do |req, res|
43+
# This request is a multipart form post
44+
expect(req.content_type).to match(%r,^multipart/form-data;,)
45+
diagnostics_payloads << req.body
6446
end
65-
loop do
66-
break if server.status == :Running || !@server_thread.alive?
67-
sleep 0.5
68-
end
69-
expect(@server_thread).to be_alive
70-
example.run
71-
@server_thread.kill
72-
loop do
73-
break unless @server_thread.alive?
74-
sleep 0.5
47+
48+
http_server.mount_proc('/debugger/v1/input') do |req, res|
49+
payload = JSON.parse(req.body)
50+
input_payloads << payload
7551
end
7652
end
7753

spec/datadog/profiling/http_transport_spec.rb

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
require "socket"
88
require "webrick"
99

10+
# https://github.com/rubocop/rubocop-rspec/issues/2078
11+
# rubocop:disable RSpec/ScatteredLet
12+
1013
# Design note for this class's specs: from the Ruby code side, we're treating the `_native_` methods as an API
1114
# between the Ruby code and the native methods, and thus in this class we have a bunch of tests to make sure the
1215
# native methods are invoked correctly.
@@ -282,51 +285,26 @@
282285

283286
context "integration testing" do
284287
shared_context "HTTP server" do
285-
let(:server) do
286-
WEBrick::HTTPServer.new(
287-
Port: 0,
288-
Logger: log,
289-
AccessLog: access_log,
290-
StartCallback: -> { init_signal.push(1) }
291-
)
288+
http_server do |http_server|
289+
http_server.mount_proc('/', &server_proc)
292290
end
293291
let(:hostname) { "127.0.0.1" }
294-
let(:log) { WEBrick::Log.new($stderr, WEBrick::Log::WARN) }
295-
let(:access_log_buffer) { StringIO.new }
296-
let(:access_log) { [[access_log_buffer, WEBrick::AccessLog::COMBINED_LOG_FORMAT]] }
297292
let(:server_proc) do
298293
proc do |req, res|
299294
messages << req.tap { req.body } # Read body, store message before socket closes.
300295
res.body = "{}"
301296
end
302297
end
303-
let(:init_signal) { Queue.new }
304298

305299
let(:messages) { [] }
306-
307-
before do
308-
server.mount_proc("/", &server_proc)
309-
@server_thread = Thread.new { server.start }
310-
init_signal.pop
311-
end
312-
313-
after do
314-
unless RSpec.current_example.skipped?
315-
# When the test is skipped, server has not been initialized and @server_thread would be nil; thus we only
316-
# want to touch them when the test actually run, otherwise we would cause the server to start (incorrectly)
317-
# and join to be called on a nil @server_thread
318-
server.shutdown
319-
@server_thread.join
320-
end
321-
end
322300
end
323301

324302
include_context "HTTP server"
325303

326304
let(:request) { messages.first }
327305

328306
let(:hostname) { "127.0.0.1" }
329-
let(:port) { server[:Port] }
307+
let(:port) { http_server_port }
330308

331309
let!(:encoded_profile_bytes) { encoded_profile._native_bytes }
332310

@@ -416,15 +394,14 @@
416394
let(:temporary_directory) { Dir.mktmpdir }
417395
let(:socket_path) { "#{temporary_directory}/rspec_unix_domain_socket" }
418396
let(:unix_domain_socket) { UNIXServer.new(socket_path) } # Closing the socket is handled by webrick
419-
let(:server) do
420-
server = WEBrick::HTTPServer.new(
397+
define_http_server do |http_server|
398+
http_server.listeners << unix_domain_socket
399+
http_server.mount_proc('/', &server_proc)
400+
end
401+
let(:http_server_options) do
402+
{
421403
DoNotListen: true,
422-
Logger: log,
423-
AccessLog: access_log,
424-
StartCallback: -> { init_signal.push(1) }
425-
)
426-
server.listeners << unix_domain_socket
427-
server
404+
}
428405
end
429406
let(:adapter) { Datadog::Core::Transport::Ext::UnixSocket::ADAPTER }
430407
let(:uds_path) { socket_path }
@@ -440,7 +417,7 @@
440417

441418
context "when agent is down" do
442419
before do
443-
server.shutdown
420+
http_server.shutdown
444421
@server_thread.join
445422
end
446423

@@ -549,3 +526,5 @@
549526
end
550527
end
551528
end
529+
530+
# rubocop:enable RSpec/ScatteredLet

spec/datadog/tracing/contrib/ethon/integration_context.rb

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,8 @@
22
require 'spec/support/thread_helpers'
33

44
RSpec.shared_context 'integration context' do
5-
before(:all) do
6-
# TODO: Consolidate mock webserver code
7-
@log_buffer = StringIO.new # set to $stderr to debug
8-
log = WEBrick::Log.new(@log_buffer, WEBrick::Log::DEBUG)
9-
access_log = [[@log_buffer, WEBrick::AccessLog::COMBINED_LOG_FORMAT]]
10-
11-
init_signal = Queue.new
12-
server = WEBrick::HTTPServer.new(
13-
Port: 0,
14-
Logger: log,
15-
AccessLog: access_log,
16-
StartCallback: -> { init_signal.push(1) }
17-
)
18-
19-
server.mount_proc '/' do |req, res|
5+
http_server do |http_server|
6+
http_server.mount_proc '/' do |req, res|
207
sleep(0.001) if req.query['simulate_timeout']
218
res.status = (req.query['status'] || req.body['status']).to_i
229
if req.query['return_headers']
@@ -29,26 +16,12 @@
2916
res.body = 'response'
3017
end
3118
end
32-
33-
ThreadHelpers.with_leaky_thread_creation(:ethon_test_server) do
34-
@thread = Thread.new { server.start }
35-
end
36-
37-
init_signal.pop
38-
39-
@server = server
40-
@port = server[:Port]
41-
end
42-
43-
after(:all) do
44-
@server.shutdown
45-
@thread.join
4619
end
4720

4821
let(:host) { 'localhost' }
4922
let(:status) { '200' }
5023
let(:path) { '/sample/path' }
51-
let(:port) { @port }
24+
let(:port) { http_server_port }
5225
let(:method) { 'GET' }
5326
let(:simulate_timeout) { false }
5427
let(:timeout) { 5 }
@@ -59,7 +32,7 @@
5932
query[:simulate_timeout] = 'true' if simulate_timeout
6033
end
6134
let(:url) do
62-
url = "http://#{host}:#{@port}#{path}?"
35+
url = "http://#{host}:#{http_server_port}#{path}?"
6336
url += "status=#{status}&" if status
6437
url += 'return_headers=true&' if return_headers
6538
url += 'simulate_timeout=true' if simulate_timeout

spec/datadog/tracing/contrib/ethon/integration_test_spec.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
require 'json'
22
require 'stringio'
33
require 'typhoeus'
4-
require 'webrick'
54

65
require 'datadog/tracing/trace_digest'
76
require 'datadog/tracing/contrib/ethon/easy_patch'

spec/datadog/tracing/contrib/ethon/typhoeus_integration_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
context 'with concurrent Hydra requests' do
4343
include_context 'integration context'
4444

45-
let(:url_1) { "http://#{host}:#{@port}#{path}?status=200&simulate_timeout=true" }
46-
let(:url_2) { "http://#{host}:#{@port}#{path}" }
45+
let(:url_1) { "http://#{host}:#{http_server_port}#{path}?status=200&simulate_timeout=true" }
46+
let(:url_2) { "http://#{host}:#{http_server_port}#{path}" }
4747
let(:request_1) { Typhoeus::Request.new(url_1, timeout: 0.001) }
4848
let(:request_2) { Typhoeus::Request.new(url_2, method: :post, timeout: timeout, body: { status: 404 }) }
4949

spec/datadog/tracing/contrib/httpclient/instrumentation_spec.rb

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,8 @@
2020
require 'spec/support/thread_helpers'
2121

2222
RSpec.describe Datadog::Tracing::Contrib::Httpclient::Instrumentation do
23-
before(:all) do
24-
# TODO: Consolidate mock webserver code
25-
@log_buffer = StringIO.new # set to $stderr to debug
26-
log = WEBrick::Log.new(@log_buffer, WEBrick::Log::DEBUG)
27-
access_log = [[@log_buffer, WEBrick::AccessLog::COMBINED_LOG_FORMAT]]
28-
29-
server = WEBrick::HTTPServer.new(Port: 0, Logger: log, AccessLog: access_log)
30-
server.mount_proc '/' do |req, res|
23+
http_server do |http_server|
24+
http_server.mount_proc '/' do |req, res|
3125
body = JSON.parse(req.body)
3226
res.status = body['code'].to_i
3327

@@ -39,18 +33,6 @@
3933

4034
res.body = req.body
4135
end
42-
43-
ThreadHelpers.with_leaky_thread_creation(:httpclient_test_server) do
44-
@thread = Thread.new { server.start }
45-
end
46-
47-
@server = server
48-
@port = server[:Port]
49-
end
50-
51-
after(:all) do
52-
@server.shutdown
53-
@thread.join
5436
end
5537

5638
let(:configuration_options) { {} }
@@ -73,8 +55,8 @@
7355
let(:host) { 'localhost' }
7456
let(:message) { 'OK' }
7557
let(:path) { '/sample/path' }
76-
let(:port) { @port }
77-
let(:url) { "http://#{host}:#{@port}#{path}" }
58+
let(:port) { http_server_port }
59+
let(:url) { "http://#{host}:#{http_server_port}#{path}" }
7860
let(:body) { { 'message' => message, 'code' => code } }
7961
let(:headers) { { accept: 'application/json' } }
8062
let(:client) { HTTPClient.new }

0 commit comments

Comments
 (0)