appsignal 3.4.0 → 3.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +63 -21
  3. data/.rubocop_todo.yml +68 -54
  4. data/.semaphore/semaphore.yml +11 -11
  5. data/CHANGELOG.md +37 -0
  6. data/Rakefile +15 -99
  7. data/appsignal.gemspec +3 -4
  8. data/bin/appsignal +4 -2
  9. data/build_matrix.yml +4 -4
  10. data/ext/._appsignal-agent +0 -0
  11. data/ext/Rakefile +22 -21
  12. data/ext/agent.rb +2 -0
  13. data/ext/base.rb +14 -17
  14. data/ext/extconf.rb +4 -1
  15. data/lib/appsignal/auth_check.rb +3 -3
  16. data/lib/appsignal/capistrano.rb +1 -1
  17. data/lib/appsignal/cli/demo.rb +5 -2
  18. data/lib/appsignal/cli/diagnose/paths.rb +4 -1
  19. data/lib/appsignal/cli/diagnose/utils.rb +7 -3
  20. data/lib/appsignal/cli/diagnose.rb +7 -5
  21. data/lib/appsignal/cli/helpers.rb +1 -4
  22. data/lib/appsignal/cli/install.rb +4 -10
  23. data/lib/appsignal/cli.rb +3 -2
  24. data/lib/appsignal/config.rb +105 -102
  25. data/lib/appsignal/demo.rb +2 -1
  26. data/lib/appsignal/environment.rb +2 -0
  27. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +2 -1
  28. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +13 -13
  29. data/lib/appsignal/event_formatter.rb +5 -4
  30. data/lib/appsignal/extension/jruby.rb +11 -9
  31. data/lib/appsignal/extension.rb +1 -1
  32. data/lib/appsignal/helpers/instrumentation.rb +50 -35
  33. data/lib/appsignal/hooks/action_cable.rb +6 -4
  34. data/lib/appsignal/hooks/action_mailer.rb +2 -0
  35. data/lib/appsignal/hooks/active_job.rb +11 -10
  36. data/lib/appsignal/hooks/active_support_notifications.rb +3 -4
  37. data/lib/appsignal/hooks/data_mapper.rb +1 -1
  38. data/lib/appsignal/hooks/gvl.rb +3 -0
  39. data/lib/appsignal/hooks/http.rb +1 -1
  40. data/lib/appsignal/hooks/mri.rb +2 -0
  41. data/lib/appsignal/hooks/net_http.rb +1 -1
  42. data/lib/appsignal/hooks/que.rb +1 -1
  43. data/lib/appsignal/hooks/rake.rb +1 -1
  44. data/lib/appsignal/hooks/redis.rb +1 -1
  45. data/lib/appsignal/hooks/resque.rb +1 -1
  46. data/lib/appsignal/hooks/shoryuken.rb +2 -4
  47. data/lib/appsignal/hooks/sidekiq.rb +1 -1
  48. data/lib/appsignal/hooks/unicorn.rb +2 -2
  49. data/lib/appsignal/hooks/webmachine.rb +1 -1
  50. data/lib/appsignal/hooks.rb +2 -2
  51. data/lib/appsignal/integrations/active_support_notifications.rb +1 -1
  52. data/lib/appsignal/integrations/capistrano/appsignal.cap +6 -3
  53. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +5 -4
  54. data/lib/appsignal/integrations/delayed_job_plugin.rb +3 -5
  55. data/lib/appsignal/integrations/grape.rb +1 -1
  56. data/lib/appsignal/integrations/hanami.rb +1 -1
  57. data/lib/appsignal/integrations/object.rb +2 -3
  58. data/lib/appsignal/integrations/padrino.rb +2 -4
  59. data/lib/appsignal/integrations/que.rb +6 -6
  60. data/lib/appsignal/integrations/railtie.rb +72 -0
  61. data/lib/appsignal/integrations/sidekiq.rb +9 -11
  62. data/lib/appsignal/integrations/sinatra.rb +1 -3
  63. data/lib/appsignal/integrations/webmachine.rb +4 -6
  64. data/lib/appsignal/logger.rb +31 -6
  65. data/lib/appsignal/marker.rb +4 -5
  66. data/lib/appsignal/minutely.rb +7 -7
  67. data/lib/appsignal/probes/gvl.rb +9 -4
  68. data/lib/appsignal/probes/helpers.rb +4 -6
  69. data/lib/appsignal/probes/mri.rb +7 -5
  70. data/lib/appsignal/probes/sidekiq.rb +3 -0
  71. data/lib/appsignal/probes.rb +2 -0
  72. data/lib/appsignal/rack/generic_instrumentation.rb +1 -5
  73. data/lib/appsignal/rack/sinatra_instrumentation.rb +3 -5
  74. data/lib/appsignal/rack/streaming_listener.rb +11 -13
  75. data/lib/appsignal/span.rb +5 -5
  76. data/lib/appsignal/system.rb +10 -11
  77. data/lib/appsignal/transaction.rb +49 -25
  78. data/lib/appsignal/transmitter.rb +4 -2
  79. data/lib/appsignal/utils/deprecation_message.rb +2 -0
  80. data/lib/appsignal/utils/hash_sanitizer.rb +1 -1
  81. data/lib/appsignal/utils/integration_logger.rb +5 -3
  82. data/lib/appsignal/utils/json.rb +1 -1
  83. data/lib/appsignal/utils/query_params_sanitizer.rb +1 -1
  84. data/lib/appsignal/version.rb +1 -1
  85. data/lib/appsignal.rb +5 -4
  86. data/lib/puma/plugin/appsignal.rb +16 -18
  87. data/script/lint_git +1 -1
  88. data/spec/lib/appsignal/capistrano2_spec.rb +6 -3
  89. data/spec/lib/appsignal/capistrano3_spec.rb +6 -3
  90. data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +1 -3
  91. data/spec/lib/appsignal/cli/diagnose_spec.rb +33 -30
  92. data/spec/lib/appsignal/cli/install_spec.rb +5 -6
  93. data/spec/lib/appsignal/cli_spec.rb +1 -1
  94. data/spec/lib/appsignal/config_spec.rb +43 -37
  95. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +11 -5
  96. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +4 -4
  97. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +1 -4
  98. data/spec/lib/appsignal/event_formatter_spec.rb +11 -9
  99. data/spec/lib/appsignal/hooks/action_cable_spec.rb +5 -2
  100. data/spec/lib/appsignal/hooks/action_mailer_spec.rb +2 -1
  101. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +1 -1
  102. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +1 -1
  103. data/spec/lib/appsignal/hooks/activejob_spec.rb +21 -12
  104. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +1 -0
  105. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +12 -12
  106. data/spec/lib/appsignal/hooks/excon_spec.rb +2 -2
  107. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +3 -1
  108. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +4 -2
  109. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -1
  110. data/spec/lib/appsignal/hooks_spec.rb +5 -4
  111. data/spec/lib/appsignal/integrations/grape_spec.rb +8 -4
  112. data/spec/lib/appsignal/integrations/hanami_spec.rb +16 -8
  113. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +2 -4
  114. data/spec/lib/appsignal/integrations/object_spec.rb +6 -1
  115. data/spec/lib/appsignal/integrations/padrino_spec.rb +4 -2
  116. data/spec/lib/appsignal/integrations/railtie_spec.rb +213 -6
  117. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +54 -41
  118. data/spec/lib/appsignal/logger_spec.rb +20 -4
  119. data/spec/lib/appsignal/marker_spec.rb +2 -2
  120. data/spec/lib/appsignal/minutely_spec.rb +3 -3
  121. data/spec/lib/appsignal/probes/gvl_spec.rb +60 -12
  122. data/spec/lib/appsignal/probes/mri_spec.rb +7 -4
  123. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -1
  124. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +2 -1
  125. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +10 -5
  126. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +7 -5
  127. data/spec/lib/appsignal/transaction_spec.rb +20 -13
  128. data/spec/lib/appsignal/utils/data_spec.rb +10 -1
  129. data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +11 -11
  130. data/spec/lib/appsignal/utils/json_spec.rb +4 -2
  131. data/spec/lib/appsignal_spec.rb +49 -35
  132. data/spec/lib/puma/appsignal_spec.rb +9 -11
  133. data/spec/spec_helper.rb +14 -2
  134. data/spec/support/fixtures/projects/valid/config/appsignal.yml +1 -1
  135. data/spec/support/helpers/config_helpers.rb +2 -1
  136. data/spec/support/helpers/dependency_helper.rb +1 -9
  137. data/spec/support/helpers/std_streams_helper.rb +1 -3
  138. data/spec/support/helpers/wait_for_helper.rb +2 -3
  139. data/spec/support/mocks/appsignal_mock.rb +1 -1
  140. data/spec/support/mocks/fake_gvl_tools.rb +2 -10
  141. data/spec/support/testing.rb +4 -3
  142. metadata +9 -135
