appsignal 2.5.0.alpha.1-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 (211) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rspec +4 -0
  4. data/.rubocop.yml +66 -0
  5. data/.rubocop_todo.yml +124 -0
  6. data/.travis.yml +72 -0
  7. data/.yardopts +8 -0
  8. data/CHANGELOG.md +639 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE +20 -0
  11. data/README.md +264 -0
  12. data/Rakefile +214 -0
  13. data/appsignal.gemspec +42 -0
  14. data/benchmark.rake +77 -0
  15. data/bin/appsignal +13 -0
  16. data/ext/Rakefile +27 -0
  17. data/ext/agent.yml +64 -0
  18. data/ext/appsignal_extension.c +692 -0
  19. data/ext/base.rb +79 -0
  20. data/ext/extconf.rb +35 -0
  21. data/gemfiles/capistrano2.gemfile +7 -0
  22. data/gemfiles/capistrano3.gemfile +7 -0
  23. data/gemfiles/grape.gemfile +7 -0
  24. data/gemfiles/no_dependencies.gemfile +5 -0
  25. data/gemfiles/padrino.gemfile +7 -0
  26. data/gemfiles/que.gemfile +5 -0
  27. data/gemfiles/rails-3.2.gemfile +6 -0
  28. data/gemfiles/rails-4.0.gemfile +6 -0
  29. data/gemfiles/rails-4.1.gemfile +6 -0
  30. data/gemfiles/rails-4.2.gemfile +10 -0
  31. data/gemfiles/rails-5.0.gemfile +5 -0
  32. data/gemfiles/rails-5.1.gemfile +5 -0
  33. data/gemfiles/resque.gemfile +12 -0
  34. data/gemfiles/sequel-435.gemfile +11 -0
  35. data/gemfiles/sequel.gemfile +11 -0
  36. data/gemfiles/sinatra.gemfile +6 -0
  37. data/gemfiles/webmachine.gemfile +5 -0
  38. data/lib/appsignal.rb +804 -0
  39. data/lib/appsignal/auth_check.rb +65 -0
  40. data/lib/appsignal/capistrano.rb +10 -0
  41. data/lib/appsignal/cli.rb +108 -0
  42. data/lib/appsignal/cli/demo.rb +63 -0
  43. data/lib/appsignal/cli/diagnose.rb +500 -0
  44. data/lib/appsignal/cli/helpers.rb +72 -0
  45. data/lib/appsignal/cli/install.rb +277 -0
  46. data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
  47. data/lib/appsignal/config.rb +287 -0
  48. data/lib/appsignal/demo.rb +107 -0
  49. data/lib/appsignal/event_formatter.rb +74 -0
  50. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
  51. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
  52. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
  53. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
  54. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
  55. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
  56. data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
  57. data/lib/appsignal/extension.rb +63 -0
  58. data/lib/appsignal/extension/jruby.rb +460 -0
  59. data/lib/appsignal/garbage_collection_profiler.rb +48 -0
  60. data/lib/appsignal/hooks.rb +105 -0
  61. data/lib/appsignal/hooks/action_cable.rb +113 -0
  62. data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
  63. data/lib/appsignal/hooks/celluloid.rb +30 -0
  64. data/lib/appsignal/hooks/data_mapper.rb +18 -0
  65. data/lib/appsignal/hooks/delayed_job.rb +19 -0
  66. data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
  67. data/lib/appsignal/hooks/net_http.rb +29 -0
  68. data/lib/appsignal/hooks/passenger.rb +22 -0
  69. data/lib/appsignal/hooks/puma.rb +35 -0
  70. data/lib/appsignal/hooks/que.rb +21 -0
  71. data/lib/appsignal/hooks/rake.rb +39 -0
  72. data/lib/appsignal/hooks/redis.rb +30 -0
  73. data/lib/appsignal/hooks/sequel.rb +60 -0
  74. data/lib/appsignal/hooks/shoryuken.rb +43 -0
  75. data/lib/appsignal/hooks/sidekiq.rb +144 -0
  76. data/lib/appsignal/hooks/unicorn.rb +40 -0
  77. data/lib/appsignal/hooks/webmachine.rb +23 -0
  78. data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
  79. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
  80. data/lib/appsignal/integrations/data_mapper.rb +33 -0
  81. data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
  82. data/lib/appsignal/integrations/grape.rb +53 -0
  83. data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
  84. data/lib/appsignal/integrations/object.rb +35 -0
  85. data/lib/appsignal/integrations/padrino.rb +84 -0
  86. data/lib/appsignal/integrations/que.rb +43 -0
  87. data/lib/appsignal/integrations/railtie.rb +41 -0
  88. data/lib/appsignal/integrations/rake.rb +2 -0
  89. data/lib/appsignal/integrations/resque.rb +20 -0
  90. data/lib/appsignal/integrations/resque_active_job.rb +30 -0
  91. data/lib/appsignal/integrations/sinatra.rb +17 -0
  92. data/lib/appsignal/integrations/webmachine.rb +38 -0
  93. data/lib/appsignal/js_exception_transaction.rb +54 -0
  94. data/lib/appsignal/marker.rb +63 -0
  95. data/lib/appsignal/minutely.rb +42 -0
  96. data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
  97. data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
  98. data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
  99. data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
  100. data/lib/appsignal/rack/streaming_listener.rb +73 -0
  101. data/lib/appsignal/system.rb +81 -0
  102. data/lib/appsignal/transaction.rb +498 -0
  103. data/lib/appsignal/transmitter.rb +107 -0
  104. data/lib/appsignal/utils.rb +127 -0
  105. data/lib/appsignal/utils/params_sanitizer.rb +59 -0
  106. data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
  107. data/lib/appsignal/version.rb +3 -0
  108. data/lib/sequel/extensions/appsignal_integration.rb +3 -0
  109. data/resources/appsignal.yml.erb +39 -0
  110. data/resources/cacert.pem +3866 -0
  111. data/spec/.rubocop.yml +7 -0
  112. data/spec/lib/appsignal/auth_check_spec.rb +80 -0
  113. data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
  114. data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
  115. data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
  116. data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
  117. data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
  118. data/spec/lib/appsignal/cli/install_spec.rb +632 -0
  119. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
  120. data/spec/lib/appsignal/cli_spec.rb +56 -0
  121. data/spec/lib/appsignal/config_spec.rb +637 -0
  122. data/spec/lib/appsignal/demo_spec.rb +87 -0
  123. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
  124. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
  125. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
  126. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
  127. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
  128. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
  129. data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
  130. data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
  131. data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
  132. data/spec/lib/appsignal/extension_spec.rb +137 -0
  133. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
  134. data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
  135. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
  136. data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
  137. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
  138. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
  139. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
  140. data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
  141. data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
  142. data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
  143. data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
  144. data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
  145. data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
  146. data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
  147. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
  148. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
  149. data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
  150. data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
  151. data/spec/lib/appsignal/hooks_spec.rb +195 -0
  152. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
  153. data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
  154. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
  155. data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
  156. data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
  157. data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
  158. data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
  159. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
  160. data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
  161. data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
  162. data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
  163. data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
  164. data/spec/lib/appsignal/marker_spec.rb +51 -0
  165. data/spec/lib/appsignal/minutely_spec.rb +50 -0
  166. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
  167. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
  168. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
  169. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
  170. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
  171. data/spec/lib/appsignal/system_spec.rb +131 -0
  172. data/spec/lib/appsignal/transaction_spec.rb +1146 -0
  173. data/spec/lib/appsignal/transmitter_spec.rb +152 -0
  174. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
  175. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
  176. data/spec/lib/appsignal/utils_spec.rb +150 -0
  177. data/spec/lib/appsignal_spec.rb +1049 -0
  178. data/spec/spec_helper.rb +116 -0
  179. data/spec/support/fixtures/containers/cgroups/docker +14 -0
  180. data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
  181. data/spec/support/fixtures/containers/cgroups/lxc +10 -0
  182. data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
  183. data/spec/support/fixtures/containers/cgroups/none +1 -0
  184. data/spec/support/fixtures/generated_config.yml +24 -0
  185. data/spec/support/fixtures/uploaded_file.txt +0 -0
  186. data/spec/support/helpers/api_request_helper.rb +19 -0
  187. data/spec/support/helpers/cli_helpers.rb +26 -0
  188. data/spec/support/helpers/config_helpers.rb +21 -0
  189. data/spec/support/helpers/dependency_helper.rb +73 -0
  190. data/spec/support/helpers/directory_helper.rb +27 -0
  191. data/spec/support/helpers/env_helpers.rb +33 -0
  192. data/spec/support/helpers/example_exception.rb +13 -0
  193. data/spec/support/helpers/example_standard_error.rb +13 -0
  194. data/spec/support/helpers/log_helpers.rb +22 -0
  195. data/spec/support/helpers/std_streams_helper.rb +66 -0
  196. data/spec/support/helpers/system_helpers.rb +8 -0
  197. data/spec/support/helpers/time_helpers.rb +11 -0
  198. data/spec/support/helpers/transaction_helpers.rb +37 -0
  199. data/spec/support/matchers/contains_log.rb +7 -0
  200. data/spec/support/mocks/fake_gc_profiler.rb +19 -0
  201. data/spec/support/mocks/mock_extension.rb +6 -0
  202. data/spec/support/project_fixture/config/application.rb +0 -0
  203. data/spec/support/project_fixture/config/appsignal.yml +32 -0
  204. data/spec/support/project_fixture/config/environments/development.rb +0 -0
  205. data/spec/support/project_fixture/config/environments/production.rb +0 -0
  206. data/spec/support/project_fixture/config/environments/test.rb +0 -0
  207. data/spec/support/project_fixture/log/.gitkeep +0 -0
  208. data/spec/support/rails/my_app.rb +6 -0
  209. data/spec/support/shared_examples/instrument.rb +43 -0
  210. data/spec/support/stubs/delayed_job.rb +0 -0
  211. metadata +483 -0
