appsignal 3.13.1 → 4.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +499 -487
  3. data/CHANGELOG.md +104 -7
  4. data/Rakefile +31 -7
  5. data/benchmark.rake +4 -6
  6. data/build_matrix.yml +45 -39
  7. data/ext/agent.rb +27 -27
  8. data/ext/appsignal_extension.c +25 -0
  9. data/gemfiles/rails-7.2.gemfile +11 -0
  10. data/lib/appsignal/check_in/cron.rb +2 -15
  11. data/lib/appsignal/cli/diagnose.rb +37 -28
  12. data/lib/appsignal/cli/install.rb +5 -1
  13. data/lib/appsignal/config.rb +57 -119
  14. data/lib/appsignal/demo.rb +2 -2
  15. data/lib/appsignal/extension/jruby.rb +14 -0
  16. data/lib/appsignal/helpers/instrumentation.rb +139 -417
  17. data/lib/appsignal/helpers/metrics.rb +0 -16
  18. data/lib/appsignal/hooks/action_cable.rb +8 -8
  19. data/lib/appsignal/hooks/active_job.rb +2 -2
  20. data/lib/appsignal/hooks/at_exit.rb +37 -0
  21. data/lib/appsignal/hooks.rb +1 -16
  22. data/lib/appsignal/integrations/action_cable.rb +2 -2
  23. data/lib/appsignal/integrations/capistrano/appsignal.cap +2 -4
  24. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +1 -4
  25. data/lib/appsignal/integrations/delayed_job_plugin.rb +3 -3
  26. data/lib/appsignal/integrations/que.rb +2 -2
  27. data/lib/appsignal/integrations/railtie.rb +26 -59
  28. data/lib/appsignal/integrations/rake.rb +2 -2
  29. data/lib/appsignal/integrations/resque.rb +2 -2
  30. data/lib/appsignal/integrations/shoryuken.rb +4 -4
  31. data/lib/appsignal/integrations/sidekiq.rb +3 -3
  32. data/lib/appsignal/integrations/webmachine.rb +2 -2
  33. data/lib/appsignal/loaders.rb +1 -1
  34. data/lib/appsignal/probes.rb +0 -9
  35. data/lib/appsignal/rack/abstract_middleware.rb +4 -26
  36. data/lib/appsignal/rack/body_wrapper.rb +0 -12
  37. data/lib/appsignal/rack/event_handler.rb +4 -4
  38. data/lib/appsignal/rack/rails_instrumentation.rb +1 -1
  39. data/lib/appsignal/rack.rb +0 -25
  40. data/lib/appsignal/sample_data.rb +95 -0
  41. data/lib/appsignal/transaction.rb +235 -361
  42. data/lib/appsignal/utils/rails_helper.rb +4 -0
  43. data/lib/appsignal/version.rb +1 -1
  44. data/lib/appsignal.rb +19 -71
  45. data/spec/lib/appsignal/auth_check_spec.rb +1 -1
  46. data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
  47. data/spec/lib/appsignal/capistrano3_spec.rb +53 -13
  48. data/spec/lib/appsignal/check_in_spec.rb +1 -207
  49. data/spec/lib/appsignal/cli/demo_spec.rb +7 -27
  50. data/spec/lib/appsignal/cli/diagnose_spec.rb +145 -110
  51. data/spec/lib/appsignal/config_spec.rb +304 -379
  52. data/spec/lib/appsignal/extension_install_failure_spec.rb +5 -1
  53. data/spec/lib/appsignal/extension_spec.rb +5 -1
  54. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +1 -1
  55. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +1 -2
  56. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +1 -0
  57. data/spec/lib/appsignal/hooks/activejob_spec.rb +7 -12
  58. data/spec/lib/appsignal/hooks/at_exit_spec.rb +72 -0
  59. data/spec/lib/appsignal/hooks/gvl_spec.rb +10 -5
  60. data/spec/lib/appsignal/hooks/http_spec.rb +3 -3
  61. data/spec/lib/appsignal/hooks/net_http_spec.rb +3 -3
  62. data/spec/lib/appsignal/hooks/rake_spec.rb +6 -9
  63. data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -10
  64. data/spec/lib/appsignal/hooks/redis_spec.rb +4 -7
  65. data/spec/lib/appsignal/hooks/resque_spec.rb +3 -5
  66. data/spec/lib/appsignal/hooks_spec.rb +0 -41
  67. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +29 -20
  68. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +4 -9
  69. data/spec/lib/appsignal/integrations/railtie_spec.rb +179 -157
  70. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +3 -5
  71. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +48 -62
  72. data/spec/lib/appsignal/loaders/hanami_spec.rb +6 -9
  73. data/spec/lib/appsignal/loaders/padrino_spec.rb +6 -10
  74. data/spec/lib/appsignal/loaders/sinatra_spec.rb +6 -9
  75. data/spec/lib/appsignal/loaders_spec.rb +8 -1
  76. data/spec/lib/appsignal/marker_spec.rb +1 -1
  77. data/spec/lib/appsignal/probes_spec.rb +4 -83
  78. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +4 -63
  79. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +0 -48
  80. data/spec/lib/appsignal/rack/event_handler_spec.rb +18 -15
  81. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +3 -11
  82. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +4 -5
  83. data/spec/lib/appsignal/sample_data_spec.rb +174 -0
  84. data/spec/lib/appsignal/transaction_spec.rb +791 -1031
  85. data/spec/lib/appsignal/transmitter_spec.rb +6 -8
  86. data/spec/lib/appsignal_spec.rb +294 -643
  87. data/spec/spec_helper.rb +1 -3
  88. data/spec/support/fixtures/projects/valid/config/appsignal.yml +4 -7
  89. data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +16 -0
  90. data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +56 -0
  91. data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +5 -0
  92. data/spec/support/helpers/api_request_helper.rb +3 -2
  93. data/spec/support/helpers/config_helpers.rb +41 -11
  94. data/spec/support/helpers/dependency_helper.rb +8 -0
  95. data/spec/support/helpers/log_helpers.rb +1 -0
  96. data/spec/support/helpers/rails_helper.rb +6 -6
  97. data/spec/support/helpers/transaction_helpers.rb +2 -24
  98. data/spec/support/matchers/transaction.rb +3 -3
  99. data/spec/support/mocks/appsignal_mock.rb +3 -3
  100. data/spec/support/mocks/mock_probe.rb +2 -0
  101. data/spec/support/testing.rb +2 -2
  102. metadata +11 -21
  103. data/gemfiles/que_beta.gemfile +0 -5
  104. data/lib/appsignal/helpers/heartbeat.rb +0 -20
  105. data/lib/appsignal/integrations/grape.rb +0 -35
  106. data/lib/appsignal/integrations/hanami.rb +0 -13
  107. data/lib/appsignal/integrations/padrino.rb +0 -13
  108. data/lib/appsignal/integrations/sinatra.rb +0 -13
  109. data/lib/appsignal/rack/generic_instrumentation.rb +0 -22
  110. data/lib/appsignal/rack/streaming_listener.rb +0 -28
  111. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -36
  112. data/spec/lib/appsignal/integrations/hanami_spec.rb +0 -17
  113. data/spec/lib/appsignal/integrations/padrino_spec.rb +0 -15
  114. data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -15
  115. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +0 -81
  116. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +0 -69
  117. data/spec/support/fixtures/projects/valid/config/environments/development.rb +0 -0
  118. data/spec/support/fixtures/projects/valid/config/environments/production.rb +0 -0
  119. data/spec/support/fixtures/projects/valid/config/environments/test.rb +0 -0
  120. data/spec/support/rails/my_app.rb +0 -6
  121. /data/spec/support/fixtures/projects/{valid/config/application.rb → valid_with_rails_app/log/.gitkeep} +0 -0
