appsignal 3.9.3-java → 3.11.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +22 -19
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +180 -0
  5. data/Gemfile +1 -0
  6. data/README.md +0 -1
  7. data/Rakefile +1 -1
  8. data/benchmark.rake +99 -42
  9. data/build_matrix.yml +10 -12
  10. data/gemfiles/webmachine1.gemfile +5 -4
  11. data/lib/appsignal/cli/demo.rb +0 -1
  12. data/lib/appsignal/config.rb +57 -97
  13. data/lib/appsignal/demo.rb +15 -20
  14. data/lib/appsignal/environment.rb +6 -1
  15. data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
  16. data/lib/appsignal/event_formatter.rb +3 -2
  17. data/lib/appsignal/helpers/instrumentation.rb +490 -16
  18. data/lib/appsignal/hooks/action_cable.rb +21 -16
  19. data/lib/appsignal/hooks/active_job.rb +15 -14
  20. data/lib/appsignal/hooks/delayed_job.rb +1 -1
  21. data/lib/appsignal/hooks/shoryuken.rb +3 -63
  22. data/lib/appsignal/integrations/action_cable.rb +5 -7
  23. data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
  24. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
  25. data/lib/appsignal/integrations/data_mapper.rb +1 -0
  26. data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
  27. data/lib/appsignal/integrations/dry_monitor.rb +1 -0
  28. data/lib/appsignal/integrations/excon.rb +1 -0
  29. data/lib/appsignal/integrations/http.rb +1 -0
  30. data/lib/appsignal/integrations/net_http.rb +1 -0
  31. data/lib/appsignal/integrations/object.rb +6 -0
  32. data/lib/appsignal/integrations/padrino.rb +21 -25
  33. data/lib/appsignal/integrations/que.rb +13 -20
  34. data/lib/appsignal/integrations/railtie.rb +1 -1
  35. data/lib/appsignal/integrations/rake.rb +45 -15
  36. data/lib/appsignal/integrations/redis.rb +1 -0
  37. data/lib/appsignal/integrations/redis_client.rb +1 -0
  38. data/lib/appsignal/integrations/resque.rb +2 -5
  39. data/lib/appsignal/integrations/shoryuken.rb +75 -0
  40. data/lib/appsignal/integrations/sidekiq.rb +7 -25
  41. data/lib/appsignal/integrations/unicorn.rb +1 -0
  42. data/lib/appsignal/integrations/webmachine.rb +12 -9
  43. data/lib/appsignal/logger.rb +7 -3
  44. data/lib/appsignal/probes/helpers.rb +1 -0
  45. data/lib/appsignal/probes/mri.rb +1 -0
  46. data/lib/appsignal/probes/sidekiq.rb +1 -0
  47. data/lib/appsignal/probes.rb +3 -0
  48. data/lib/appsignal/rack/abstract_middleware.rb +67 -24
  49. data/lib/appsignal/rack/body_wrapper.rb +143 -0
  50. data/lib/appsignal/rack/event_handler.rb +39 -8
  51. data/lib/appsignal/rack/generic_instrumentation.rb +6 -4
  52. data/lib/appsignal/rack/grape_middleware.rb +3 -2
  53. data/lib/appsignal/rack/hanami_middleware.rb +1 -1
  54. data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
  55. data/lib/appsignal/rack/rails_instrumentation.rb +1 -3
  56. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
  57. data/lib/appsignal/rack/streaming_listener.rb +14 -59
  58. data/lib/appsignal/rack.rb +60 -0
  59. data/lib/appsignal/span.rb +1 -0
  60. data/lib/appsignal/transaction.rb +353 -104
  61. data/lib/appsignal/utils/data.rb +0 -1
  62. data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
  63. data/lib/appsignal/utils/integration_logger.rb +0 -13
  64. data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
  65. data/lib/appsignal/utils/json.rb +0 -1
  66. data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
  67. data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
  68. data/lib/appsignal/utils.rb +6 -0
  69. data/lib/appsignal/version.rb +1 -1
  70. data/lib/appsignal.rb +9 -6
  71. data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
  72. data/spec/lib/appsignal/config_spec.rb +139 -43
  73. data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
  74. data/spec/lib/appsignal/hooks/activejob_spec.rb +9 -0
  75. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
  76. data/spec/lib/appsignal/hooks/rake_spec.rb +100 -17
  77. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
  78. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
  79. data/spec/lib/appsignal/integrations/padrino_spec.rb +181 -131
  80. data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
  81. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
  82. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -4
  83. data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -2
  84. data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -17
  85. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +144 -11
  86. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
  87. data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -10
  88. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -17
  89. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +1 -1
  90. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
  91. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
  92. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +43 -120
  93. data/spec/lib/appsignal/rack_spec.rb +63 -0
  94. data/spec/lib/appsignal/transaction_spec.rb +1675 -953
  95. data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
  96. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
  97. data/spec/lib/appsignal_spec.rb +517 -13
  98. data/spec/support/helpers/transaction_helpers.rb +44 -20
  99. data/spec/support/matchers/transaction.rb +15 -1
  100. data/spec/support/mocks/dummy_app.rb +1 -1
  101. data/spec/support/testing.rb +1 -1
  102. metadata +12 -4
  103. data/support/check_versions +0 -22
