appsignal 3.10.0-java → 3.12.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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +197 -0
  4. data/Gemfile +1 -0
  5. data/Rakefile +1 -1
  6. data/benchmark.rake +99 -42
  7. data/lib/appsignal/cli/demo.rb +0 -1
  8. data/lib/appsignal/cli/diagnose.rb +1 -1
  9. data/lib/appsignal/config.rb +204 -130
  10. data/lib/appsignal/demo.rb +16 -26
  11. data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
  12. data/lib/appsignal/event_formatter.rb +3 -2
  13. data/lib/appsignal/helpers/instrumentation.rb +331 -19
  14. data/lib/appsignal/hooks/action_cable.rb +21 -16
  15. data/lib/appsignal/hooks/active_job.rb +14 -8
  16. data/lib/appsignal/hooks/delayed_job.rb +1 -1
  17. data/lib/appsignal/hooks/shoryuken.rb +3 -63
  18. data/lib/appsignal/integrations/action_cable.rb +5 -7
  19. data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
  20. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
  21. data/lib/appsignal/integrations/data_mapper.rb +1 -0
  22. data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
  23. data/lib/appsignal/integrations/dry_monitor.rb +1 -0
  24. data/lib/appsignal/integrations/excon.rb +1 -0
  25. data/lib/appsignal/integrations/grape.rb +7 -0
  26. data/lib/appsignal/integrations/hanami.rb +8 -43
  27. data/lib/appsignal/integrations/http.rb +1 -0
  28. data/lib/appsignal/integrations/net_http.rb +1 -0
  29. data/lib/appsignal/integrations/object.rb +6 -0
  30. data/lib/appsignal/integrations/padrino.rb +8 -73
  31. data/lib/appsignal/integrations/que.rb +13 -20
  32. data/lib/appsignal/integrations/railtie.rb +36 -14
  33. data/lib/appsignal/integrations/rake.rb +1 -5
  34. data/lib/appsignal/integrations/redis.rb +1 -0
  35. data/lib/appsignal/integrations/redis_client.rb +1 -0
  36. data/lib/appsignal/integrations/resque.rb +2 -5
  37. data/lib/appsignal/integrations/shoryuken.rb +75 -0
  38. data/lib/appsignal/integrations/sidekiq.rb +7 -15
  39. data/lib/appsignal/integrations/sinatra.rb +8 -19
  40. data/lib/appsignal/integrations/unicorn.rb +1 -0
  41. data/lib/appsignal/integrations/webmachine.rb +2 -5
  42. data/lib/appsignal/loaders/grape.rb +13 -0
  43. data/lib/appsignal/loaders/hanami.rb +40 -0
  44. data/lib/appsignal/loaders/padrino.rb +68 -0
  45. data/lib/appsignal/loaders/sinatra.rb +24 -0
  46. data/lib/appsignal/loaders.rb +92 -0
  47. data/lib/appsignal/logger.rb +7 -3
  48. data/lib/appsignal/probes/helpers.rb +1 -0
  49. data/lib/appsignal/probes/mri.rb +1 -0
  50. data/lib/appsignal/probes/sidekiq.rb +1 -0
  51. data/lib/appsignal/probes.rb +3 -0
  52. data/lib/appsignal/rack/abstract_middleware.rb +20 -13
  53. data/lib/appsignal/rack/event_handler.rb +44 -13
  54. data/lib/appsignal/rack/generic_instrumentation.rb +1 -0
  55. data/lib/appsignal/rack/grape_middleware.rb +2 -1
  56. data/lib/appsignal/rack/streaming_listener.rb +1 -0
  57. data/lib/appsignal/rack.rb +35 -0
  58. data/lib/appsignal/span.rb +1 -0
  59. data/lib/appsignal/transaction.rb +308 -101
  60. data/lib/appsignal/utils/data.rb +0 -1
  61. data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
  62. data/lib/appsignal/utils/integration_logger.rb +0 -13
  63. data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
  64. data/lib/appsignal/utils/json.rb +0 -1
  65. data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
  66. data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
  67. data/lib/appsignal/utils.rb +6 -0
  68. data/lib/appsignal/version.rb +1 -1
  69. data/lib/appsignal.rb +169 -14
  70. data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
  71. data/spec/lib/appsignal/cli/demo_spec.rb +0 -1
  72. data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +1 -1
  73. data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1
  74. data/spec/lib/appsignal/config_spec.rb +291 -44
  75. data/spec/lib/appsignal/demo_spec.rb +1 -2
  76. data/spec/lib/appsignal/environment_spec.rb +4 -2
  77. data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
  78. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +3 -6
  79. data/spec/lib/appsignal/hooks/activejob_spec.rb +12 -3
  80. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
  81. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +4 -7
  82. data/spec/lib/appsignal/hooks/excon_spec.rb +3 -6
  83. data/spec/lib/appsignal/hooks/gvl_spec.rb +2 -2
  84. data/spec/lib/appsignal/hooks/http_spec.rb +1 -3
  85. data/spec/lib/appsignal/hooks/net_http_spec.rb +1 -1
  86. data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -8
  87. data/spec/lib/appsignal/hooks/redis_spec.rb +3 -6
  88. data/spec/lib/appsignal/hooks/resque_spec.rb +1 -1
  89. data/spec/lib/appsignal/hooks/sequel_spec.rb +3 -5
  90. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
  91. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +1 -1
  92. data/spec/lib/appsignal/hooks/webmachine_spec.rb +1 -1
  93. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
  94. data/spec/lib/appsignal/integrations/grape_spec.rb +36 -0
  95. data/spec/lib/appsignal/integrations/hanami_spec.rb +9 -178
  96. data/spec/lib/appsignal/integrations/http_spec.rb +1 -5
  97. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +4 -2
  98. data/spec/lib/appsignal/integrations/net_http_spec.rb +1 -1
  99. data/spec/lib/appsignal/integrations/object_spec.rb +1 -3
  100. data/spec/lib/appsignal/integrations/padrino_spec.rb +8 -330
  101. data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
  102. data/spec/lib/appsignal/integrations/railtie_spec.rb +275 -191
  103. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
  104. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +15 -13
  105. data/spec/lib/appsignal/integrations/sinatra_spec.rb +9 -104
  106. data/spec/lib/appsignal/integrations/webmachine_spec.rb +13 -1
  107. data/spec/lib/appsignal/loaders/grape_spec.rb +12 -0
  108. data/spec/lib/appsignal/loaders/hanami_spec.rb +95 -0
  109. data/spec/lib/appsignal/loaders/padrino_spec.rb +277 -0
  110. data/spec/lib/appsignal/loaders/sinatra_spec.rb +47 -0
  111. data/spec/lib/appsignal/loaders_spec.rb +137 -0
  112. data/spec/lib/appsignal/probes/sidekiq_spec.rb +1 -1
  113. data/spec/lib/appsignal/probes_spec.rb +6 -5
  114. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +51 -5
  115. data/spec/lib/appsignal/rack/event_handler_spec.rb +114 -10
  116. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +1 -1
  117. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +2 -35
  118. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +1 -1
  119. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
  120. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +3 -3
  121. data/spec/lib/appsignal/rack_spec.rb +63 -0
  122. data/spec/lib/appsignal/span_spec.rb +1 -3
  123. data/spec/lib/appsignal/transaction_spec.rb +1640 -1075
  124. data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
  125. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
  126. data/spec/lib/appsignal_spec.rb +601 -36
  127. data/spec/lib/puma/appsignal_spec.rb +0 -3
  128. data/spec/spec_helper.rb +5 -4
  129. data/spec/support/helpers/config_helpers.rb +2 -1
  130. data/spec/support/helpers/loader_helper.rb +21 -0
  131. data/spec/support/helpers/transaction_helpers.rb +44 -20
  132. data/spec/support/matchers/transaction.rb +15 -1
  133. data/spec/support/stubs/appsignal/loaders/loader_stub.rb +7 -0
  134. data/spec/support/testing.rb +47 -1
  135. metadata +19 -2