@@ -6,7 +6,11 @@ describe Appsignal::Extension, :extension_installation_failure do
6
6
  expect(stderr).to include("ERROR: AppSignal failed to load extension")
7
7
  error_message =
8
8
  if DependencyHelper.running_jruby?
9
- "cannot open shared object file"
9
+ if DependencyHelper.macos?
10
+ "Could not open library"
11
+ else
12
+ "cannot open shared object file"
13
+ end
10
14
  else
11
15
  "LoadError: cannot load such file"
12
16
  end
@@ -49,7 +49,7 @@ describe Appsignal::Extension do
49
49
 
50
50
  context "with a valid config" do
51
51
  before do
52
- project_fixture_config.write_to_environment
52
+ build_config.write_to_environment
53
53
  end
54
54
 
55
55
  it "should have a start and stop method" do
@@ -100,6 +100,10 @@ describe Appsignal::Extension do
100
100
  subject.finish(0)
101
101
  end
102
102
 
103
+ it "should have a duplicate method" do
104
+ subject.duplicate("request_id")
105
+ end
106
+
103
107
  it "should have a complete method" do
104
108
  subject.complete
105
109
  end
@@ -88,12 +88,12 @@ shared_examples "activesupport instrument override" do
88
88
 
89
89
  context "when a transaction is completed in an instrumented block" do