@@ -3,8 +3,11 @@ describe Appsignal::Rack::EventHandler do
3
3
  let(:env) do
4
4
  {
5
5
  "HTTP_X_REQUEST_START" => "t=#{queue_start_time.to_i}", # in milliseconds
6
- "REQUEST_METHOD" => "GET",
7
- "PATH_INFO" => "/path"
6
+ "REQUEST_METHOD" => "POST",
7
+ "PATH_INFO" => "/path",
8
+ "QUERY_STRING" => "query_param1=value1&query_param2=value2",
9
+ "rack.session" => { "session1" => "value1", "session2" => "value2" },
10
+ "rack.input" => StringIO.new("post_param1=value1&post_param2=value2")
8
11
  }
9
12
  end
10
13
  let(:request) { Rack::Request.new(env) }
@@ -172,20 +175,93 @@ describe Appsignal::Rack::EventHandler do
172
175
  expect(last_transaction).to_not be_completed
173
176
  end
174
177
 
175
- it "completes the transaction" do
178
+ it "sets params on the transaction" do
179
+ on_start
180
+ on_finish
181
+
182
+ expect(last_transaction).to include_params(
183
+ "query_param1" => "value1",
184
+ "query_param2" => "value2",
185
+ "post_param1" => "value1",
186
+ "post_param2" => "value2"
187
+ )
188
+ end
189
+
190
+ it "sets headers on the transaction" do
176
191
  on_start
177
192
  on_finish
178
193
 
179
- expect(last_transaction).to_not have_action
180
194
  expect(last_transaction).to include_environment(
181
- "REQUEST_METHOD" => "GET",
195
+ "REQUEST_METHOD" => "POST",
182
196
  "PATH_INFO" => "/path"
183
197
  )
198
+ end
199
+
200
+ it "sets session data on the transaction" do
201
+ on_start
202
+ on_finish
203
+
204
+ expect(last_transaction).to include_session_data(
205
+ "session1" => "value1",
206
+ "session2" => "value2"
207
+ )
208
+ end
209
+
210
+ it "sets the queue start time on the transaction" do
211
+ on_start
212
+ on_finish
213
+
184
214
  expect(last_transaction).to have_queue_start(queue_start_time)
215
+ end
216
+
217
+ it "completes the transaction" do
218
+ on_start
219
+ on_finish
220
+
221
+ expect(last_transaction).to_not have_action
185
222
  expect(last_transaction).to be_completed
186
223
  end
187
224
 
188
225
  context "without a response" do