@@ -0,0 +1,167 @@
1
+ require "appsignal/integrations/shoryuken"
2
+
3
+ describe Appsignal::Integrations::ShoryukenMiddleware do
4
+ class DemoShoryukenWorker
5
+ end
6
+
7
+ let(:time) { "2010-01-01 10:01:00UTC" }
8
+ let(:worker_instance) { DemoShoryukenWorker.new }
9
+ let(:queue) { "some-funky-queue-name" }
10
+ let(:sqs_msg) { double(:message_id => "msg1", :attributes => {}) }
11
+ let(:body) { {} }
12
+ before { start_agent }
13
+ around { |example| keep_transactions { example.run } }
14
+
15
+ def perform_shoryuken_job(&block)
16
+ block ||= lambda {}
17
+ Timecop.freeze(Time.parse(time)) do
18
+ described_class.new.call(
19
+ worker_instance,
20
+ queue,
21
+ sqs_msg,
22
+ body,
23
+ &block
24
+ )
25
+ end
26
+ end
27
+
28
+ context "with a performance call" do
29
+ let(:sent_timestamp) { Time.parse("1976-11-18 0:00:00UTC").to_i * 1000 }
30
+ let(:sqs_msg) do
31
+ double(:message_id => "msg1", :attributes => { "SentTimestamp" => sent_timestamp })
32
+ end
33
+
34
+ context "with complex argument" do
35
+ let(:body) { { :foo => "Foo", :bar => "Bar" } }
36
+
37
+ it "wraps the job in a transaction with the correct params" do
38
+ expect { perform_shoryuken_job }.to change { created_transactions.length }.by(1)
39
+
40
+ transaction = last_transaction
41
+ expect(transaction).to have_id
42
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
43
+ expect(transaction).to have_action("DemoShoryukenWorker#perform")
44
+ expect(transaction).to_not have_error
45
+ expect(transaction).to include_event(
46
+ "body" => "",
47
+ "body_format" => Appsignal::EventFormatter::DEFAULT,
48
+ "count" => 1,
49
+ "name" => "perform_job.shoryuken",
50
+ "title" => ""
51
+ )
52
+ expect(transaction).to include_params("foo" => "Foo", "bar" => "Bar")
53
+ expect(transaction).to include_tags(
54
+ "message_id" => "msg1",
55
+ "queue" => queue,
56
+ "SentTimestamp" => sent_timestamp
57
+ )
58
+ expect(transaction).to have_queue_start(sent_timestamp)
59
+ expect(transaction).to be_completed
60
+ end
61
+
62
+ context "with parameter filtering" do
63
+ before do
64
+ start_agent("production")
65
+ Appsignal.config[:filter_parameters] = ["foo"]
66
+ end
67
+
68
+ it "filters selected arguments" do
69
+ perform_shoryuken_job
70
+
71
+ expect(last_transaction).to include_params("foo" => "[FILTERED]", "bar" => "Bar")
72
+ end
73
+ end
74
+ end
75
+
76
+ context "with a string as an argument" do
77
+ let(:body) { "foo bar" }
78
+
79
+ it "handles string arguments" do
80
+ perform_shoryuken_job
81
+
82
+ expect(last_transaction).to include_params("params" => body)
83
+ end
84
+ end
85
+
86
+ context "with primitive type as argument" do
87
+ let(:body) { 1 }
88
+
89
+ it "handles primitive types as arguments" do
90
+ perform_shoryuken_job
91
+
92
+ expect(last_transaction).to include_params("params" => body)
93
+ end
94
+ end
95
+ end
96
+
97
+ context "with exception" do
98
+ it "sets the exception on the transaction" do
99
+ expect do
100
+ expect do
101
+ perform_shoryuken_job { raise ExampleException, "error message" }
102
+ end.to raise_error(ExampleException)
103
+ end.to change { created_transactions.length }.by(1)
104
+
105
+ transaction = last_transaction
106
+ expect(transaction).to have_id
107
+ expect(transaction).to have_action("DemoShoryukenWorker#perform")
108
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
109
+ expect(transaction).to have_error("ExampleException", "error message")
110
+ expect(transaction).to be_completed
111
+ end
112
+ end
113
+
114
+ context "with batched jobs" do
115
+ let(:sqs_msg) do
116
+ [
117
+ double(
118
+ :message_id => "msg2",
119
+ :attributes => {
120
+ "SentTimestamp" => (Time.parse("1976-11-18 01:00:00UTC").to_i * 1000).to_s
121
+ }
122
+ ),
123
+ double(
124
+ :message_id => "msg1",
125
+ :attributes => { "SentTimestamp" => sent_timestamp.to_s }
126
+ )
127
+ ]
128
+ end
129
+ let(:body) do
130
+ [
131
+ "foo bar",
132
+ { :id => "123", :foo => "Foo", :bar => "Bar" }
133
+ ]
134
+ end
135
+ let(:sent_timestamp) { Time.parse("1976-11-18 01:00:00UTC").to_i * 1000 }
136
+
137
+ it "creates a transaction for the batch" do
138
+ expect do
139
+ perform_shoryuken_job {} # rubocop:disable Lint/EmptyBlock
140
+ end.to change { created_transactions.length }.by(1)
141
+
142
+ transaction = last_transaction
143
+ expect(transaction).to have_id
144
+ expect(transaction).to have_action("DemoShoryukenWorker#perform")
145
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
146
+ expect(transaction).to_not have_error
147
+ expect(transaction).to include_event(
148
+ "body" => "",
149
+ "body_format" => Appsignal::EventFormatter::DEFAULT,
150
+ "count" => 1,
151
+ "name" => "perform_job.shoryuken",
152
+ "title" => ""
153
+ )
154
+ expect(transaction).to include_params(
155
+ "msg2" => "foo bar",
156
+ "msg1" => { "id" => "123", "foo" => "Foo", "bar" => "Bar" }
157
+ )
158
+ expect(transaction).to include_tags(
159
+ "batch" => true,
160
+ "queue" => "some-funky-queue-name",
161
+ "SentTimestamp" => sent_timestamp.to_s # Earliest/oldest timestamp from messages
162
+ )
163
+ # Queue time based on earliest/oldest timestamp from messages
164
+ expect(transaction).to have_queue_start(sent_timestamp)
165
+ end
166
+ end
167
+ end
@@ -243,7 +243,7 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
243
243
 