@@ -4,36 +4,84 @@ describe Appsignal::Probes::GvlProbe do
4
4
 
5
5
  let(:hostname) { "some-host" }
6
6
 
7
+ def gauges_for(metric)
8
+ gauges = appsignal_mock.gauges.select do |gauge|
9
+ gauge[0] == metric
10
+ end
11
+
12
+ gauges.map do |gauge|
13
+ gauge.drop(1)
14
+ end
15
+ end
16
+
7
17
  after(:each) { FakeGVLTools.reset }
8
18
 
9
- context "with global timer enabled" do
10
- before(:each) { FakeGVLTools::GlobalTimer.enabled = true }
19
+ it "gauges the global timer delta" do
20
+ FakeGVLTools::GlobalTimer.monotonic_time = 100_000_000
21
+ probe.call
22
+
23
+ expect(gauges_for("gvl_global_timer")).to be_empty
24
+
25
+ FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
26
+ probe.call
11
27
 
12
- it "gauges the global timer delta" do
13
- FakeGVLTools::GlobalTimer.monotonic_time = 100_000_000
28
+ expect(gauges_for("gvl_global_timer")).to eq [
29
+ [200, { :hostname => hostname }]
30
+ ]
31
+ end
32
+
33
+ context "when the delta is negative" do
34
+ it "does not gauge the global timer delta" do
35
+ FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
14
36
  probe.call