90
90
  it "does not complete the ActiveSupport::Notifications.instrument event" do
91
- expect(transaction).to receive(:complete)
92
91
  as.instrument("sql.active_record", :sql => "SQL") do
93
92
  Appsignal::Transaction.complete_current!
94
93
  end
95
94
 
96
95
  expect(transaction).to_not include_events
96
+ expect(transaction).to be_completed
97
97
  end
98
98
  end
99
99
  end
@@ -36,13 +36,12 @@ shared_examples "activesupport start finish override" do
36
36
 
37
37
  context "when a transaction is completed in an instrumented block" do
38
38
  it "does not complete the ActiveSupport::Notifications.instrument event" do
39
- expect(transaction).to receive(:complete)
40
-
41
39
  instrumenter.start("sql.active_record", {})
42
40
  Appsignal::Transaction.complete_current!
43
41
  instrumenter.finish("sql.active_record", {})
44
42
 
45
43
  expect(transaction).to_not include_events
44
+ expect(transaction).to be_completed
46
45
  end
47
46
  end
48
47
  end
@@ -10,6 +10,7 @@ describe Appsignal::Hooks::ActiveSupportNotificationsHook do
10
10
  set_current_transaction(transaction)
11
11
  as.notifier = notifier
12
12
  end
13
+ around { |example| keep_transactions { example.run } }
13
14
 
14
15
  describe "#dependencies_present?" do
15
16
  subject { described_class.new.dependencies_present? }
@@ -34,7 +34,6 @@ if DependencyHelper.active_job_present?
34
34
  let(:time) { Time.parse("2001-01-01 10:00:00UTC") }
35
35
  let(:namespace) { Appsignal::Transaction::BACKGROUND_JOB }
36
36
  let(:queue) { "default" }
37
- let(:log) { StringIO.new }
38
37
  let(:parameterized_given_args) do