244
244
  context "with parameter filtering" do
245
245
  before do
246
- Appsignal.config = project_fixture_config("production")
246
+ start_agent("production")
247
247
  Appsignal.config[:filter_parameters] = ["foo"]
248
248
  end
249
249
 
@@ -362,7 +362,7 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
362
362
  perform_sidekiq_job { raise error, "uh oh" }
363
363
  end.to raise_error(error)
364
364
 
365
- expect(transaction).to have_id(jid)
365
+ expect(transaction).to have_id
366
366
  expect(transaction).to have_namespace(namespace)
367
367
  expect(transaction).to have_action("TestClass#perform")
368
368
  expect(transaction).to have_error("ExampleException", "uh oh")
@@ -373,7 +373,7 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
373
373
  )
374
374
  expect(transaction).to_not include_environment
375
375
  expect(transaction).to include_params(expected_args)
376
- expect(transaction).to_not include_tags
376
+ expect(transaction).to include_tags("request_id" => jid)
377
377
  expect(transaction).to_not include_breadcrumbs
378
378
  expect_transaction_to_have_sidekiq_event(transaction)
379
379
  end
@@ -384,7 +384,7 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
384
384
  include RailsHelper
385
385
 
386
386
  it "reports the worker name as the action, copies the namespace and tags" do