15
37
 
16
- expect(appsignal_mock.gauges).to be_empty
38
+ expect(gauges_for("gvl_global_timer")).to be_empty
39
+
40
+ FakeGVLTools::GlobalTimer.monotonic_time = 0
41
+ probe.call
42
+
43
+ expect(gauges_for("gvl_global_timer")).to be_empty
44
+ end
45
+ end
17
46
 
47
+ context "when the delta is zero" do
48
+ it "does not gauge the global timer delta" do
18
49
  FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
19
50
  probe.call
20
51
 
21
- expect(appsignal_mock.gauges).to eq [
22
- ["gvl_global_timer", 200, { :hostname => hostname }]
23
- ]
52
+ expect(gauges_for("gvl_global_timer")).to be_empty
53
+
54
+ probe.call
55
+
56
+ expect(gauges_for("gvl_global_timer")).to be_empty
24
57
  end
25
58
  end
26
59
 
27
- context "with waiting threads enabled" do
28
- before(:each) { FakeGVLTools::WaitingThreads.enabled = true }
60
+ context "when the waiting threads count is enabled" do
61
+ before(:each) do
62
+ FakeGVLTools::WaitingThreads.enabled = true
63
+ end
29
64
 
30
65
  it "gauges the waiting threads count" do
31
66
  FakeGVLTools::WaitingThreads.count = 3
32
67
  probe.call
33
68
 
34
- expect(appsignal_mock.gauges).to eq [
35
- ["gvl_waiting_threads", 3, { :hostname => hostname }]
69
+ expect(gauges_for("gvl_waiting_threads")).to eq [
70
+ [3, { :hostname => hostname }]
36
71
  ]
37
72
  end
38
73
  end
74
+
75
+ context "when the waiting threads count is disabled" do
76
+ before(:each) do
77
+ FakeGVLTools::WaitingThreads.enabled = false
78
+ end
79
+
80
+ it "does not gauge the waiting threads count" do
81
+ FakeGVLTools::WaitingThreads.count = 3
82
+ probe.call
83
+
84
+ expect(gauges_for("gvl_waiting_threads")).to be_empty
85
+ end
86
+ end
39
87
  end
@@ -1,10 +1,12 @@
1
1
  describe Appsignal::Probes::MriProbe do
2
2
  let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
3
3
  let(:gc_profiler_mock) { instance_double("Appsignal::GarbageCollectionProfiler") }
4
- let(:probe) { described_class.new(:appsignal => appsignal_mock, :gc_profiler => gc_profiler_mock) }
4
+ let(:probe) do
5
+ described_class.new(:appsignal => appsignal_mock, :gc_profiler => gc_profiler_mock)
6
+ end
5
7
 
6
8
  describe ".dependencies_present?" do
7
- if DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
9
+ if DependencyHelper.running_jruby?
8
10
  it "should not be present" do
9
11
  expect(described_class.dependencies_present?).to be_falsy
10
12
  end
@@ -15,7 +17,7 @@ describe Appsignal::Probes::MriProbe do
15
17
  end
16
18
  end
17
19
 
18
- unless DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
20
+ unless DependencyHelper.running_jruby?
19
21
  describe "#call" do
20
22
  let(:hostname) { nil }
21
23
  before do
@@ -126,7 +128,8 @@ describe Appsignal::Probes::MriProbe do
126
128
 
127
129
  it "reports custom hostname tag value" do
128
130
  probe.call
129
- expect_gauge_value("heap_slots", :tags => { :metric => :heap_live, :hostname => hostname })
131
+ expect_gauge_value("heap_slots",
132
+ :tags => { :metric => :heap_live, :hostname => hostname })
130
133
  end
131
134
  end
132
135
  end
@@ -42,7 +42,8 @@ describe Appsignal::Rack::GenericInstrumentation do
42
42
  kind_of(String),
43
43
  Appsignal::Transaction::HTTP_REQUEST,
44
44
  kind_of(Rack::Request)
45
- ).and_return(double(:set_action_if_nil => nil, :set_http_or_background_queue_start => nil, :set_metadata => nil))
45
+ ).and_return(double(:set_action_if_nil => nil, :set_http_or_background_queue_start => nil,
46
+ :set_metadata => nil))
46
47
  end
47
48
 
48
49
  it "should call the app" do
@@ -113,7 +113,8 @@ if DependencyHelper.rails_present?
113
113
 
114
114
  transaction_hash = last_transaction.to_h
115
115
  expect(transaction_hash["metadata"]).to_not have_key("method")
116
- expect(log_contents(log)).to contains_log(:error, "Unable to report HTTP request method: '")
116
+ expect(log_contents(log)).to contains_log(:error,
117
+ "Unable to report HTTP request method: '")
117
118
  end