@@ -0,0 +1,92 @@
1
+ describe Appsignal::Hooks::ActiveSupportNotificationsHook do
2
+ if active_support_present?
3
+ let(:notifier) { ActiveSupport::Notifications::Fanout.new }
4
+ let(:as) { ActiveSupport::Notifications }
5
+ before :context do
6
+ start_agent
7
+ end
8
+ before do
9
+ as.notifier = notifier
10
+ Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
11
+ end
12
+
13
+ describe "#dependencies_present?" do
14
+ subject { described_class.new.dependencies_present? }
15
+
16
+ it { is_expected.to be_truthy }
17
+ end
18
+
19
+ it "instruments an ActiveSupport::Notifications.instrument event" do
20
+ expect(Appsignal::Transaction.current).to receive(:start_event)
21
+ .at_least(:once)
22
+ expect(Appsignal::Transaction.current).to receive(:finish_event)
23
+ .at_least(:once)
24
+ .with("sql.active_record", nil, "SQL", 1)
25
+
26
+ return_value = as.instrument("sql.active_record", :sql => "SQL") do
27
+ "value"
28
+ end
29
+
30
+ expect(return_value).to eq "value"
31
+ end
32
+
33
+ it "should convert non-string names to strings" do
34
+ expect(Appsignal::Transaction.current).to receive(:start_event)
35
+ .at_least(:once)
36
+ expect(Appsignal::Transaction.current).to receive(:finish_event)
37
+ .at_least(:once)
38
+ .with("not_a_string", nil, nil, nil)
39
+
40
+ as.instrument(:not_a_string) {}
41
+ end
42
+
43
+ it "does not instrument events whose name starts with a bang" do
44
+ expect(Appsignal::Transaction.current).not_to receive(:start_event)
45
+ expect(Appsignal::Transaction.current).not_to receive(:finish_event)
46
+
47
+ return_value = as.instrument("!sql.active_record", :sql => "SQL") do
48
+ "value"
49
+ end
50
+
51
+ expect(return_value).to eq "value"
52
+ end
53
+
54
+ context "when an error is raised in an instrumented block" do
55
+ it "instruments an ActiveSupport::Notifications.instrument event" do
56
+ expect(Appsignal::Transaction.current).to receive(:start_event)
57
+ .at_least(:once)
58
+ expect(Appsignal::Transaction.current).to receive(:finish_event)
59
+ .at_least(:once)
60
+ .with("sql.active_record", nil, "SQL", 1)
61
+
62
+ expect do
63
+ as.instrument("sql.active_record", :sql => "SQL") do
64
+ raise ExampleException, "foo"
65
+ end
66
+ end.to raise_error(ExampleException, "foo")
67
+ end
68
+ end
69
+
70
+ context "when a message is thrown in an instrumented block" do
71
+ it "instruments an ActiveSupport::Notifications.instrument event" do
72
+ expect(Appsignal::Transaction.current).to receive(:start_event)
73
+ .at_least(:once)
74
+ expect(Appsignal::Transaction.current).to receive(:finish_event)
75
+ .at_least(:once)
76
+ .with("sql.active_record", nil, "SQL", 1)
77
+
78
+ expect do
79
+ as.instrument("sql.active_record", :sql => "SQL") do
80
+ throw :foo
81
+ end
82
+ end.to throw_symbol(:foo)
83
+ end
84
+ end
85
+ else
86
+ describe "#dependencies_present?" do
87
+ subject { described_class.new.dependencies_present? }
88
+
89
+ it { is_expected.to be_falsy }
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,35 @@
1
+ describe Appsignal::Hooks::CelluloidHook do
2
+ context "with celluloid" do
3
+ before :context do
4
+ module Celluloid
5
+ def self.shutdown
6
+ end
7
+ end
8
+ Appsignal::Hooks::CelluloidHook.new.install
9
+ end
10
+ after :context do
11
+ Object.send(:remove_const, :Celluloid)
12
+ end
13
+
14
+ describe "#dependencies_present?" do
15
+ subject { described_class.new.dependencies_present? }
16
+
17
+ it { is_expected.to be_truthy }
18
+ end
19
+
20
+ specify { expect(Appsignal).to receive(:stop) }
21
+ specify { expect(Celluloid).to receive(:shutdown_without_appsignal) }
22
+
23
+ after do
24
+ Celluloid.shutdown
25
+ end
26
+ end
27
+
28
+ context "without celluloid" do
29
+ describe "#dependencies_present?" do
30
+ subject { described_class.new.dependencies_present? }
31
+
32
+ it { is_expected.to be_falsy }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ describe Appsignal::Hooks::DataMapperHook do
2
+ context "with datamapper" do
3
+ before :context do
4
+ module DataMapper
5
+ end
6
+ module DataObjects
7
+ class Connection
8
+ end
9
+ end
10
+ Appsignal::Hooks::DataMapperHook.new.install
11
+ end
12
+
13
+ after :context do
14
+ Object.send(:remove_const, :DataMapper)
15
+ Object.send(:remove_const, :DataObjects)
16
+ end
17
+
18
+ describe "#dependencies_present?" do
19
+ subject { described_class.new.dependencies_present? }
20
+
21
+ it { is_expected.to be_truthy }
22
+ end
23
+
24
+ it "should install the listener" do
25
+ expect(::DataObjects::Connection).to receive(:include)
26
+ .with(Appsignal::Hooks::DataMapperLogListener)
27
+
28
+ Appsignal::Hooks::DataMapperHook.new.install
29
+ end
30
+ end
31
+
32
+ context "without datamapper" do
33
+ describe "#dependencies_present?" do
34
+ subject { described_class.new.dependencies_present? }
35
+
36
+ it { is_expected.to be_falsy }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,358 @@
1
+ describe Appsignal::Hooks::DelayedJobHook do
2
+ context "with delayed job" do
3
+ before(:context) do
4
+ module Delayed
5
+ class Plugin
6
+ def self.callbacks
7
+ end
8
+ end
9
+
10
+ class Worker
11
+ def self.plugins
12
+ @plugins ||= []
13
+ end
14
+ end
15
+ end
16
+ end
17
+ after(:context) { Object.send(:remove_const, :Delayed) }
18
+ before do
19
+ start_agent
20
+ end
21
+
22
+ describe "#dependencies_present?" do
23
+ subject { described_class.new.dependencies_present? }
24
+
25
+ it { is_expected.to be_truthy }
26
+ end
27
+
28
+ it "adds the plugin" do
29
+ expect(::Delayed::Worker.plugins).to include Appsignal::Hooks::DelayedJobPlugin
30
+ end
31
+
32
+ # We haven't found a way to test the hooks, we'll have to do that manually
33
+
34
+ describe ".invoke_with_instrumentation" do
35
+ let(:plugin) { Appsignal::Hooks::DelayedJobPlugin }
36
+ let(:time) { Time.parse("01-01-2001 10:01:00UTC") }
37
+ let(:created_at) { time - 3600 }
38
+ let(:run_at) { time - 3600 }
39
+ let(:job_data) do
40
+ {
41
+ :id => 123,
42
+ :name => "TestClass#perform",
43
+ :priority => 1,
44
+ :attempts => 1,
45
+ :queue => "default",
46
+ :created_at => created_at,
47
+ :run_at => run_at,
48
+ :payload_object => double(:args => args)
49
+ }
50
+ end
51
+ let(:args) { ["argument"] }
52
+ let(:job) { double(job_data) }
53
+ let(:invoked_block) { proc {} }
54
+
55
+ context "with a normal call" do
56
+ let(:default_params) do
57
+ {
58
+ :class => "TestClass",
59
+ :method => "perform",
60
+ :metadata => {
61
+ :priority => 1,
62
+ :attempts => 1,
63
+ :queue => "default",
64
+ :id => "123"
65
+ },
66
+ :params => args,
67
+ :queue_start => run_at
68
+ }
69
+ end
70
+ after do
71
+ Timecop.freeze(time) do
72
+ plugin.invoke_with_instrumentation(job, invoked_block)
73
+ end
74
+ end
75
+
76
+ it "wraps it in a transaction with the correct params" do
77
+ expect(Appsignal).to receive(:monitor_transaction).with(
78
+ "perform_job.delayed_job",
79
+ default_params.merge(:params => ["argument"])
80
+ )
81
+ end
82
+
83
+ context "with more complex params" do
84
+ let(:args) do
85
+ {
86
+ :foo => "Foo",
87
+ :bar => "Bar"
88
+ }
89
+ end
90
+
91
+ it "adds the more complex arguments" do
92
+ expect(Appsignal).to receive(:monitor_transaction).with(
93
+ "perform_job.delayed_job",
94
+ default_params.merge(
95
+ :params => {
96
+ :foo => "Foo",
97
+ :bar => "Bar"
98
+ }
99
+ )
100
+ )
101
+ end
102
+
103
+ context "with parameter filtering" do
104
+ before do
105
+ Appsignal.config = project_fixture_config("production")
106
+ Appsignal.config[:filter_parameters] = ["foo"]
107
+ end
108
+
109
+ it "filters selected arguments" do
110
+ expect(Appsignal).to receive(:monitor_transaction).with(
111
+ "perform_job.delayed_job",
112
+ default_params.merge(
113
+ :params => {
114
+ :foo => "[FILTERED]",
115
+ :bar => "Bar"
116
+ }
117
+ )
118
+ )
119
+ end
120
+ end
121
+ end
122
+
123
+ context "with run_at in the future" do
124
+ let(:run_at) { Time.parse("2017-01-01 10:01:00UTC") }
125
+
126
+ it "reports queue_start with run_at time" do
127
+ expect(Appsignal).to receive(:monitor_transaction).with(
128
+ "perform_job.delayed_job",
129
+ default_params.merge(:queue_start => run_at)
130
+ )
131
+ end
132
+ end
133
+
134
+ context "with custom name call" do
135
+ let(:job_data) do
136
+ {
137
+ :payload_object => double(
138
+ :appsignal_name => "CustomClass#perform",
139
+ :args => args
140
+ ),
141
+ :id => "123",
142
+ :name => "TestClass#perform",
143
+ :priority => 1,
144
+ :attempts => 1,
145
+ :queue => "default",
146
+ :created_at => created_at,
147
+ :run_at => run_at
148
+ }
149
+ end
150
+ let(:default_params) do
151
+ {
152
+ :class => "CustomClass",
153
+ :method => "perform",
154
+ :metadata => {
155
+ :priority => 1,
156
+ :attempts => 1,
157
+ :queue => "default",
158
+ :id => "123"
159
+ },
160
+ :queue_start => run_at
161
+ }
162
+ end
163
+
164
+ it "wraps it in a transaction with the correct params" do
165
+ expect(Appsignal).to receive(:monitor_transaction).with(
166
+ "perform_job.delayed_job",
167
+ default_params.merge(
168
+ :params => ["argument"]
169
+ )
170
+ )
171
+ end
172
+
173
+ context "with more complex params" do
174
+ let(:args) do
175
+ {
176
+ :foo => "Foo",
177
+ :bar => "Bar"
178
+ }
179
+ end
180
+
181
+ it "adds the more complex arguments" do
182
+ expect(Appsignal).to receive(:monitor_transaction).with(
183
+ "perform_job.delayed_job",
184
+ default_params.merge(
185
+ :params => {
186
+ :foo => "Foo",
187
+ :bar => "Bar"
188
+ }
189
+ )
190
+ )
191
+ end
192
+
193
+ context "with parameter filtering" do
194
+ before do
195
+ Appsignal.config = project_fixture_config("production")
196
+ Appsignal.config[:filter_parameters] = ["foo"]
197
+ end
198
+
199
+ it "filters selected arguments" do
200
+ expect(Appsignal).to receive(:monitor_transaction).with(
201
+ "perform_job.delayed_job",
202
+ default_params.merge(
203
+ :params => {
204
+ :foo => "[FILTERED]",
205
+ :bar => "Bar"
206
+ }
207
+ )
208
+ )
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ if active_job_present?
215
+ require "active_job"
216
+
217
+ context "when wrapped by ActiveJob" do
218
+ let(:wrapped_job) do
219
+ ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper.new(
220
+ "arguments" => args,
221
+ "job_class" => "TestClass",
222
+ "job_id" => 123,
223
+ "locale" => :en,
224
+ "queue_name" => "default"
225
+ )
226
+ end
227
+ let(:job) do
228
+ double(
229
+ :id => 123,
230
+ :name => "ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper",
231
+ :priority => 1,
232
+ :attempts => 1,
233
+ :queue => "default",
234
+ :created_at => created_at,
235
+ :run_at => run_at,
236
+ :payload_object => wrapped_job
237
+ )
238
+ end
239
+ let(:default_params) do
240
+ {
241
+ :class => "TestClass",
242
+ :method => "perform",
243
+ :metadata => {
244
+ :priority => 1,
245
+ :attempts => 1,
246
+ :queue => "default",
247
+ :id => "123"
248
+ },
249
+ :queue_start => run_at,
250
+ :params => args
251
+ }
252
+ end
253
+ let(:args) { ["activejob_argument"] }
254
+
255
+ context "with simple params" do
256
+ it "wraps it in a transaction with the correct params" do
257
+ expect(Appsignal).to receive(:monitor_transaction).with(
258
+ "perform_job.delayed_job",
259
+ default_params.merge(:params => ["activejob_argument"])
260
+ )
261
+ end
262
+ end
263
+
264
+ context "with more complex params" do
265
+ let(:args) do
266
+ {
267
+ :foo => "Foo",
268
+ :bar => "Bar"
269
+ }
270
+ end
271
+
272
+ it "adds the more complex arguments" do
273
+ expect(Appsignal).to receive(:monitor_transaction).with(
274
+ "perform_job.delayed_job",
275
+ default_params.merge(
276
+ :params => {
277
+ :foo => "Foo",
278
+ :bar => "Bar"
279
+ }
280
+ )
281
+ )
282
+ end
283
+
284
+ context "with parameter filtering" do
285
+ before do
286
+ Appsignal.config = project_fixture_config("production")
287
+ Appsignal.config[:filter_parameters] = ["foo"]
288
+ end
289
+
290
+ it "filters selected arguments" do
291
+ expect(Appsignal).to receive(:monitor_transaction).with(
292
+ "perform_job.delayed_job",
293
+ default_params.merge(
294
+ :params => {
295
+ :foo => "[FILTERED]",
296
+ :bar => "Bar"
297
+ }
298
+ )
299
+ )
300
+ end
301
+ end
302
+ end
303
+
304
+ context "with run_at in the future" do
305
+ let(:run_at) { Time.parse("2017-01-01 10:01:00UTC") }
306
+
307
+ it "reports queue_start with run_at time" do
308
+ expect(Appsignal).to receive(:monitor_transaction).with(
309
+ "perform_job.delayed_job",
310
+ default_params.merge(:queue_start => run_at)
311
+ )
312
+ end
313
+ end
314
+ end
315
+ end
316
+ end
317
+
318
+ context "with an erroring call" do
319
+ let(:error) { ExampleException }
320
+ let(:transaction) do
321
+ Appsignal::Transaction.new(
322
+ SecureRandom.uuid,
323
+ Appsignal::Transaction::BACKGROUND_JOB,
324
+ Appsignal::Transaction::GenericRequest.new({})
325
+ )
326
+ end
327
+ before do
328
+ expect(invoked_block).to receive(:call).and_raise(error)
329
+
330
+ allow(Appsignal::Transaction).to receive(:current).and_return(transaction)
331
+ expect(Appsignal::Transaction).to receive(:create)
332
+ .with(
333
+ kind_of(String),
334
+ Appsignal::Transaction::BACKGROUND_JOB,
335
+ kind_of(Appsignal::Transaction::GenericRequest)
336
+ ).and_return(transaction)
337
+ end
338
+
339
+ it "adds the error to the transaction" do
340
+ expect(transaction).to receive(:set_error).with(error)
341
+ expect(transaction).to receive(:complete)
342
+
343
+ expect do
344
+ plugin.invoke_with_instrumentation(job, invoked_block)
345
+ end.to raise_error(error)
346
+ end
347
+ end
348
+ end
349
+ end
350
+
351
+ context "without delayed job" do
352
+ describe "#dependencies_present?" do
353
+ subject { described_class.new.dependencies_present? }
354
+
355
+ it { is_expected.to be_falsy }
356
+ end
357
+ end
358
+ end