appsignal 3.11.0-java → 3.12.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +115 -0
- data/Rakefile +1 -1
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +150 -32
- data/lib/appsignal/demo.rb +1 -6
- data/lib/appsignal/helpers/instrumentation.rb +2 -2
- data/lib/appsignal/integrations/grape.rb +7 -0
- data/lib/appsignal/integrations/hanami.rb +8 -43
- data/lib/appsignal/integrations/padrino.rb +8 -73
- data/lib/appsignal/integrations/railtie.rb +35 -13
- data/lib/appsignal/integrations/sinatra.rb +8 -19
- data/lib/appsignal/loaders/grape.rb +13 -0
- data/lib/appsignal/loaders/hanami.rb +40 -0
- data/lib/appsignal/loaders/padrino.rb +68 -0
- data/lib/appsignal/loaders/sinatra.rb +24 -0
- data/lib/appsignal/loaders.rb +92 -0
- data/lib/appsignal/rack/abstract_middleware.rb +2 -1
- data/lib/appsignal/rack/event_handler.rb +5 -5
- data/lib/appsignal/rack.rb +6 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +163 -9
- data/spec/lib/appsignal/cli/demo_spec.rb +0 -1
- data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1
- data/spec/lib/appsignal/config_spec.rb +153 -1
- data/spec/lib/appsignal/demo_spec.rb +1 -2
- data/spec/lib/appsignal/environment_spec.rb +4 -2
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +3 -6
- data/spec/lib/appsignal/hooks/activejob_spec.rb +3 -3
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +4 -7
- data/spec/lib/appsignal/hooks/excon_spec.rb +3 -6
- data/spec/lib/appsignal/hooks/gvl_spec.rb +2 -2
- data/spec/lib/appsignal/hooks/http_spec.rb +1 -3
- data/spec/lib/appsignal/hooks/net_http_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -8
- data/spec/lib/appsignal/hooks/redis_spec.rb +3 -6
- data/spec/lib/appsignal/hooks/resque_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/sequel_spec.rb +3 -5
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +2 -2
- data/spec/lib/appsignal/integrations/grape_spec.rb +36 -0
- data/spec/lib/appsignal/integrations/hanami_spec.rb +9 -178
- data/spec/lib/appsignal/integrations/http_spec.rb +1 -5
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +4 -2
- data/spec/lib/appsignal/integrations/net_http_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/object_spec.rb +1 -3
- data/spec/lib/appsignal/integrations/padrino_spec.rb +8 -330
- data/spec/lib/appsignal/integrations/railtie_spec.rb +275 -191
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +11 -9
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +9 -104
- data/spec/lib/appsignal/loaders/grape_spec.rb +12 -0
- data/spec/lib/appsignal/loaders/hanami_spec.rb +95 -0
- data/spec/lib/appsignal/loaders/padrino_spec.rb +277 -0
- data/spec/lib/appsignal/loaders/sinatra_spec.rb +47 -0
- data/spec/lib/appsignal/loaders_spec.rb +137 -0
- data/spec/lib/appsignal/probes/sidekiq_spec.rb +1 -1
- data/spec/lib/appsignal/probes_spec.rb +6 -5
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +3 -2
- data/spec/lib/appsignal/rack/event_handler_spec.rb +33 -0
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +1 -1
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +2 -35
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +1 -1
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +3 -3
- data/spec/lib/appsignal/span_spec.rb +1 -3
- data/spec/lib/appsignal/transaction_spec.rb +61 -70
- data/spec/lib/appsignal_spec.rb +284 -26
- data/spec/lib/puma/appsignal_spec.rb +0 -3
- data/spec/spec_helper.rb +5 -4
- data/spec/support/helpers/config_helpers.rb +2 -1
- data/spec/support/helpers/loader_helper.rb +21 -0
- data/spec/support/matchers/transaction.rb +3 -2
- data/spec/support/stubs/appsignal/loaders/loader_stub.rb +7 -0
- data/spec/support/testing.rb +46 -0
- metadata +15 -2
@@ -1,110 +1,15 @@
|
|
1
|
-
if DependencyHelper.
|
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
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
98
|
-
before do
|
99
|
-
ENV["APPSIGNAL_APP_ENV"] = "env-staging"
|
100
|
-
install_sinatra_integration
|
101
|
-
end
|
7
|
+
require "appsignal/integrations/sinatra"
|
102
8
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
@@ -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
|
@@ -0,0 +1,277 @@
|
|
1
|
+
if DependencyHelper.padrino_present?
|
2
|
+
describe "Appsignal::Loaders::PadrinoLoader" do
|
3
|
+
before { Appsignal.config = nil }
|
4
|
+
|
5
|
+
describe "#on_load" do
|
6
|
+
it "registers Padrino default config" do
|
7
|
+
load_loader(:padrino)
|
8
|
+
|
9
|
+
expect(Appsignal::Config.loader_defaults).to include([
|
10
|
+
:padrino,
|
11
|
+
{
|
12
|
+
:env => :test,
|
13
|
+
:root_path => Padrino.mounted_root
|
14
|
+
}
|
15
|
+
])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#on_start" do
|
20
|
+
let(:callbacks) { { :before_load => nil } }
|
21
|
+
before do
|
22
|
+
allow(Padrino).to receive(:before_load)
|
23
|
+
.and_wrap_original do |original_method, *args, &block|
|
24
|
+
callbacks[:before_load] = block
|
25
|
+
original_method.call(*args, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
after { uninstall_padrino_integration }
|
29
|
+
|
30
|
+
def uninstall_padrino_integration
|
31
|
+
expected_middleware = [
|
32
|
+
Rack::Events,
|
33
|
+
Appsignal::Rack::SinatraBaseInstrumentation
|
34
|
+
]
|
35
|
+
Padrino.middleware.delete_if do |middleware|
|
36
|
+
expected_middleware.include?(middleware.first)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "adds the instrumentation middleware to Padrino" do
|
41
|
+
load_loader(:padrino)
|
42
|
+
start_loader(:padrino)
|
43
|
+
|
44
|
+
callbacks[:before_load].call
|
45
|
+
|
46
|
+
middlewares = Padrino.middleware
|
47
|
+
expect(middlewares).to include(
|
48
|
+
[Rack::Events, [[instance_of(Appsignal::Rack::EventHandler)]], nil]
|
49
|
+
)
|
50
|
+
expect(middlewares).to include(
|
51
|
+
[
|
52
|
+
Appsignal::Rack::SinatraBaseInstrumentation,
|
53
|
+
[
|
54
|
+
:instrument_event_name => "process_action.padrino"
|
55
|
+
],
|
56
|
+
nil
|
57
|
+
]
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "Padrino integration" do
|
63
|
+
class PadrinoClassWithRouter
|
64
|
+
include Padrino::Routing
|
65
|
+
end
|
66
|
+
|
67
|
+
let(:base) { double }
|
68
|
+
let(:router) { PadrinoClassWithRouter.new }
|
69
|
+
let(:env) { {} }
|
70
|
+
# TODO: use an instance double
|
71
|
+
let(:settings) { double(:name => "TestApp") }
|
72
|
+
around { |example| keep_transactions { example.run } }
|
73
|
+
before { Appsignal.config = nil }
|
74
|
+
|
75
|
+
describe "routes" do
|
76
|
+
let(:env) do
|
77
|
+
{
|
78
|
+
"REQUEST_METHOD" => "GET",
|
79
|
+
"PATH_INFO" => path,
|
80
|
+
"REQUEST_PATH" => path,
|
81
|
+
"rack.input" => StringIO.new
|
82
|
+
}
|
83
|
+
end
|
84
|
+
let(:app) do
|
85
|
+
Class.new(Padrino::Application) do
|
86
|
+
def self.name
|
87
|
+
"PadrinoTestApp"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
let(:response) { app.call(env) }
|
92
|
+
|
93
|
+
def fetch_body(body)
|
94
|
+
if body.respond_to?(:response)
|
95
|
+
_, _, nested_body = body.response.to_a
|
96
|
+
fetch_body(nested_body)
|
97
|
+
elsif body.respond_to?(:to_ary)
|
98
|
+
body.to_ary
|
99
|
+
else
|
100
|
+
body
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
RSpec::Matchers.define :match_response do |expected_status, expected_body|
|
105
|
+
match do |response|
|
106
|
+
status, _headers, potential_body = response
|
107
|
+
body = fetch_body(potential_body)
|
108
|
+
|
109
|
+
matches_body =
|
110
|
+
if expected_body.is_a?(Regexp)
|
111
|
+
body.join =~ expected_body
|
112
|
+
else
|
113
|
+
body == [expected_body].compact
|
114
|
+
end
|
115
|
+
status == expected_status && matches_body
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "when AppSignal is not active" do
|
120
|
+
let(:path) { "/foo" }
|
121
|
+
before { app.controllers { get(:foo) { "content" } } }
|
122
|
+
|
123
|
+
it "does not instrument the request" do
|
124
|
+
expect do
|
125
|
+
expect(response).to match_response(200, "content")
|
126
|
+
end.to_not(change { created_transactions.count })
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "when AppSignal is active" do
|
131
|
+
let(:transaction) { http_request_transaction }
|
132
|
+
before do
|
133
|
+
start_agent
|
134
|
+
set_current_transaction(transaction)
|
135
|
+
end
|
136
|
+
|
137
|
+
context "with not existing route" do
|
138
|
+
let(:path) { "/404" }
|
139
|
+
|
140
|
+
it "instruments the request" do
|
141
|
+
expect(response).to match_response(404, /^GET /404/)
|
142
|
+
expect(last_transaction).to have_action("PadrinoTestApp#unknown")
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "when Sinatra tells us it's a static file" do
|
147
|
+
let(:path) { "/static" }
|
148
|
+
before do
|
149
|
+
env["sinatra.static_file"] = true
|
150
|
+
app.controllers { get(:static) { "Static!" } }
|
151
|
+
end
|
152
|
+
|
153
|
+
it "does not instrument the request" do
|
154
|
+
expect(response).to match_response(200, "Static!")
|
155
|
+
expect(last_transaction).to_not have_action
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Older Padrino versions don't support `action` (v11.0+)
|
160
|
+
context "without #action on Sinatra::Request" do
|
161
|
+
let(:path) { "/my_original_path/10" }
|
162
|
+
before do
|
163
|
+
allow_any_instance_of(Sinatra::Request).to receive(:action).and_return(nil)
|
164
|
+
app.controllers { get(:my_original_path, :with => :id) { "content" } }
|
165
|
+
end
|
166
|
+
|
167
|
+
it "falls back on Sinatra::Request#route_obj.original_path" do
|
168
|
+
expect(response).to match_response(200, "content")
|
169
|
+
expect(last_transaction).to have_action("PadrinoTestApp:/my_original_path/:id")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "without Sinatra::Request#route_obj.original_path" do
|
174
|
+
let(:path) { "/my_original_path" }
|
175
|
+
before do
|
176
|
+
allow_any_instance_of(Sinatra::Request).to receive(:action).and_return(nil)
|
177
|
+
allow_any_instance_of(Sinatra::Request).to receive(:route_obj).and_return(nil)
|
178
|
+
app.controllers { get(:my_original_path) { "content" } }
|
179
|
+
end
|
180
|
+
|
181
|
+
it "falls back on app name" do
|
182
|
+
expect(response).to match_response(200, "content")
|
183
|
+
expect(last_transaction).to have_action("PadrinoTestApp#unknown")
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "with existing route" do
|
188
|
+
let(:path) { "/" }
|
189
|
+
def make_request
|
190
|
+
expect(response).to match_response(200, "content")
|
191
|
+
end
|
192
|
+
|
193
|
+
context "with action name as symbol" do
|
194
|
+
context "with :index helper" do
|
195
|
+
before do
|
196
|
+
# :index == "/"
|
197
|
+
app.controllers { get(:index) { "content" } }
|
198
|
+
end
|
199
|
+
|
200
|
+
it "sets the action with the app name and action name" do
|
201
|
+
make_request
|
202
|
+
expect(last_transaction).to have_action("PadrinoTestApp:#index")
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "with custom action name" do
|
207
|
+
let(:path) { "/foo" }
|
208
|
+
before do
|
209
|
+
app.controllers { get(:foo) { "content" } }
|
210
|
+
end
|
211
|
+
|
212
|
+
it "sets the action with the app name and action name" do
|
213
|
+
make_request
|
214
|
+
expect(last_transaction).to have_action("PadrinoTestApp:#foo")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context "with an action defined with a path" do
|
220
|
+
context "with root path" do
|
221
|
+
before do
|
222
|
+
# :index == "/"
|
223
|
+
app.controllers { get("/") { "content" } }
|
224
|
+
end
|
225
|
+
|
226
|
+
it "sets the action with the app name and action path" do
|
227
|
+
make_request
|
228
|
+
expect(last_transaction).to have_action("PadrinoTestApp:#/")
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context "with custom path" do
|
233
|
+
let(:path) { "/foo" }
|
234
|
+
before do
|
235
|
+
app.controllers { get("/foo") { "content" } }
|
236
|
+
end
|
237
|
+
|
238
|
+
it "sets the action with the app name and action path" do
|
239
|
+
make_request
|
240
|
+
expect(last_transaction).to have_action("PadrinoTestApp:#/foo")
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
context "with controller" do
|
246
|
+
let(:path) { "/my_controller" }
|
247
|
+
|
248
|
+
context "with controller as name" do
|
249
|
+
before do
|
250
|
+
# :index == "/"
|
251
|
+
app.controllers(:my_controller) { get(:index) { "content" } }
|
252
|
+
end
|
253
|
+
|
254
|
+
it "sets the action with the app name, controller name and action name" do
|
255
|
+
make_request
|
256
|
+
expect(last_transaction).to have_action("PadrinoTestApp:my_controller#index")
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context "with controller as path" do
|
261
|
+
before do
|
262
|
+
# :index == "/"
|
263
|
+
app.controllers("/my_controller") { get(:index) { "content" } }
|
264
|
+
end
|
265
|
+
|
266
|
+
it "sets the action with the app name, controller name and action path" do
|
267
|
+
make_request
|
268
|
+
expect(last_transaction).to have_action("PadrinoTestApp:/my_controller#index")
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
if DependencyHelper.sinatra_present?
|
2
|
+
describe "Appsignal::Loaders::SinatraLoader" do
|
3
|
+
before { Appsignal.config = nil }
|
4
|
+
|
5
|
+
describe "#on_load" do
|
6
|
+
it "registers Sinatra default config" do
|
7
|
+
::Sinatra::Application.settings.root = "/some/path"
|
8
|
+
load_loader(:sinatra)
|
9
|
+
|
10
|
+
expect(Appsignal::Config.loader_defaults).to include([
|
11
|
+
:sinatra,
|
12
|
+
{
|
13
|
+
:env => :test,
|
14
|
+
:root_path => "/some/path"
|
15
|
+
}
|
16
|
+
])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#on_start" do
|
21
|
+
after { uninstall_sinatra_integration }
|
22
|
+
|
23
|
+
def uninstall_sinatra_integration
|
24
|
+
expected_middleware = [
|
25
|
+
Rack::Events,
|
26
|
+
Appsignal::Rack::SinatraBaseInstrumentation
|
27
|
+
]
|
28
|
+
Sinatra::Base.instance_variable_get(:@middleware).delete_if do |middleware|
|
29
|
+
expected_middleware.include?(middleware.first)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "adds the instrumentation middleware to Sinatra::Base" do
|
34
|
+
load_loader(:sinatra)
|
35
|
+
start_loader(:sinatra)
|
36
|
+
|
37
|
+
middlewares = Sinatra::Base.middleware.to_a
|
38
|
+
expect(middlewares).to include(
|
39
|
+
[Rack::Events, [[instance_of(Appsignal::Rack::EventHandler)]], nil]
|
40
|
+
)
|
41
|
+
expect(middlewares).to include(
|
42
|
+
[Appsignal::Rack::SinatraBaseInstrumentation, [], nil]
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
describe Appsignal::Loaders do
|
2
|
+
describe ".register" do
|
3
|
+
before do
|
4
|
+
define_loader(:test_loader) do
|
5
|
+
def on_load
|
6
|
+
puts "do something on_load"
|
7
|
+
register_config_defaults(
|
8
|
+
:root_path => "/some/path",
|
9
|
+
:env => "test env",
|
10
|
+
:active => false
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "registers a loader" do
|
17
|
+
define_loader(:test_loader)
|
18
|
+
expect(Appsignal::Loaders.loaders).to have_key(:test_loader)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ".unregister" do
|
23
|
+
it "unregisters a loader" do
|
24
|
+
define_loader(:test_loader)
|
25
|
+
expect(Appsignal::Loaders.loaders).to have_key(:test_loader)
|
26
|
+
|
27
|
+
Appsignal::Loaders.unregister(:test_loader)
|
28
|
+
expect(Appsignal::Loaders.loaders).to_not have_key(:test_loader)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ".load" do
|
33
|
+
it "calls the Loader's on_loader method" do
|
34
|
+
Appsignal::Testing.store[:loader_loaded] = 0
|
35
|
+
define_loader(:test_loader) do
|
36
|
+
def on_load
|
37
|
+
Appsignal::Testing.store[:loader_loaded] += 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
Appsignal::Loaders.load(:test_loader)
|
41
|
+
|
42
|
+
expect(Appsignal::Testing.store[:loader_loaded]).to eq(1)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "registers config defaults" do
|
46
|
+
define_loader(:test_loader) do
|
47
|
+
def on_load
|
48
|
+
register_config_defaults(:my_option => true)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
Appsignal::Loaders.load(:test_loader)
|
52
|
+
|
53
|
+
expect(Appsignal::Config.loader_defaults).to eq([[:test_loader, { :my_option => true }]])
|
54
|
+
end
|
55
|
+
|
56
|
+
it "does not load errors that aren't registered" do
|
57
|
+
logs =
|
58
|
+
capture_logs do
|
59
|
+
Appsignal::Loaders.load(:unknown_loader)
|
60
|
+
end
|
61
|
+
|
62
|
+
expect(logs).to contains_log(:warn, "No loader found with the name 'unknown_loader'.")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "loads the loader file on load" do
|
66
|
+
expect(Appsignal::Loaders.registered?(:loader_stub)).to be_falsy
|
67
|
+
Appsignal::Loaders.load(:loader_stub)
|
68
|
+
|
69
|
+
expect(Appsignal::Loaders.registered?(:loader_stub)).to be_truthy
|
70
|
+
end
|
71
|
+
|
72
|
+
it "does not error when a loader has no on_load method" do
|
73
|
+
define_loader(:test_loader) do
|
74
|
+
# Do nothing
|
75
|
+
end
|
76
|
+
Appsignal::Loaders.load(:test_loader)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "logs an error when an error occurs on load" do
|
80
|
+
define_loader(:test_loader) do
|
81
|
+
def on_load
|
82
|
+
raise ExampleStandardError, "uh oh"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
logs =
|
86
|
+
capture_logs do
|
87
|
+
Appsignal::Loaders.load(:test_loader)
|
88
|
+
end
|
89
|
+
|
90
|
+
expect(logs).to contains_log(
|
91
|
+
:error,
|
92
|
+
"An error occurred while loading the 'test_loader' loader: ExampleStandardError: uh oh"
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe ".start" do
|
98
|
+
it "starts all loaded loaders" do
|
99
|
+
Appsignal::Testing.store[:loader_started] = 0
|
100
|
+
define_loader(:test_loader) do
|
101
|
+
def on_start
|
102
|
+
Appsignal::Testing.store[:loader_started] += 1
|
103
|
+
end
|
104
|
+
end
|
105
|
+
Appsignal::Loaders.load(:test_loader)
|
106
|
+
Appsignal::Loaders.start
|
107
|
+
|
108
|
+
expect(Appsignal::Testing.store[:loader_started]).to eq(1)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "does not error when a loader has no on_start method" do
|
112
|
+
define_loader(:test_loader) do
|
113
|
+
# Do nothing
|
114
|
+
end
|
115
|
+
Appsignal::Loaders.load(:test_loader)
|
116
|
+
Appsignal::Loaders.start
|
117
|
+
end
|
118
|
+
|
119
|
+
it "logs an error when an error occurs on start" do
|
120
|
+
define_loader(:test_loader) do
|
121
|
+
def on_start
|
122
|
+
raise ExampleStandardError, "uh oh"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
logs =
|
126
|
+
capture_logs do
|
127
|
+
Appsignal::Loaders.load(:test_loader)
|
128
|
+
Appsignal::Loaders.start
|
129
|
+
end
|
130
|
+
|
131
|
+
expect(logs).to contains_log(
|
132
|
+
:error,
|
133
|
+
"An error occurred while starting the 'test_loader' loader: ExampleStandardError: uh oh"
|
134
|
+
)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|