118
119
  end
119
120
 
@@ -110,7 +110,8 @@ if DependencyHelper.sinatra_present?
110
110
  Appsignal::Transaction::HTTP_REQUEST,
111
111
  kind_of(Sinatra::Request),
112
112
  kind_of(Hash)
113
- ).and_return(double(:set_action_if_nil => nil, :set_http_or_background_queue_start => nil, :set_metadata => nil))
113
+ ).and_return(double(:set_action_if_nil => nil, :set_http_or_background_queue_start => nil,
114
+ :set_metadata => nil))
114
115
  end
115
116
 
116
117
  it "should call the app" do
@@ -158,7 +159,8 @@ if DependencyHelper.sinatra_present?
158
159
 
159
160
  describe "action name" do
160
161
  it "should set the action" do
161
- expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil).with("GET /")
162
+ expect_any_instance_of(Appsignal::Transaction)
163
+ .to receive(:set_action_if_nil).with("GET /")
162
164
  end
163
165
 
164
166
  context "without 'sinatra.route' env" do
@@ -173,14 +175,16 @@ if DependencyHelper.sinatra_present?
173
175
  before { env["SCRIPT_NAME"] = "/api" }
174
176
 
175
177
  it "should call set_action with an application prefix path" do
176
- expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil).with("GET /api/")
178
+ expect_any_instance_of(Appsignal::Transaction)
179
+ .to receive(:set_action_if_nil).with("GET /api/")
177
180
  end
178
181
 
179
182
  context "without 'sinatra.route' env" do
180
183
  let(:env) { { :path => "/", :method => "GET" } }
181
184
 
182
185
  it "returns nil" do
183
- expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil).with(nil)
186
+ expect_any_instance_of(Appsignal::Transaction)
187
+ .to receive(:set_action_if_nil).with(nil)
184
188
  end
185
189
  end
186
190
  end
@@ -191,7 +195,8 @@ if DependencyHelper.sinatra_present?
191
195
  end
192
196
 
193
197
  it "should set the queue start" do
194
- expect_any_instance_of(Appsignal::Transaction).to receive(:set_http_or_background_queue_start)
198
+ expect_any_instance_of(Appsignal::Transaction)
199
+ .to receive(:set_http_or_background_queue_start)
195
200
  end
196
201
 
197
202
  context "with overridden request class and params method" do
@@ -4,10 +4,10 @@ describe Appsignal::Rack::StreamingListener do
4
4
  let(:headers) { {} }
5
5
  let(:env) do
6
6
  {
7
- "rack.input" => StringIO.new,
7
+ "rack.input" => StringIO.new,
8
8
  "REQUEST_METHOD" => "GET",
9
- "PATH_INFO" => "/homepage",
10
- "QUERY_STRING" => "param=something"
9
+ "PATH_INFO" => "/homepage",
10
+ "QUERY_STRING" => "param=something"
11
11
  }
12
12
  end
13
13
  let(:app) { double(:call => [200, headers, "body"]) }
@@ -114,8 +114,10 @@ end
114
114
 
115
115
  describe Appsignal::StreamWrapper do
116
116
  let(:stream) { double }
117
- let(:transaction) { Appsignal::Transaction.create(SecureRandom.uuid, Appsignal::Transaction::HTTP_REQUEST, {}) }
118
- let(:wrapper) { Appsignal::StreamWrapper.new(stream, transaction) }
117
+ let(:transaction) do
118
+ Appsignal::Transaction.create(SecureRandom.uuid, Appsignal::Transaction::HTTP_REQUEST, {})
119
+ end
120
+ let(:wrapper) { Appsignal::StreamWrapper.new(stream, transaction) }
119
121
 
120
122
  describe "#each" do
121
123
  it "calls the original stream" do
@@ -66,8 +66,8 @@ describe Appsignal::Transaction do
66
66
  create_transaction("2")
67
67
  expect(log_contents(log)).to contains_log :warn,
68
68
  "Trying to start new transaction with id '2', but a " \
69
- "transaction with id '#{transaction_id}' is already " \
70
- "running. Using transaction '#{transaction_id}'."
69
+ "transaction with id '#{transaction_id}' is already " \
70
+ "running. Using transaction '#{transaction_id}'."
71
71
  end
72
72
 
73
73
  context "with option :force => true" do
@@ -741,7 +741,7 @@ describe Appsignal::Transaction do
741
741
  it "does not add the error" do
742
742
  expect(Appsignal.logger).to receive(:error).with(
743
743
  "Appsignal::Transaction#set_error: Cannot set error. " \
744
- "The given value is not an exception: #{error.inspect}"
744
+ "The given value is not an exception: #{error.inspect}"
745
745
  )
746
746
  expect(transaction.ext).to_not receive(:set_error)
747
747
 
@@ -1083,7 +1083,9 @@ describe Appsignal::Transaction do
1083
1083
 
1084
1084
  context "with an array" do
1085
1085
  let(:request) do