226
+ it "sets params on the transaction" do
227
+ on_start
228
+ on_finish
229
+
230
+ expect(last_transaction).to include_params(
231
+ "query_param1" => "value1",
232
+ "query_param2" => "value2",
233
+ "post_param1" => "value1",
234
+ "post_param2" => "value2"
235
+ )
236
+ end
237
+
238
+ it "sets headers on the transaction" do
239
+ on_start
240
+ on_finish
241
+
242
+ expect(last_transaction).to include_environment(
243
+ "REQUEST_METHOD" => "POST",
244
+ "PATH_INFO" => "/path"
245
+ )
246
+ end
247
+
248
+ it "sets session data on the transaction" do
249
+ on_start
250
+ on_finish
251
+
252
+ expect(last_transaction).to include_session_data(
253
+ "session1" => "value1",
254
+ "session2" => "value2"
255
+ )
256
+ end
257
+
258
+ it "sets the queue start time on the transaction" do
259
+ on_start
260
+ on_finish
261
+
262
+ expect(last_transaction).to have_queue_start(queue_start_time)
263
+ end
264
+
189
265
  it "completes the transaction" do
190
266
  on_start
191
267
  on_finish(request, nil)
@@ -193,11 +269,6 @@ describe Appsignal::Rack::EventHandler do
193
269
  # The action is not set on purpose, as we can't set a normalized route
194
270
  # It requires the app to set an action name
195
271
  expect(last_transaction).to_not have_action
196
- expect(last_transaction).to include_environment(
197
- "REQUEST_METHOD" => "GET",
198
- "PATH_INFO" => "/path"
199
- )
200
- expect(last_transaction).to have_queue_start(queue_start_time)
201
272
  expect(last_transaction).to be_completed
202
273
  end
203
274
 
@@ -1,28 +1,81 @@
1
- describe Appsignal::Rack::GenericInstrumentation do
2
- let(:app) { double(:call => true) }
3
- let(:env) { Rack::MockRequest.env_for("/some/path") }
4
- let(:middleware) { Appsignal::Rack::GenericInstrumentation.new(app, {}) }
1
+ describe "Appsignal::Rack::GenericInstrumentation" do
2
+ describe "Appsignal::Rack::GenericInstrumentation constant" do
3
+ let(:err_stream) { std_stream }
4
+ let(:stderr) { err_stream.read }
5
+ before do
6
+ if Appsignal::Rack.const_defined?(:GenericInstrumentation)
7
+ hide_const "Appsignal::Rack::GenericInstrumentation"
8
+ end
9
+ end
10
+
11
+ it "returns the Rack::GenericInstrumentation constant" do
12
+ silence do
13
+ expect(Appsignal::Rack::GenericInstrumentation)
14
+ .to be(Appsignal::Rack::GenericInstrumentationAlias)
15
+ end
16
+ end
5
17
 
6
- before(:context) { start_agent }
7
- around { |example| keep_transactions { example.run } }
18
+ it "prints a deprecation warning to STDERR" do
19
+ capture_std_streams(std_stream, err_stream) do
20
+ Appsignal::Rack::GenericInstrumentation
21
+ end
8
22
 
9
- def make_request(env)
10
- middleware.call(env)
11
- end
23
+ expect(stderr).to include(
24
+ "appsignal WARNING: The constant Appsignal::Rack::GenericInstrumentation " \
25
+ "has been deprecated."
26
+ )
27
+ end
12
28
 
13
- context "without an exception" do
14
- it "reports a process_action.generic event" do
15
- make_request(env)
29
+ it "logs a warning" do
30
+ logs =
31
+ capture_logs do
32
+ silence do
33
+ Appsignal::Rack::GenericInstrumentation
34
+ end
35
+ end
16
36
 
17
- expect(last_transaction).to include_event("name" => "process_action.generic")
37
+ expect(logs).to contains_log(
38
+ :warn,
39
+ "The constant Appsignal::Rack::GenericInstrumentation has been deprecated."
40
+ )
18
41
  end
19
42
  end
20
43
 