387
- Appsignal.config = project_fixture_config("production")
387
+ start_agent("production")
388
388
  with_rails_error_reporter do
389
389
  perform_sidekiq_job do
390
390
  Appsignal.tag_job("test_tag" => "value")
@@ -418,11 +418,11 @@ describe Appsignal::Integrations::SidekiqMiddleware, :with_yaml_parse_error => f
418
418
  .with("sidekiq_queue_job_count", 1, { :queue => "default", :status => :processed })
419
419
  perform_sidekiq_job
420
420
 
421
- expect(transaction).to have_id(jid)
421
+ expect(transaction).to have_id
422
422
  expect(transaction).to have_namespace(namespace)
423
423
  expect(transaction).to have_action("TestClass#perform")
424
424
  expect(transaction).to_not have_error
425
- expect(transaction).to_not include_tags
425
+ expect(transaction).to include_tags("request_id" => jid)
426
426
  expect(transaction).to_not include_environment
427
427
  expect(transaction).to_not include_breadcrumbs
428
428
  expect(transaction).to_not include_params(expected_args)
@@ -527,6 +527,15 @@ if DependencyHelper.active_job_present?
527
527
  end
528
528
  end
529
529
  around do |example|
530
+ with_rails_error_reporter do
531
+ keep_transactions do
532
+ Sidekiq::Testing.fake! do
533
+ example.run
534
+ end
535
+ end
536
+ end
537
+ end
538
+ before do
530
539
  start_agent