1086
- Appsignal::Transaction::GenericRequest.new(background_env_with_data(:params => %w[arg1 arg2]))
1086
+ Appsignal::Transaction::GenericRequest.new(
1087
+ background_env_with_data(:params => %w[arg1 arg2])
1088
+ )
1087
1089
  end
1088
1090
 
1089
1091
  it { is_expected.to eq %w[arg1 arg2] }
@@ -1099,8 +1101,9 @@ describe Appsignal::Transaction do
1099
1101
  context "with env" do
1100
1102
  context "with sanitization" do
1101
1103
  let(:request) do
1102
- Appsignal::Transaction::GenericRequest.new \
1104
+ Appsignal::Transaction::GenericRequest.new(
1103
1105
  http_request_env_with_data(:params => { :foo => :bar })
1106
+ )
1104
1107
  end
1105
1108
 
1106
1109
  it "should call the params sanitizer" do
@@ -1110,8 +1113,9 @@ describe Appsignal::Transaction do
1110
1113
 
1111
1114
  context "with AppSignal filtering" do
1112
1115
  let(:request) do
1113
- Appsignal::Transaction::GenericRequest.new \
1116
+ Appsignal::Transaction::GenericRequest.new(
1114
1117
  http_request_env_with_data(:params => { :foo => :bar, :baz => :bat })
1118
+ )
1115
1119
  end
1116
1120
  before { Appsignal.config.config_hash[:filter_parameters] = %w[foo] }
1117
1121
  after { Appsignal.config.config_hash[:filter_parameters] = [] }
@@ -1233,7 +1237,8 @@ describe Appsignal::Transaction do
1233
1237
  true
1234
1238
  end
1235
1239
  end.new
1236
- ActionDispatch::Request::Session.create(store, ActionDispatch::Request.new("rack.input" => StringIO.new), {})
1240
+ ActionDispatch::Request::Session.create(store,
1241
+ ActionDispatch::Request.new("rack.input" => StringIO.new), {})
1237
1242
  end
1238
1243
  before do
1239
1244
  expect(transaction).to respond_to(:request)
@@ -1334,12 +1339,14 @@ describe Appsignal::Transaction do
1334
1339
 
1335
1340
  let(:error) do
1336
1341
  PG::UniqueViolation.new(
1337
- "ERROR: duplicate key value violates unique constraint \"index_users_on_email\" DETAIL: Key (email)=(test@test.com) already exists."
1342
+ "ERROR: duplicate key value violates unique constraint " \
1343
+ "\"index_users_on_email\" DETAIL: Key (email)=(test@test.com) already exists."
1338
1344
  )
1339
1345
  end
1340
1346
 
1341
1347
  it "returns a sanizited error message" do
1342
- expect(subject).to eq "ERROR: duplicate key value violates unique constraint \"index_users_on_email\" DETAIL: Key (email)=(?) already exists."
1348
+ expect(subject).to eq "ERROR: duplicate key value violates unique constraint " \
1349
+ "\"index_users_on_email\" DETAIL: Key (email)=(?) already exists."
1343
1350
  end
1344
1351
  end
1345
1352
 
@@ -1350,15 +1357,15 @@ describe Appsignal::Transaction do
1350
1357
 
1351
1358
  let(:error) do
1352
1359
  ActiveRecord::RecordNotUnique.new(
1353
- "PG::UniqueViolation: ERROR: duplicate key value violates unique constraint \"example_constraint\"\n" \
1354
- "DETAIL: Key (email)=(foo@example.com) already exists."
1360
+ "PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
1361
+ "\"example_constraint\"\nDETAIL: Key (email)=(foo@example.com) already exists."
1355
1362
  )
1356
1363
  end
1357
1364
 
1358
1365
  it "returns a sanizited error message" do
1359
1366
  expect(subject).to eq \
1360
- "PG::UniqueViolation: ERROR: duplicate key value violates unique constraint \"example_constraint\"\n" \
1361
- "DETAIL: Key (email)=(?) already exists."
1367
+ "PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
1368
+ "\"example_constraint\"\nDETAIL: Key (email)=(?) already exists."
1362
1369
  end
1363
1370
  end
1364
1371
  end
@@ -47,6 +47,7 @@ describe Appsignal::Utils::Data do
47
47
 
48
48
  describe "#to_s" do
49
49
  it "returns a serialized hash" do
50
+ # rubocop:disable Style/StringConcatenation
50
51
  expect(subject.to_s).to eq %({"":"test",) +
51
52
  %("1":true,) +
52
53
  %("bar":null,) +
@@ -59,6 +60,7 @@ describe Appsignal::Utils::Data do
59
60
  %("int63":"bigint:#{1 << 63}",) +
60
61
  %("int64":"bigint:#{1 << 64}",) +
61
62
  %("the":"payload"})
63
+ # rubocop:enable Style/StringConcatenation
62
64
  end
63
65
  end
64
66
  end
@@ -73,6 +75,7 @@ describe Appsignal::Utils::Data do
73
75
 
74
76
  describe "#to_s" do
75
77
  it "returns a serialized array" do