21
- context "without action name metadata" do
22
- it "reports 'unknown' as the action name" do
23
- make_request(env)
44
+ describe "middleware" do
45
+ let(:app) { double(:call => true) }
46
+ let(:env) { Rack::MockRequest.env_for("/some/path") }
47
+ let(:middleware) { Appsignal::Rack::GenericInstrumentation.new(app, {}) }
48
+
49
+ before(:context) { start_agent }
50
+ around { |example| keep_transactions { example.run } }
51
+
52
+ def make_request(env)
53
+ middleware.call(env)
54
+ end
55
+
56
+ context "without an exception" do
57
+ it "reports a process_action.generic event" do
58
+ make_request(env)
59
+
60
+ expect(last_transaction).to include_event("name" => "process_action.generic")
61
+ end
62
+ end
63
+
64
+ context "with action name env" do
65
+ it "reports the appsignal.action env as the action name" do
66
+ env["appsignal.action"] = "MyAction"
67
+ make_request(env)
68
+
69
+ expect(last_transaction).to have_action("MyAction")
70
+ end
71
+ end
72
+
73
+ context "without action name metadata" do
74
+ it "reports 'unknown' as the action name" do
75
+ make_request(env)
24
76
 
25
- expect(last_transaction).to have_action("unknown")
77
+ expect(last_transaction).to have_action("unknown")
78
+ end
26
79
  end
27
80
  end
28
81
  end
@@ -5,7 +5,7 @@ if DependencyHelper.grape_present?
5
5
  let(:err_stream) { std_stream }
6
6
  let(:stderr) { err_stream.read }
7
7
 
8
- it "returns the Probes constant calling the Minutely constant" do
8
+ it "returns the Rack::GrapeMiddleware constant calling the Grape::Middleware constant" do
9
9
  silence { expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware) }
10
10
  end
11
11
 
@@ -0,0 +1,38 @@
1
+ describe Appsignal::Rack::InstrumentationMiddleware do
2
+ let(:app) { DummyApp.new }
3
+ let(:env) { Rack::MockRequest.env_for("/some/path") }
4
+ let(:middleware) { described_class.new(app, {}) }
5
+
6
+ before { start_agent }
7
+ around { |example| keep_transactions { example.run } }
8
+
9
+ def make_request(env)
10
+ middleware.call(env)
11
+ end
12
+
13
+ context "without an exception" do
14
+ it "reports a process_request_middleware.rack event" do
15
+ make_request(env)
16
+
17
+ expect(last_transaction).to include_event("name" => "process_request_middleware.rack")
18
+ end
19
+ end
20
+
21
+ context "with custom action name" do
22
+ let(:app) { DummyApp.new { |_env| Appsignal.set_action("MyAction") } }
23
+
24
+ it "reports the custom action name" do
25
+ make_request(env)
26
+
27
+ expect(last_transaction).to have_action("MyAction")
28
+ end
29
+ end
30
+
31
+ context "without action name metadata" do
32
+ it "reports no action name" do
33
+ make_request(env)
34
+
35
+ expect(last_transaction).to_not have_action
36
+ end
37
+ end
38
+ end
@@ -114,8 +114,10 @@ if DependencyHelper.rails_present?
114
114
  make_request
115
115
 
116
116
  expect(last_transaction).to_not include_metadata("method" => anything)
117
- expect(log_contents(log))
118
- .to contains_log(:error, "Unable to report HTTP request method: '")
117
+ expect(log_contents(log)).to contains_log(
118
+ :error,
119
+ "Exception while fetching the HTTP request method: "
120
+ )
119
121
  end
120
122
  end
121
123
 
@@ -1,146 +1,69 @@
1
- require "appsignal/rack/streaming_listener"
2
-
3
- describe Appsignal::Rack::StreamingListener do
4
- let(:env) do
5
- {
6
- "rack.input" => StringIO.new,
7
- "REQUEST_METHOD" => "GET",
8
- "PATH_INFO" => "/homepage",
9
- "QUERY_STRING" => "param=something"
10
- }
1
+ describe "Appsignal::Rack::StreamingListener" do
2
+ def load_middleware
3
+ load "lib/appsignal/rack/streaming_listener.rb"
11
4
  end
12
- let(:app) { DummyApp.new }
13
- let(:listener) { Appsignal::Rack::StreamingListener.new(app, {}) }
14
- before(:context) { start_agent }
15
- around { |example| keep_transactions { example.run } }
16
5
 