531
540
  Appsignal.internal_logger = test_logger(log)
532
541
  ActiveJob::Base.queue_adapter = :sidekiq
@@ -551,13 +560,6 @@ if DependencyHelper.active_job_present?
551
560
  Sidekiq::Testing.server_middleware do |chain|
552
561
  chain.add Appsignal::Integrations::SidekiqMiddleware
553
562
  end
554
- with_rails_error_reporter do
555
- keep_transactions do
556
- Sidekiq::Testing.fake! do
557
- example.run
558
- end
559
- end
560
- end
561
563
  end
562
564
  after do
563
565
  Object.send(:remove_const, :ActiveJobSidekiqTestJob)
@@ -1,110 +1,15 @@
1
- if DependencyHelper.sinatra_present?
2
- require "appsignal/integrations/sinatra"
3
-
4
- def install_sinatra_integration
5
- load File.expand_path("lib/appsignal/integrations/sinatra.rb", project_dir)
6
- end
7
-
8
- # "Uninstall" the AppSignal integration
9
- def uninstall_sinatra_integration
10
- expected_middleware = [
11
- Rack::Events,
12
- Appsignal::Rack::SinatraBaseInstrumentation
13
- ]
14
- Sinatra::Base.instance_variable_get(:@middleware).delete_if do |middleware|
15
- expected_middleware.include?(middleware.first)
16
- end
17
- end
18
-
1
+ if DependencyHelper.padrino_present?
19
2
  describe "Sinatra integration" do