78
+ # rubocop:disable Style/StringConcatenation, Style/RedundantStringEscape
76
79
  expect(subject.to_s).to eq %([null,) +
77
80
  %(true,) +
78
81
  %(false,) +
@@ -84,6 +87,7 @@ describe Appsignal::Utils::Data do
84
87
  %("bigint:#{1 << 63}",) +
85
88
  %("bigint:#{1 << 64}",) +
86
89
  %({\"arr\":[1,2,\"three\"],\"foo\":\"bʊr\"}])
90
+ # rubocop:enable Style/StringConcatenation, Style/RedundantStringEscape
87
91
  end
88
92
  end
89
93
  end
@@ -105,7 +109,12 @@ describe Appsignal::Utils::Data do
105
109
 
106
110
  describe "#to_s" do
107
111
  it "returns a JSON representation in a String" do
108
- expect(subject.to_s).to eq %({"field_four":{"one":"aa�"},"field_one":"aa","field_three":["one","aa�"],"field_two":"aa�"})
112
+ # rubocop:disable Style/StringConcatenation
113
+ expect(subject.to_s).to eq %({"field_four":{"one":"aa�"},) +
114
+ %("field_one":"aa",) +
115
+ %("field_three":["one","aa�"],) +
116
+ %("field_two":"aa�"})
117
+ # rubocop:enable Style/StringConcatenation
109
118
  end
110
119
  end
111
120
  end
@@ -2,23 +2,23 @@ describe Appsignal::Utils::HashSanitizer do
2
2
  let(:file) { uploaded_file }
3
3
  let(:params) do
4
4
  {
5
- :text => "string",
6
- "string" => "string key value",
7
- :file => file,
8
- :float => 0.0,
9
- :bool_true => true,
5
+ :text => "string",
6
+ "string" => "string key value",
7
+ :file => file,
8
+ :float => 0.0,
9
+ :bool_true => true,
10
10
  :bool_false => false,
11
- :nil => nil,
12
- :int => 1, # Fixnum
13
- :int64 => 1 << 64, # Bignum
14
- :hash => {
15
- :nested_text => "string",
11
+ :nil => nil,
12
+ :int => 1, # Fixnum
13
+ :int64 => 1 << 64, # Bignum
14
+ :hash => {
15
+ :nested_text => "string",
16
16
  :nested_array => [
17
17
  "something",
18
18
  "else",
19
19
  file,
20
20
  {
21
- :key => "value",
21
+ :key => "value",
22
22
  :file => file
23
23
  }
24
24
  ]
@@ -15,7 +15,8 @@ describe Appsignal::Utils::JSON do
15
15
  end
16
16
 
17
17
  it "returns a JSON string" do
18
- is_expected.to eq %({"the":"payload","1":true,"":"test","foo":[1,2,"three"],"bar":null,"baz":{"foo":"bar"}})
18
+ is_expected.to eq %({"the":"payload","1":true,"":"test",) +
19
+ %("foo":[1,2,"three"],"bar":null,"baz":{"foo":"bar"}})
19
20
  end
20
21
  end
21
22
 
@@ -35,7 +36,8 @@ describe Appsignal::Utils::JSON do
35
36
  end
36
37
 
37
38
  it "returns a JSON string with invalid UTF-8 content" do
38
- is_expected.to eq %({"field_one":"aa","field_two":"aa�","field_three":["one","aa�"],"field_four":{"one":"aa�"}})
39
+ is_expected.to eq %({"field_one":"aa","field_two":"aa�",) +
40
+ %("field_three":["one","aa�"],"field_four":{"one":"aa�"}})
39
41
  end
40
42
  end
41
43
  end
@@ -22,12 +22,10 @@ describe Appsignal do
22
22
  describe ".start" do
23
23
  context "with no config set beforehand" do
24
24
  it "should do nothing when config is not set and there is no valid config in the env" do
25
- expect(Appsignal.logger).to receive(:error).with(
26
- "Push API key not set after loading config"
27
- ).once
28
- expect(Appsignal.logger).to receive(:error).with(
29
- "Not starting, no valid config for this environment"
30
- ).once
25
+ expect(Appsignal.logger).to receive(:error)
26
+ .with("Push API key not set after loading config").once
27
+ expect(Appsignal.logger).to receive(:error)
28
+ .with("Not starting, no valid config for this environment").once
31
29
  expect(Appsignal::Extension).to_not receive(:start)
32
30
  Appsignal.start
33
31
  end
@@ -249,7 +247,7 @@ describe Appsignal do
249
247
  end
250
248
 
251
249
  it "logs an error" do
252
- Appsignal.monitor_transaction("unknown.sidekiq") {}
250
+ Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
253
251
  expect(log).to contains_log(
254
252
  :error,
255
253
  "Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
@@ -317,9 +315,8 @@ describe Appsignal do
317
315
  describe ".monitor_transaction" do
318
316
  context "with a successful call" do
319
317
  it "should instrument and complete for a background job" do
320
- expect(Appsignal).to receive(:instrument).with(
321
- "perform_job.something"
322
- ).and_yield
318
+ expect(Appsignal).to receive(:instrument)
319
+ .with("perform_job.something").and_yield
323
320
  expect(Appsignal::Transaction).to receive(:complete_current!)
324
321
  object = double
325
322
  expect(object).to receive(:some_method).and_return(1)
@@ -336,9 +333,8 @@ describe Appsignal do
336
333
  end
337
334
 
338
335
  it "should instrument and complete for a http request" do
339
- expect(Appsignal).to receive(:instrument).with(
340
- "process_action.something"
341
- ).and_yield
336
+ expect(Appsignal).to receive(:instrument)
337
+ .with("process_action.something").and_yield
342
338
  expect(Appsignal::Transaction).to receive(:complete_current!)
343
339
  object = double
344
340
  expect(object).to receive(:some_method)
@@ -378,7 +374,7 @@ describe Appsignal do
378
374
  end
379
375
 
380
376
  it "logs an error" do
381
- Appsignal.monitor_transaction("unknown.sidekiq") {}
377
+ Appsignal.monitor_transaction("unknown.sidekiq") {} # rubocop:disable Lint/EmptyBlock
382
378
  expect(log).to contains_log(
383
379
  :error,
384
380
  "Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
@@ -529,7 +525,8 @@ describe Appsignal do
529
525
 
530
526
  describe ".set_gauge" do
531
527
  it "should call set_gauge on the extension with a string key and float" do
532
- expect(Appsignal::Extension).to receive(:set_gauge).with("key", 0.1, Appsignal::Extension.data_map_new)
528
+ expect(Appsignal::Extension).to receive(:set_gauge)
529
+ .with("key", 0.1, Appsignal::Extension.data_map_new)
533
530
  Appsignal.set_gauge("key", 0.1)
534
531
  end
535
532
 
@@ -540,12 +537,14 @@ describe Appsignal do
540
537
  end
541
538
 
542
539
  it "should call set_gauge on the extension with a symbol key and int" do
543
- expect(Appsignal::Extension).to receive(:set_gauge).with("key", 1.0, Appsignal::Extension.data_map_new)
540
+ expect(Appsignal::Extension).to receive(:set_gauge)
541
+ .with("key", 1.0, Appsignal::Extension.data_map_new)
544
542
  Appsignal.set_gauge(:key, 1)
545
543
  end
546
544
 
547
545
  it "should not raise an exception when out of range" do
548
- expect(Appsignal::Extension).to receive(:set_gauge).with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
546
+ expect(Appsignal::Extension).to receive(:set_gauge).with("key", 10,
547
+ Appsignal::Extension.data_map_new).and_raise(RangeError)
549
548
  expect(Appsignal.logger).to receive(:warn).with("Gauge value 10 for key 'key' is too big")
550
549
  expect do
551
550
  Appsignal.set_gauge("key", 10)
@@ -565,8 +564,10 @@ describe Appsignal do
565
564
  end
566
565
 
567
566
  it "should not raise an exception when out of range" do
568
- expect(Appsignal::Extension).to receive(:set_host_gauge).with("key", 10).and_raise(RangeError)
569
- expect(Appsignal.logger).to receive(:warn).with("Host gauge value 10 for key 'key' is too big")
567
+ expect(Appsignal::Extension).to receive(:set_host_gauge).with("key",
568
+ 10).and_raise(RangeError)
569
+ expect(Appsignal.logger).to receive(:warn)
570
+ .with("Host gauge value 10 for key 'key' is too big")
570
571
  expect do
571
572
  Appsignal.set_host_gauge("key", 10)
572
573
  end.to_not raise_error
@@ -585,8 +586,10 @@ describe Appsignal do
585
586
  end
586
587
 
587
588
  it "should not raise an exception when out of range" do
588
- expect(Appsignal::Extension).to receive(:set_process_gauge).with("key", 10).and_raise(RangeError)
589
- expect(Appsignal.logger).to receive(:warn).with("Process gauge value 10 for key 'key' is too big")
589
+ expect(Appsignal::Extension).to receive(:set_process_gauge).with("key",
590
+ 10).and_raise(RangeError)
591
+ expect(Appsignal.logger).to receive(:warn)
592
+ .with("Process gauge value 10 for key 'key' is too big")
590
593
  expect do
591
594
  Appsignal.set_process_gauge("key", 10)
592
595
  end.to_not raise_error
@@ -595,7 +598,8 @@ describe Appsignal do
595
598
 
596
599
  describe ".increment_counter" do
597
600
  it "should call increment_counter on the extension with a string key" do
598
- expect(Appsignal::Extension).to receive(:increment_counter).with("key", 1, Appsignal::Extension.data_map_new)
601
+ expect(Appsignal::Extension).to receive(:increment_counter)
602
+ .with("key", 1, Appsignal::Extension.data_map_new)
599
603
  Appsignal.increment_counter("key")
600
604
  end
601
605
 
@@ -606,18 +610,22 @@ describe Appsignal do
606
610
  end
607
611
 
608
612
  it "should call increment_counter on the extension with a symbol key" do
609
- expect(Appsignal::Extension).to receive(:increment_counter).with("key", 1, Appsignal::Extension.data_map_new)
613
+ expect(Appsignal::Extension).to receive(:increment_counter)
614
+ .with("key", 1, Appsignal::Extension.data_map_new)
610
615
  Appsignal.increment_counter(:key)
611
616
  end
612
617
 
613
618
  it "should call increment_counter on the extension with a count" do
614
- expect(Appsignal::Extension).to receive(:increment_counter).with("key", 5, Appsignal::Extension.data_map_new)
619
+ expect(Appsignal::Extension).to receive(:increment_counter)
620
+ .with("key", 5, Appsignal::Extension.data_map_new)
615
621
  Appsignal.increment_counter("key", 5)
616
622
  end
617
623
 
618
624
  it "should not raise an exception when out of range" do
619
- expect(Appsignal::Extension).to receive(:increment_counter).with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
620
- expect(Appsignal.logger).to receive(:warn).with("Counter value 10 for key 'key' is too big")
625
+ expect(Appsignal::Extension).to receive(:increment_counter)
626
+ .with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
627
+ expect(Appsignal.logger).to receive(:warn)
628
+ .with("Counter value 10 for key 'key' is too big")
621
629
  expect do
622
630
  Appsignal.increment_counter("key", 10)
623
631
  end.to_not raise_error
@@ -626,7 +634,8 @@ describe Appsignal do
626
634
 
627
635
  describe ".add_distribution_value" do
628
636
  it "should call add_distribution_value on the extension with a string key and float" do
629
- expect(Appsignal::Extension).to receive(:add_distribution_value).with("key", 0.1, Appsignal::Extension.data_map_new)
637
+ expect(Appsignal::Extension).to receive(:add_distribution_value)
638
+ .with("key", 0.1, Appsignal::Extension.data_map_new)
630
639
  Appsignal.add_distribution_value("key", 0.1)
631
640
  end
632
641
 
@@ -637,13 +646,16 @@ describe Appsignal do
637
646
  end
638
647
 
639
648
  it "should call add_distribution_value on the extension with a symbol key and int" do
640
- expect(Appsignal::Extension).to receive(:add_distribution_value).with("key", 1.0, Appsignal::Extension.data_map_new)
649
+ expect(Appsignal::Extension).to receive(:add_distribution_value)
650
+ .with("key", 1.0, Appsignal::Extension.data_map_new)
641
651
  Appsignal.add_distribution_value(:key, 1)
642
652
  end
643
653
 
644
654
  it "should not raise an exception when out of range" do
645
- expect(Appsignal::Extension).to receive(:add_distribution_value).with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
646
- expect(Appsignal.logger).to receive(:warn).with("Distribution value 10 for key 'key' is too big")
655
+ expect(Appsignal::Extension).to receive(:add_distribution_value)
656
+ .with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
657
+ expect(Appsignal.logger).to receive(:warn)
658
+ .with("Distribution value 10 for key 'key' is too big")
647
659
  expect do
648
660
  Appsignal.add_distribution_value("key", 10)
649
661
  end.to_not raise_error
@@ -1053,14 +1065,16 @@ describe Appsignal do
1053
1065
  it_behaves_like "instrument helper" do
1054
1066
  let(:instrumenter) { Appsignal }
1055
1067
  before do
1056
- expect(Appsignal::Transaction).to receive(:current).at_least(:once).and_return(transaction)
1068
+ expect(Appsignal::Transaction).to receive(:current).at_least(:once)
1069
+ .and_return(transaction)
1057
1070
  end
1058
1071
  end
1059
1072
  end
1060
1073
 
1061
1074
  describe ".instrument_sql" do
1062
1075
  before do
1063
- expect(Appsignal::Transaction).to receive(:current).at_least(:once).and_return(transaction)
1076
+ expect(Appsignal::Transaction).to receive(:current).at_least(:once)
1077
+ .and_return(transaction)
1064
1078
  end
1065
1079
 
1066
1080
  it "creates an SQL event on the transaction" do
@@ -1119,7 +1133,7 @@ describe Appsignal do
1119
1133
 
1120
1134
  context "when the log path is writable" do
1121
1135
  context "when the log file is writable" do
1122
- let(:log_file_contents) { File.open(log_file).read }
1136
+ let(:log_file_contents) { File.read(log_file) }
1123
1137
 
1124
1138
  before do
1125
1139
  capture_stdout(out_stream) do
@@ -1198,8 +1212,8 @@ describe Appsignal do
1198
1212
 
1199
1213
  it "outputs a warning" do
1200
1214
  expect(output).to include \
1201
- "appsignal: Unable to log to '#{log_path}' "\
1202
- "or the '#{Appsignal::Config.system_tmp_dir}' fallback."
1215
+ "appsignal: Unable to log to '#{log_path}' " \
1216
+ "or the '#{Appsignal::Config.system_tmp_dir}' fallback."
1203
1217
  end
1204
1218
  end
1205
1219