17
- describe "#call" do
18
- context "when Appsignal is not active" do
19
- before { allow(Appsignal).to receive(:active?).and_return(false) }
6
+ describe "loading the streaming_listener integrations file" do
7
+ let(:err_stream) { std_stream }
8
+ let(:stderr) { err_stream.read }
9
+ after { Appsignal::Rack.send(:remove_const, :StreamingListener) }
20
10
 
21
- it "does not create a transaction" do
22
- expect do
23
- listener.call(env)
24
- end.to_not(change { created_transactions.count })
11
+ it "prints a deprecation warning to STDERR" do
12
+ capture_std_streams(std_stream, err_stream) do
13
+ load_middleware
25
14
  end
26
15
 
27
- it "calls the app" do
28
- listener.call(env)
29
-
30
- expect(app).to be_called
31
- end
16
+ expect(stderr).to include(
17
+ "appsignal WARNING: The constant Appsignal::Rack::StreamingListener " \
18
+ "has been deprecated."
19
+ )
32
20
  end
33
21
 
34
- context "when Appsignal is active" do
35
- before { allow(Appsignal).to receive(:active?).and_return(true) }
36
-
37
- let(:wrapper) { Appsignal::StreamWrapper.new("body", transaction) }
38
- let(:raw_payload) { { :foo => :bar } }
39
- before { allow(listener).to receive(:raw_payload).and_return(raw_payload) }
40
-
41
- it "creates a transaction" do
42
- expect do
43
- listener.call(env)
44
- end.to(change { created_transactions.count }.by(1))
45
- end
46
-
47
- it "instruments the call" do
48
- listener.call(env)
49
-
50
- expect(last_transaction).to include_event("name" => "process_action.rack")
51
- end
52
-
53
- it "set `appsignal.action` to the action name" do
54
- env["appsignal.action"] = "Action"
55
-
56
- listener.call(env)
57
-
58
- expect(last_transaction).to have_action("Action")
59
- end
60
-
61
- it "adds the path, method and queue start to the transaction" do
62
- listener.call(env)
63
-
64
- expect(last_transaction).to include_metadata(
65
- "path" => "/homepage",
66
- "method" => "GET"
67
- )
68
- expect(last_transaction).to have_queue_start
69
- end
70
-
71
- context "with an exception in the instrumentation call" do
72
- let(:error) { ExampleException.new("error message") }
73
- let(:app) { DummyApp.new { raise error } }
74
-
75
- it "adds the exception to the transaction" do
76
- expect do
77
- listener.call(env)
78
- end.to raise_error(error)
79
-
80
- expect(last_transaction).to have_error("ExampleException", "error message")
22
+ it "logs a warning" do
23
+ logs =
24
+ capture_logs do
25
+ silence do
26
+ load_middleware
27
+ end
81
28
  end
82
- end
83
29
 
84
- it "wraps the body in a wrapper" do
85
- _, _, body = listener.call(env)
86
-
87
- expect(body).to be_a(Appsignal::StreamWrapper)
88
- end
30
+ expect(logs).to contains_log(
31
+ :warn,
32
+ "The constant Appsignal::Rack::StreamingListener has been deprecated."
33
+ )
89
34
  end
90
35
  end
91
- end
92
-
93
- describe Appsignal::StreamWrapper do
94
- let(:stream) { double }
95
- let(:transaction) { http_request_transaction }
96
- let(:wrapper) { Appsignal::StreamWrapper.new(stream, transaction) }
97
- before do
98
- start_agent
99
- set_current_transaction(transaction)
100
- end
101
- around { |example| keep_transactions { example.run } }
102
36
 
103
- describe "#each" do
104
- it "calls the original stream" do
105
- expect(stream).to receive(:each)
37
+ describe "middleware" do
38
+ let(:env) { {} }
39
+ let(:app) { DummyApp.new }
40
+ let(:middleware) { Appsignal::Rack::StreamingListener.new(app, {}) }
41
+ around { |example| keep_transactions { example.run } }
42
+ before(:context) { load_middleware }
43
+ before { start_agent }
106
44
 