20
- before do
21
- Appsignal.config = nil
22
- end
23
- after { uninstall_sinatra_integration }
24
-
25
- context "when active" do
26
- before { allow(Appsignal).to receive(:active?).and_return(true) }
27
-
28
- it "does not start AppSignal again" do
29
- expect(Appsignal::Config).to_not receive(:new)
30
- expect(Appsignal).to_not receive(:start)
31
- install_sinatra_integration
32
- end
33
-
34
- it "adds the instrumentation middleware to Sinatra::Base" do
35
- install_sinatra_integration
36
- middlewares = Sinatra::Base.middleware.to_a
37
- expect(middlewares).to include(
38
- [Rack::Events, [[instance_of(Appsignal::Rack::EventHandler)]], nil]
39
- )
40
- expect(middlewares).to include(
41
- [Appsignal::Rack::SinatraBaseInstrumentation, [], nil]
42
- )
43
- end
44
- end
45
-
46
- context "when not active" do
47
- context "Appsignal.internal_logger" do
48
- subject { Appsignal.internal_logger }
49
-
50
- it "sets a logger" do
51
- install_sinatra_integration
52
- is_expected.to be_a Logger
53
- end
54
- end
55
-
56
- describe "middleware" do
57
- context "when AppSignal is not active" do
58
- it "does not add the instrumentation middleware to Sinatra::Base" do
59
- install_sinatra_integration
60
- middlewares = Sinatra::Base.middleware.to_a
61
- expect(middlewares).to_not include(
62
- [Appsignal::Rack::SinatraBaseInstrumentation, [], nil]
63
- )
64
- expect(middlewares).to_not include(
65
- [Rack::Events, [Appsignal::Rack::EventHandler], nil]
66
- )
67
- end
68
- end
69
-
70
- context "when the new AppSignal config is active" do
71
- it "adds the instrumentation middleware to Sinatra::Base" do
72
- ENV["APPSIGNAL_APP_NAME"] = "My Sinatra app name"
73
- ENV["APPSIGNAL_APP_ENV"] = "test"
74
- ENV["APPSIGNAL_PUSH_API_KEY"] = "my-key"
75
-
76
- install_sinatra_integration
77
- middlewares = Sinatra::Base.middleware.to_a
78
- expect(middlewares).to include(
79
- [Rack::Events, [[Appsignal::Rack::EventHandler]], nil],
80
- [Appsignal::Rack::SinatraBaseInstrumentation, [], nil]
81
- )
82
- end
83
- end
84
- end
85
-
86
- describe "environment" do
87
- subject { Appsignal.config.env }
88
-
89
- context "without APPSIGNAL_APP_ENV" do
90
- before { install_sinatra_integration }
91
-
92
- it "uses the app environment" do
93
- expect(subject).to eq("test")
94
- end
95
- end
3
+ it "loads the Sinatra loader" do
4
+ ENV["APPSIGNAL_APP_NAME"] = "test/sinatra"
5
+ ENV["APPSIGNAL_PUSH_API_KEY"] = "test-key"
96
6
 
97
- context "with APPSIGNAL_APP_ENV" do
98
- before do
99
- ENV["APPSIGNAL_APP_ENV"] = "env-staging"
100
- install_sinatra_integration
101
- end
7
+ require "appsignal/integrations/sinatra"
102
8
 
103
- it "uses the environment variable" do
104
- expect(subject).to eq("env-staging")
105
- end
106
- end
107
- end
9
+ expect(Appsignal::Loaders.instances).to include(
10
+ :sinatra => kind_of(Appsignal::Loaders::SinatraLoader)
11
+ )
12
+ expect(Appsignal.active?).to be(true)
108
13
  end
109
14
  end
110
15
  end
@@ -18,7 +18,11 @@ if DependencyHelper.webmachine_present?
18
18
  Webmachine::Request.new(
19
19
  "GET",
20
20
  "http://google.com:80/foo?param1=value1&param2=value2",
21
- {},
21
+ {
22
+ "REQUEST_METHOD" => "GET",
23
+ "PATH_INFO" => "/some/path",
24
+ "ignored_header" => "something"
25
+ },
22
26
  nil
23
27
  )
24
28
  end
@@ -81,6 +85,14 @@ if DependencyHelper.webmachine_present?
81
85
  expect(last_transaction).to include_params("param1" => "value1", "param2" => "value2")
82
86
  end
83
87
 
88
+ it "sets the headers" do
89
+ fsm.run
90
+ expect(last_transaction).to include_environment(
91
+ "REQUEST_METHOD" => "GET",
92
+ "PATH_INFO" => "/some/path"
93
+ )
94
+ end
95
+
84
96
  it "closes the transaction" do