39
38
  {
40
39
  :foo => "Foo",
@@ -72,11 +71,11 @@ if DependencyHelper.active_job_present?
72
71
  ["perform_start.active_job", "perform.active_job"]
73
72
  end
74
73
  end
74
+ let(:options) { {} }
75
75
  before do
76
76
  ActiveJob::Base.queue_adapter = :inline
77
77
 
78
- start_agent
79
- Appsignal.internal_logger = test_logger(log)
78
+ start_agent(:options => options)
80
79
  class ActiveJobTestJob < ActiveJob::Base
81
80
  def perform(*_args)
82
81
  end
@@ -209,10 +208,9 @@ if DependencyHelper.active_job_present?
209
208
  end
210
209
 
211
210
  context "with activejob_report_errors set to none" do
212
- it "does not report the error" do
213
- start_agent("production")
214
- Appsignal.config[:activejob_report_errors] = "none"
211
+ let(:options) { { :activejob_report_errors => "none" } }
215
212
 
213
+ it "does not report the error" do
216
214
  allow(Appsignal).to receive(:increment_counter)
217
215
  tags = { :queue => queue }
218
216
  expect(Appsignal).to receive(:increment_counter)
@@ -228,10 +226,7 @@ if DependencyHelper.active_job_present?
228
226
 
229
227
  if DependencyHelper.rails_version >= Gem::Version.new("7.1.0")
230
228
  context "with activejob_report_errors set to discard" do
231
- before do
232
- start_agent("production")
233
- Appsignal.config[:activejob_report_errors] = "discard"
234
- end
229
+ let(:options) { { :activejob_report_errors => "discard" } }
235
230
 
236
231
  it "does not report error on first failure" do
237
232
  with_test_adapter do
@@ -351,9 +346,9 @@ if DependencyHelper.active_job_present?
351
346
  end
352
347
 
353
348
  context "with params" do
349
+ let(:options) { { :filter_parameters => ["foo"] } }
350
+
354
351
  it "filters the configured params" do
355
- start_agent("production")
356
- Appsignal.config[:filter_parameters] = ["foo"]
357
352
  queue_job(ActiveJobTestJob, method_given_args)
358
353
 
359
354
  transaction = last_transaction
@@ -0,0 +1,72 @@
1
+ describe Appsignal::Hooks::AtExit do
2
+ describe ".install" do
3
+ before { start_agent(:options => options) }
4
+
5
+ context "with :enable_at_exit_reporter == true" do
6
+ let(:options) { { :enable_at_exit_reporter => true } }
7
+
8
+ it "installs the at_exit hook" do
9
+ expect(Appsignal::Hooks::AtExit::AtExitCallback).to receive(:call)
10
+
11
+ expect(Kernel).to receive(:at_exit).with(no_args) do |*_args, &block|
12
+ block.call
13
+ end
14
+
15
+ described_class.new.install
16
+ end
17
+ end
18
+
19
+ context "with :enable_at_exit_reporter == false" do
20
+ let(:options) { { :enable_at_exit_reporter => false } }
21
+
22
+ it "doesn't install the at_exit hook" do
23
+ expect(Kernel).to_not receive(:at_exit)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ describe Appsignal::Hooks::AtExit::AtExitCallback do
30
+ around { |example| keep_transactions { example.run } }
31
+ before { start_agent(:options => { :enable_at_exit_reporter => true }) }
32
+
33
+ def with_error(error_class, error_message)
34
+ raise error_class, error_message
35
+ rescue error_class => error
36
+ yield error
37
+ end
38
+
39
+ def call_callback
40
+ Appsignal::Hooks::AtExit::AtExitCallback.call
41
+ end
42
+
43
+ it "reports an error if there's an unhandled error" do
44
+ expect do
45
+ with_error(ExampleException, "error message") do
46
+ call_callback
47
+ end
48
+ end.to change { created_transactions.count }.by(1)
49
+
50
+ transaction = last_transaction
51
+ expect(transaction).to have_namespace("unhandled")
52
+ expect(transaction).to have_error("ExampleException", "error message")
53
+ end
54
+
55
+ it "calls Appsignal.stop" do
56
+ expect(Appsignal).to receive(:stop).with("at_exit")
57
+ with_error(ExampleException, "error message") do
58
+ call_callback
59
+ end
60
+ end
61
+
62
+ it "doesn't report the error if is also the last error reported" do
63
+ with_error(ExampleException, "error message") do |error|
64
+ Appsignal.report_error(error)
65
+ expect(created_transactions.count).to eq(1)
66
+
67
+ expect do
68
+ call_callback
69
+ end.to_not change { created_transactions.count }.from(1)
70
+ end
71
+ end
72
+ end
@@ -7,8 +7,9 @@ describe Appsignal::Hooks::GvlHook do
7
7
  end
8
8
  end
9
9
  else
10
+ let(:options) { {} }
10
11
  before do
11
- start_agent
12
+ start_agent(:options => options)
12
13
  end
13
14
 
14
15
  def expect_gvltools_require
@@ -100,8 +101,9 @@ describe Appsignal::Hooks::GvlHook do
100
101
 
101
102
  describe "#install" do
102
103
  context "with enable_gvl_global_timer" do
104
+ let(:options) { { :enable_gvl_global_timer => true } }
105
+
103
106
  it "enables the GVL global timer" do
104
- Appsignal.config[:enable_gvl_global_timer] = true
105
107
  expect(::GVLTools::GlobalTimer).to receive(:enable)
106
108
 
107
109
  described_class.new.install
@@ -109,8 +111,9 @@ describe Appsignal::Hooks::GvlHook do
109
111
  end
110
112
 
111
113
  context "without enable_gvl_global_timer" do
114
+ let(:options) { { :enable_gvl_global_timer => false } }
115
+
112
116
  it "does not enable the GVL global timer" do
113
- Appsignal.config[:enable_gvl_global_timer] = false
114
117
  expect(::GVLTools::GlobalTimer).not_to receive(:enable)
115
118
 
116
119
  described_class.new.install
@@ -118,8 +121,9 @@ describe Appsignal::Hooks::GvlHook do
118
121
  end
119
122
 
120
123
  context "with enable_gvl_waiting_threads" do
124
+ let(:options) { { :enable_gvl_waiting_threads => true } }
125
+
121
126
  it "enables the GVL waiting threads" do
122
- Appsignal.config[:enable_gvl_global_timer] = true
123
127
  expect(::GVLTools::WaitingThreads).to receive(:enable)
124
128
 
125
129
  described_class.new.install
@@ -127,8 +131,9 @@ describe Appsignal::Hooks::GvlHook do
127
131
  end
128
132
 
129
133
  context "without enable_gvl_waiting_threads" do
134
+ let(:options) { { :enable_gvl_waiting_threads => false } }
135
+
130
136
  it "does not enable the GVL waiting threads" do
131
- Appsignal.config[:enable_gvl_waiting_threads] = false
132
137
  expect(::GVLTools::WaitingThreads).not_to receive(:enable)
133
138
 
134
139
  described_class.new.install
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe Appsignal::Hooks::HttpHook do
4
- before { start_agent }
4
+ let(:options) { {} }
5
+ before { start_agent(:options => options) }
5
6
 
6
7
  if DependencyHelper.http_present?
7
8
  context "with instrument_http_rb set to true" do
@@ -18,8 +19,7 @@ describe Appsignal::Hooks::HttpHook do
18
19
  end
19
20
 
20
21
  context "with instrument_http_rb set to false" do
21
- before { Appsignal.config.config_hash[:instrument_http_rb] = false }
22
- after { Appsignal.config.config_hash[:instrument_http_rb] = true }
22
+ let(:options) { { :instrument_http_rb => false } }
23
23
 
24
24
  describe "#dependencies_present?" do
25
25
  subject { described_class.new.dependencies_present? }
@@ -1,5 +1,6 @@
1
1
  describe Appsignal::Hooks::NetHttpHook do
2
- before { start_agent }
2
+ let(:options) { {} }
3
+ before { start_agent(:options => options) }
3
4
 
4
5
  describe "#dependencies_present?" do
5
6
  subject { described_class.new.dependencies_present? }
@@ -9,8 +10,7 @@ describe Appsignal::Hooks::NetHttpHook do
9
10
  end
10
11
 
11
12
  context "with Net::HTTP instrumentation disabled" do
12
- before { Appsignal.config.config_hash[:instrument_net_http] = false }
13
- after { Appsignal.config.config_hash[:instrument_net_http] = true }
13
+ let(:options) { { :instrument_net_http => false } }
14
14
 
15
15
  it { is_expected.to be_falsy }
16
16
  end
@@ -4,8 +4,9 @@ describe Appsignal::Hooks::RakeHook do
4
4
  let(:helper) { Appsignal::Integrations::RakeIntegrationHelper }
5
5
  let(:task) { Rake::Task.new("task:name", Rake::Application.new) }
6
6
  let(:arguments) { Rake::TaskArguments.new(["foo"], ["bar"]) }
7
+ let(:options) { {} }
7
8
  before do
8
- start_agent
9
+ start_agent(:options => options)
9
10
  allow(Kernel).to receive(:at_exit)
10
11
  end
11
12
  around { |example| keep_transactions { example.run } }
@@ -30,9 +31,7 @@ describe Appsignal::Hooks::RakeHook do
30
31
  end
31
32
 
32
33
  context "with :enable_rake_performance_instrumentation == false" do
33
- before do
34
- Appsignal.config[:enable_rake_performance_instrumentation] = false
35
- end
34
+ let(:options) { { :enable_rake_performance_instrumentation => false } }
36
35
 
37
36
  it "creates no transaction" do
38
37
  expect { perform }.to_not(change { created_transactions.count })
@@ -49,16 +48,14 @@ describe Appsignal::Hooks::RakeHook do
49
48
  end
50
49
 
51
50
  context "with :enable_rake_performance_instrumentation == true" do
52
- before do
53
- Appsignal.config[:enable_rake_performance_instrumentation] = true
54
- end
51
+ let(:options) { { :enable_rake_performance_instrumentation => true } }
55
52
 
56
53
  it "creates a transaction" do
57
54
  expect { perform }.to(change { created_transactions.count }.by(1))
58
55
 
59
56
  transaction = last_transaction
60
57
  expect(transaction).to have_id
61
- expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
58
+ expect(transaction).to have_namespace("rake")
62
59
  expect(transaction).to have_action("task:name")
63
60
  expect(transaction).to_not have_error
64
61
  expect(transaction).to include_params("foo" => "bar")
@@ -91,7 +88,7 @@ describe Appsignal::Hooks::RakeHook do
91
88
 
92
89
  transaction = last_transaction
93
90
  expect(transaction).to have_id
94
- expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
91
+ expect(transaction).to have_namespace("rake")
95
92
  expect(transaction).to have_action("task:name")
96
93
  expect(transaction).to have_error("ExampleException", "error message")
97
94
  expect(transaction).to include_params("foo" => "bar")
@@ -1,6 +1,7 @@
1
1
  describe Appsignal::Hooks::RedisClientHook do
2
+ let(:options) { {} }
2
3
  before do
3
- start_agent
4
+ start_agent(:options => options)
4
5
  end
5
6
 
6
7
  if DependencyHelper.redis_client_present?
@@ -30,9 +31,7 @@ describe Appsignal::Hooks::RedisClientHook do
30
31
 
31
32
  context "with rest-client gem" do
32
33
  describe "integration" do
33
- before do
34
- Appsignal.config.config_hash[:instrument_redis] = true
35
- end
34
+ let(:options) { { :instrument_redis => true } }
36
35
 
37
36
  context "install" do
38
37
  before do
@@ -115,9 +114,7 @@ describe Appsignal::Hooks::RedisClientHook do
115
114
  if DependencyHelper.hiredis_client_present?
116
115
  context "with hiredis driver" do
117
116
  describe "integration" do
118
- before do
119
- Appsignal.config.config_hash[:instrument_redis] = true
120
- end
117
+ let(:options) { { :instrument_redis => true } }
121
118
 
122
119
  context "install" do
123
120
  before do
@@ -200,9 +197,7 @@ describe Appsignal::Hooks::RedisClientHook do
200
197
  end
201
198
 
202
199
  context "with instrumentation disabled" do
203
- before do
204
- Appsignal.config.config_hash[:instrument_redis] = false
205
- end
200
+ let(:options) { { :instrument_redis => false } }
206
201
 
207
202
  describe "#dependencies_present?" do
208
203
  subject { described_class.new.dependencies_present? }
@@ -1,5 +1,6 @@
1
1
  describe Appsignal::Hooks::RedisHook do
2
- before { start_agent }
2
+ let(:options) { {} }
3
+ before { start_agent(:options => options) }
3
4
 
4
5
  if DependencyHelper.redis_present?
5
6
  context "with redis" do
@@ -22,9 +23,7 @@ describe Appsignal::Hooks::RedisHook do
22
23
  end
23
24
 
24
25
  describe "integration" do
25
- before do
26
- Appsignal.config.config_hash[:instrument_redis] = true
27
- end
26
+ let(:options) { { :instrument_redis => true } }
28
27
 
29
28
  context "install" do
30
29
  before do
@@ -103,9 +102,7 @@ describe Appsignal::Hooks::RedisHook do
103
102
  end
104
103
 
105
104
  context "with instrumentation disabled" do
106
- before do
107
- Appsignal.config.config_hash[:instrument_redis] = false
108
- end
105
+ let(:options) { { :instrument_redis => false } }
109
106
 
110
107
  describe "#dependencies_present?" do
111
108
  subject { described_class.new.dependencies_present? }
@@ -25,8 +25,9 @@ describe Appsignal::Hooks::ResqueHook do
25
25
 
26
26
  let(:queue) { "default" }
27
27
  let(:namespace) { Appsignal::Transaction::BACKGROUND_JOB }
28
+ let(:options) { {} }
28
29
  before do
29
- start_agent
30
+ start_agent(:options => options)
30
31
 
31
32
  class ResqueTestJob
32
33
  def self.perform(*_args)
@@ -82,10 +83,7 @@ describe Appsignal::Hooks::ResqueHook do
82
83
  end
83
84
 
84
85
  context "with arguments" do
85
- before do
86
- start_agent("production")
87
- Appsignal.config[:filter_parameters] = ["foo"]
88
- end
86
+ let(:options) { { :filter_parameters => ["foo"] } }
89
87
 
90
88
  it "filters out configured arguments" do
91
89
  perform_rescue_job(
@@ -82,47 +82,6 @@ describe Appsignal::Hooks do
82
82
  expect(Appsignal::Hooks.hooks[:mock_error_hook].installed?).to be_falsy
83
83
  Appsignal::Hooks.hooks.delete(:mock_error_hook)
84
84
  end
85
-
86
- describe "missing constants" do
87
- let(:err_stream) { std_stream }
88
- let(:stderr) { err_stream.read }
89
- let(:log_stream) { std_stream }
90
- let(:log) { log_contents(log_stream) }
91
- before do
92
- Appsignal.internal_logger = test_logger(log_stream)
93
- end
94
-
95
- def call_constant(&block)
96
- capture_std_streams(std_stream, err_stream, &block)
97
- end
98
-
99
- describe "SidekiqPlugin" do
100
- it "logs a deprecation message and returns the new constant" do
101
- constant = call_constant { Appsignal::Hooks::SidekiqPlugin }
102
-
103
- expect(constant).to eql(Appsignal::Integrations::SidekiqMiddleware)
104
- expect(constant.name).to eql("Appsignal::Integrations::SidekiqMiddleware")
105
-
106
- deprecation_message =
107
- "The constant Appsignal::Hooks::SidekiqPlugin has been deprecated. " \
108
- "Please update the constant name to Appsignal::Integrations::SidekiqMiddleware " \
109
- "in the following file to remove this message.\n#{__FILE__}:"
110
- expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
111
- expect(log).to contains_log :warn, deprecation_message
112
- end
113
- end
114
-
115
- describe "other constant" do
116
- it "raises a NameError like Ruby normally does" do
117
- expect do
118
- call_constant { Appsignal::Hooks::Unknown }
119
- end.to raise_error(NameError)
120
-
121
- expect(stderr).to be_empty
122
- expect(log).to be_empty
123
- end
124
- end
125
- end
126
85
  end
127
86
 
128
87
  describe Appsignal::Hooks::Helpers do
@@ -7,11 +7,11 @@ describe Appsignal::Hooks::DataMapperLogListener do
7
7
  end
8
8
 
9
9
  describe "#log" do
10
- let(:transaction) { double }
10
+ let(:transaction) { http_request_transaction }
11
11
  let(:message) do
12
12
  double(
13
13
  :query => "SELECT * from users",
14
- :duration => 100
14
+ :duration => 100_000_000 # nanoseconds
15
15
  )
16
16
  end
17
17
  let(:connection_class) do
@@ -24,20 +24,29 @@ describe Appsignal::Hooks::DataMapperLogListener do
24
24
  end
25
25
  end
26
26
  end
27
+ before do
28
+ start_agent
29
+ set_current_transaction(transaction)
30
+ end
31
+ around { |example| keep_transactions { example.run } }
32
+
33
+ def log_message
34
+ connection_class.new.log(message)
35
+ end
27
36
 
28
- before { allow(Appsignal::Transaction).to receive(:current) { transaction } }
37
+ it "records the log entry in an event" do
38
+ log_message
29
39
 
30
- it "should record the log entry in an event" do
31
- expect(transaction).to receive(:record_event).with(
32
- "query.data_mapper",
33
- "DataMapper Query",
34
- "SELECT * from users",
35
- 100,
36
- Appsignal::EventFormatter::SQL_BODY_FORMAT
40
+ expect(transaction).to include_event(
41
+ "name" => "query.data_mapper",
42
+ "title" => "DataMapper Query",
43
+ "body" => "SELECT * from users",
44
+ "body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
45
+ "duration" => 100.0
37
46
  )
38
47
  end
39
48
 
40
- context "when scheme is not sql-like" do
49
+ context "when the scheme is not sql-like" do
41
50
  let(:connection_class) do
42
51
  module DataObjects
43
52
  module MongoDB
@@ -49,17 +58,17 @@ describe Appsignal::Hooks::DataMapperLogListener do
49
58
  end
50
59
  end
51
60
 
52
- it "should record the log entry in an event without body" do
53
- expect(transaction).to receive(:record_event).with(
54
- "query.data_mapper",
55
- "DataMapper Query",
56
- "",
57
- 100,
58
- Appsignal::EventFormatter::DEFAULT
61
+ it "records the log entry in an event without body" do
62
+ log_message
63
+
64
+ expect(transaction).to include_event(
65
+ "name" => "query.data_mapper",
66
+ "title" => "DataMapper Query",
67
+ "body" => "",
68
+ "body_format" => Appsignal::EventFormatter::DEFAULT,
69
+ "duration" => 100.0
59
70
  )
60
71
  end
61
72
  end
62
-
63
- after { connection_class.new.log(message) }
64
73
  end
65
74
  end
@@ -15,7 +15,8 @@ describe "Appsignal::Integrations::DelayedJobHook" do
15
15
  require "appsignal/integrations/delayed_job_plugin"
16
16
  end
17
17
  after(:context) { Object.send(:remove_const, :Delayed) }
18
- before { start_agent }
18
+ let(:options) { {} }
19
+ before { start_agent(:options => options) }
19
20
 
20
21
  # We haven't found a way to test the hooks, we'll have to do that manually
21
22
 
@@ -82,10 +83,7 @@ describe "Appsignal::Integrations::DelayedJobHook" do
82
83
  end
83
84
 
84
85
  context "with parameter filtering" do
85
- before do
86
- start_agent("production")
87
- Appsignal.config[:filter_parameters] = ["foo"]
88
- end
86
+ let(:options) { { :filter_parameters => ["foo"] } }
89
87
 
90
88
  it "filters selected arguments" do
91
89
  perform
@@ -271,10 +269,7 @@ describe "Appsignal::Integrations::DelayedJobHook" do
271
269
  end
272
270
 
273
271
  context "with parameter filtering" do
274
- before do
275
- start_agent("production")
276
- Appsignal.config[:filter_parameters] = ["foo"]
277
- end
272
+ let(:options) { { :filter_parameters => ["foo"] } }
278
273
 
279
274
  it "filters selected arguments" do
280
275
  perform