107
- wrapper.each
45
+ def make_request
46
+ middleware.call(env)
108
47
  end
109
48
 
110
- context "when #each raises an error" do
111
- let(:error) { ExampleException.new("error message") }
112
-
113
- it "records the exception" do
114
- allow(stream).to receive(:each).and_raise(error)
49
+ it "instruments the call" do
50
+ make_request
115
51
 
116
- expect { wrapper.send(:each) }.to raise_error(error)
117
-
118
- expect(transaction).to have_error("ExampleException", "error message")
119
- end
52
+ expect(last_transaction).to include_event("name" => "process_streaming_request.rack")
120
53
  end
121
- end
122
-
123
- describe "#close" do
124
- it "closes the original stream and completes the transaction" do
125
- expect(stream).to receive(:close)
126
54
 
127
- wrapper.close
55
+ it "set no action by default" do
56
+ make_request
128
57
 
129
- expect(current_transaction?).to be_falsy
130
- expect(transaction).to be_completed
58
+ expect(last_transaction).to_not have_action
131
59
  end
132
60
 
133
- context "when #close raises an error" do
134
- let(:error) { ExampleException.new("error message") }
61
+ it "set `appsignal.action` to the action name" do
62
+ env["appsignal.action"] = "Action"
135
63
 
136
- it "records the exception and completes the transaction" do
137
- allow(stream).to receive(:close).and_raise(error)
64
+ make_request
138
65
 
139
- expect { wrapper.send(:close) }.to raise_error(error)
140
-
141
- expect(transaction).to have_error("ExampleException", "error message")
142
- expect(transaction).to be_completed
143
- end
66
+ expect(last_transaction).to have_action("Action")
144
67
  end
145
68
  end
146
69
  end
@@ -0,0 +1,63 @@
1
+ describe Appsignal::Rack::Utils do
2
+ describe ".queue_start_from" do
3
+ let(:header_time) { fixed_time - 0.4 }
4
+ let(:header_time_value) { (header_time * factor).to_i }
5
+ subject { described_class.queue_start_from(env) }
6
+
7
+ shared_examples "HTTP queue start" do
8
+ context "when env is nil" do
9
+ let(:env) { nil }
10
+
11
+ it { is_expected.to be_nil }
12
+ end
13
+
14
+ context "with no relevant header set" do
15
+ let(:env) { {} }
16
+
17
+ it { is_expected.to be_nil }
18
+ end
19
+
20
+ context "with the HTTP_X_REQUEST_START header set" do
21
+ let(:env) { { "HTTP_X_REQUEST_START" => "t=#{header_time_value}" } }
22
+
23
+ it { is_expected.to eq 1_389_783_599_600 }
24
+
25
+ context "with unparsable content" do
26
+ let(:env) { { "HTTP_X_REQUEST_START" => "something" } }
27
+
28
+ it { is_expected.to be_nil }
29
+ end
30
+
31
+ context "with unparsable content at the end" do
32
+ let(:env) { { "HTTP_X_REQUEST_START" => "t=#{header_time_value}aaaa" } }
33
+
34
+ it { is_expected.to eq 1_389_783_599_600 }
35
+ end
36
+
37
+ context "with a really low number" do
38
+ let(:env) { { "HTTP_X_REQUEST_START" => "t=100" } }
39
+
40
+ it { is_expected.to be_nil }
41
+ end
42
+
43
+ context "with the alternate HTTP_X_QUEUE_START header set" do
44
+ let(:env) { { "HTTP_X_QUEUE_START" => "t=#{header_time_value}" } }
45
+
46
+ it { is_expected.to eq 1_389_783_599_600 }
47
+ end
48
+ end
49
+ end
50
+
51
+ context "time in milliseconds" do
52
+ let(:factor) { 1_000 }
53
+
54
+ it_should_behave_like "HTTP queue start"
55
+ end
56
+
57
+ context "time in microseconds" do
58
+ let(:factor) { 1_000_000 }
59
+
60
+ it_should_behave_like "HTTP queue start"
61
+ end
62
+ end
63
+ end