85
97
  fsm.run
86
98
  expect(last_transaction).to be_completed
@@ -0,0 +1,12 @@
1
+ if DependencyHelper.grape_present?
2
+ describe "Appsignal::Loaders::PadrinoLoader" do
3
+ describe "#on_load" do
4
+ it "ensures the Grape middleware is loaded" do
5
+ load_loader(:grape)
6
+
7
+ # Calling this doesn't raise a NameError
8
+ Appsignal::Rack::GrapeMiddleware
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,95 @@
1
+ if DependencyHelper.hanami_present?
2
+ describe "Appsignal::Loaders::HanamiLoader" do
3
+ before { Appsignal.config = nil }
4
+
5
+ describe "#on_load" do
6
+ it "registers Hanami default config" do
7
+ load_loader(:hanami)
8
+
9
+ expect(Appsignal::Config.loader_defaults).to include([
10
+ :hanami,
11
+ {
12
+ :env => :test,
13
+ :root_path => Dir.pwd
14
+ }
15
+ ])
16
+ end
17
+ end
18
+
19
+ describe "#on_start" do
20
+ before do
21
+ allow(::Hanami::Action).to receive(:prepend)
22
+ load_loader(:hanami)
23
+ start_loader(:hanami)
24
+ end
25
+ after { uninstall_hanami_middleware }
26
+
27
+ def uninstall_hanami_middleware
28
+ middleware_stack = ::Hanami.app.config.middleware.stack[::Hanami::Router::DEFAULT_PREFIX]
29
+ middleware_stack.delete_if do |middleware|
30
+ middleware.first == Appsignal::Rack::HanamiMiddleware ||
31
+ middleware.first == Rack::Events
32
+ end
33
+ end
34
+
35
+ it "adds the instrumentation middleware to Sinatra::Base" do
36
+ expect(::Hanami.app.config.middleware.stack[::Hanami::Router::DEFAULT_PREFIX])
37
+ .to include(
38
+ [Rack::Events, [[kind_of(Appsignal::Rack::EventHandler)]], *hanami_middleware_options],
39
+ [Appsignal::Rack::HanamiMiddleware, [], *hanami_middleware_options]
40
+ )
41
+ end
42
+
43
+ it "prepends the integration to Hanami::Action" do
44
+ expect(::Hanami::Action)
45
+ .to have_received(:prepend).with(Appsignal::Loaders::HanamiLoader::HanamiIntegration)
46
+ end
47
+
48
+ def hanami_middleware_options
49
+ if DependencyHelper.hanami2_1_present?
50
+ [{}, nil]
51
+ else
52
+ [nil]
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "Appsignal::Loaders::HanamiLoader::HanamiIntegration" do
58
+ let(:transaction) { http_request_transaction }
59
+ let(:app) { HanamiApp::Actions::Books::Index }
60
+ around { |example| keep_transactions { example.run } }
61
+ before do
62
+ expect(::Hanami.app.config).to receive(:root).and_return(project_fixture_path)
63
+ Appsignal.load(:hanami)
64
+ start_agent
65
+ end
66
+
67
+ def make_request(env)
68
+ action = app.new
69
+ action.call(env)
70
+ end
71
+
72
+ describe "#call" do
73
+ context "without an active transaction" do
74
+ let(:env) { {} }
75
+
76
+ it "does not set the action name" do
77
+ make_request(env)
78
+
79
+ expect(transaction).to_not have_action
80
+ end
81
+ end
82
+
83
+ context "with an active transaction" do
84
+ let(:env) { { Appsignal::Rack::APPSIGNAL_TRANSACTION => transaction } }
85
+
86
+ it "sets action name on the transaction" do
87
+ make_request(env)
88
+
89
+ expect(transaction).to have_action("HanamiApp::Actions::Books::Index")
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end