appsignal 4.0.4 → 4.0.6
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/.github/workflows/ci.yml +151 -16
- data/CHANGELOG.md +42 -0
- data/build_matrix.yml +2 -1
- data/ext/agent.rb +27 -27
- data/gemfiles/que-1.gemfile +5 -0
- data/gemfiles/que-2.gemfile +5 -0
- data/lib/appsignal/check_in/scheduler.rb +3 -4
- data/lib/appsignal/config.rb +7 -0
- data/lib/appsignal/hooks/at_exit.rb +1 -0
- data/lib/appsignal/hooks/puma.rb +5 -1
- data/lib/appsignal/integrations/puma.rb +45 -0
- data/lib/appsignal/integrations/que.rb +8 -2
- data/lib/appsignal/rack/abstract_middleware.rb +3 -47
- data/lib/appsignal/rack/event_handler.rb +2 -0
- data/lib/appsignal/rack/hanami_middleware.rb +5 -1
- data/lib/appsignal/rack.rb +68 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/check_in/cron_spec.rb +134 -134
- data/spec/lib/appsignal/check_in/scheduler_spec.rb +297 -224
- data/spec/lib/appsignal/config_spec.rb +13 -0
- data/spec/lib/appsignal/hooks/at_exit_spec.rb +11 -0
- data/spec/lib/appsignal/hooks/puma_spec.rb +31 -23
- data/spec/lib/appsignal/integrations/puma_spec.rb +150 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +56 -21
- data/spec/lib/appsignal/probes_spec.rb +4 -6
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +41 -122
- data/spec/lib/appsignal/rack_spec.rb +180 -0
- data/spec/lib/appsignal/transaction_spec.rb +96 -92
- data/spec/spec_helper.rb +6 -7
- data/spec/support/helpers/api_request_helper.rb +40 -0
- data/spec/support/helpers/config_helpers.rb +2 -1
- data/spec/support/helpers/dependency_helper.rb +5 -0
- data/spec/support/matchers/contains_log.rb +10 -3
- data/spec/support/mocks/hash_like.rb +10 -0
- data/spec/support/mocks/puma_mock.rb +43 -0
- data/spec/support/testing.rb +9 -0
- metadata +8 -3
- data/gemfiles/que.gemfile +0 -5
@@ -61,3 +61,183 @@ describe Appsignal::Rack::Utils do
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
|
+
|
65
|
+
describe Appsignal::Rack::ApplyRackRequest do
|
66
|
+
describe "#apply_to" do
|
67
|
+
let(:merged_env) do
|
68
|
+
Rack::MockRequest.env_for(
|
69
|
+
"/some/path",
|
70
|
+
{
|
71
|
+
"REQUEST_METHOD" => "GET",
|
72
|
+
:params => { "page" => 2, "query" => "lorem" },
|
73
|
+
"rack.session" => { "session" => "data", "user_id" => 123 }
|
74
|
+
}.merge(env)
|
75
|
+
)
|
76
|
+
end
|
77
|
+
let(:env) { {} }
|
78
|
+
let(:request) { ::Rack::Request.new(merged_env) }
|
79
|
+
let(:options) { {} }
|
80
|
+
let(:helper) { described_class.new(request, options) }
|
81
|
+
let(:transaction) { http_request_transaction }
|
82
|
+
before { start_agent }
|
83
|
+
|
84
|
+
def apply_to(transaction)
|
85
|
+
helper.apply_to(transaction)
|
86
|
+
transaction._sample
|
87
|
+
end
|
88
|
+
|
89
|
+
it "sets request metadata" do
|
90
|
+
apply_to(transaction)
|
91
|
+
|
92
|
+
expect(transaction).to include_metadata(
|
93
|
+
"method" => "GET",
|
94
|
+
"path" => "/some/path"
|
95
|
+
)
|
96
|
+
expect(transaction).to include_environment(
|
97
|
+
"REQUEST_METHOD" => "GET",
|
98
|
+
"PATH_INFO" => "/some/path"
|
99
|
+
# and more, but we don't need to test Rack mock defaults
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
context "with an invalid HTTP request method" do
|
104
|
+
let(:env) { { "REQUEST_METHOD" => "FOO" } }
|
105
|
+
|
106
|
+
it "stores the invalid HTTP request method" do
|
107
|
+
apply_to(transaction)
|
108
|
+
|
109
|
+
expect(transaction).to include_metadata("method" => "FOO")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when fetching the request method raises an error" do
|
114
|
+
class BrokenRequestMethodRequest < Rack::Request
|
115
|
+
def request_method
|
116
|
+
raise "uh oh!"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
let(:env) { { "REQUEST_METHOD" => "FOO" } }
|
121
|
+
let(:request) { BrokenRequestMethodRequest.new(merged_env) }
|
122
|
+
|
123
|
+
it "does not store the invalid HTTP request method" do
|
124
|
+
logs = capture_logs { apply_to(transaction) }
|
125
|
+
|
126
|
+
expect(transaction).to_not include_metadata("method" => anything)
|
127
|
+
expect(logs).to contains_log(
|
128
|
+
:error,
|
129
|
+
"Exception while fetching the HTTP request method: RuntimeError: uh oh"
|
130
|
+
)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it "sets request parameters" do
|
135
|
+
apply_to(transaction)
|
136
|
+
|
137
|
+
expect(transaction).to include_params(
|
138
|
+
"page" => "2",
|
139
|
+
"query" => "lorem"
|
140
|
+
)
|
141
|
+
end
|
142
|
+
|
143
|
+
context "when params_method isn't set" do
|
144
|
+
let(:options) { { :params_method => nil } }
|
145
|
+
|
146
|
+
it "reports no params" do
|
147
|
+
apply_to(transaction)
|
148
|
+
|
149
|
+
expect(transaction).to_not include_params
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "when fetching the request method raises an error" do
|
154
|
+
class BrokenRequestParamsRequest < Rack::Request
|
155
|
+
def params
|
156
|
+
raise "uh oh!"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
let(:request) { BrokenRequestParamsRequest.new(merged_env) }
|
161
|
+
let(:options) { { :params_method => :params } }
|
162
|
+
|
163
|
+
it "does not store the invalid HTTP request method" do
|
164
|
+
logs = capture_logs { apply_to(transaction) }
|
165
|
+
|
166
|
+
expect(transaction).to_not include_params
|
167
|
+
expect(logs).to contains_log(
|
168
|
+
:error,
|
169
|
+
"Exception while fetching params " \
|
170
|
+
"from 'BrokenRequestParamsRequest#params': RuntimeError uh oh!"
|
171
|
+
)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
it "sets session data" do
|
176
|
+
apply_to(transaction)
|
177
|
+
|
178
|
+
expect(transaction).to include_session_data("session" => "data", "user_id" => 123)
|
179
|
+
end
|
180
|
+
|
181
|
+
context "with Hash-like session data" do
|
182
|
+
let(:env) { { "rack.session" => HashLike.new("hash-like" => "value", "user_id" => 123) } }
|
183
|
+
|
184
|
+
it "sets session data" do
|
185
|
+
apply_to(transaction)
|
186
|
+
|
187
|
+
expect(transaction).to include_session_data("hash-like" => "value", "user_id" => 123)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "with queue start header" do
|
192
|
+
let(:queue_start_time) { fixed_time * 1_000 }
|
193
|
+
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{queue_start_time.to_i}" } } # in milliseconds
|
194
|
+
|
195
|
+
it "sets the queue start" do
|
196
|
+
apply_to(transaction)
|
197
|
+
|
198
|
+
expect(transaction).to have_queue_start(queue_start_time)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class RackFilteredRequest
|
203
|
+
attr_reader :env
|
204
|
+
|
205
|
+
def initialize(env)
|
206
|
+
@env = env
|
207
|
+
end
|
208
|
+
|
209
|
+
def path
|
210
|
+
"/static/path"
|
211
|
+
end
|
212
|
+
|
213
|
+
def request_method
|
214
|
+
"GET"
|
215
|
+
end
|
216
|
+
|
217
|
+
def filtered_params
|
218
|
+
{ "abc" => "123" }
|
219
|
+
end
|
220
|
+
|
221
|
+
def session
|
222
|
+
{ "data" => "value" }
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context "with overridden request class and params method" do
|
227
|
+
let(:request) { RackFilteredRequest.new(env) }
|
228
|
+
let(:options) { { :params_method => :filtered_params } }
|
229
|
+
|
230
|
+
it "uses the overridden request class and params method to fetch params" do
|
231
|
+
apply_to(transaction)
|
232
|
+
|
233
|
+
expect(transaction).to include_params("abc" => "123")
|
234
|
+
end
|
235
|
+
|
236
|
+
it "uses the overridden request class to fetch session data" do
|
237
|
+
apply_to(transaction)
|
238
|
+
|
239
|
+
expect(transaction).to include_session_data("data" => "value")
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -211,15 +211,15 @@ describe Appsignal::Transaction do
|
|
211
211
|
|
212
212
|
context "when a transaction has errors" do
|
213
213
|
let(:error) do
|
214
|
-
|
215
|
-
|
216
|
-
|
214
|
+
ExampleStandardError.new("test message").tap do |e|
|
215
|
+
e.set_backtrace(["line 1"])
|
216
|
+
end
|
217
217
|
end
|
218
218
|
|
219
219
|
let(:other_error) do
|
220
|
-
|
221
|
-
|
222
|
-
|
220
|
+
ExampleStandardError.new("other test message").tap do |e|
|
221
|
+
e.set_backtrace(["line 2"])
|
222
|
+
end
|
223
223
|
end
|
224
224
|
|
225
225
|
context "when an error is already set on the transaction" do
|
@@ -1526,9 +1526,9 @@ describe Appsignal::Transaction do
|
|
1526
1526
|
let(:transaction) { create_transaction }
|
1527
1527
|
|
1528
1528
|
let(:error) do
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1529
|
+
ExampleStandardError.new("test message").tap do |e|
|
1530
|
+
e.set_backtrace(["line 1"])
|
1531
|
+
end
|
1532
1532
|
end
|
1533
1533
|
|
1534
1534
|
context "when error argument is not an error" do
|
@@ -1588,9 +1588,9 @@ describe Appsignal::Transaction do
|
|
1588
1588
|
|
1589
1589
|
context "when an error is already set in the transaction" do
|
1590
1590
|
let(:other_error) do
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1591
|
+
ExampleStandardError.new("other test message").tap do |e|
|
1592
|
+
e.set_backtrace(["line 2"])
|
1593
|
+
end
|
1594
1594
|
end
|
1595
1595
|
|
1596
1596
|
before { transaction.set_error(other_error) }
|
@@ -1697,12 +1697,92 @@ describe Appsignal::Transaction do
|
|
1697
1697
|
end
|
1698
1698
|
end
|
1699
1699
|
end
|
1700
|
+
|
1701
|
+
context "with a PG::UniqueViolation" do
|
1702
|
+
let(:error) do
|
1703
|
+
PG::UniqueViolation.new(
|
1704
|
+
"ERROR: duplicate key value violates unique constraint " \
|
1705
|
+
"\"index_users_on_email\" DETAIL: Key (email)=(test@test.com) already exists."
|
1706
|
+
)
|
1707
|
+
end
|
1708
|
+
before do
|
1709
|
+
stub_const("PG::UniqueViolation", Class.new(StandardError))
|
1710
|
+
transaction.add_error(error)
|
1711
|
+
end
|
1712
|
+
|
1713
|
+
it "returns a sanizited error message" do
|
1714
|
+
expect(transaction).to have_error(
|
1715
|
+
"PG::UniqueViolation",
|
1716
|
+
"ERROR: duplicate key value violates unique constraint " \
|
1717
|
+
"\"index_users_on_email\" DETAIL: Key (email)=(?) already exists."
|
1718
|
+
)
|
1719
|
+
end
|
1720
|
+
end
|
1721
|
+
|
1722
|
+
context "with a ActiveRecord::RecordNotUnique" do
|
1723
|
+
let(:error) do
|
1724
|
+
ActiveRecord::RecordNotUnique.new(
|
1725
|
+
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
|
1726
|
+
"\"example_constraint\"\nDETAIL: Key (email)=(foo@example.com) already exists."
|
1727
|
+
)
|
1728
|
+
end
|
1729
|
+
before do
|
1730
|
+
stub_const("ActiveRecord::RecordNotUnique", Class.new(StandardError))
|
1731
|
+
transaction.add_error(error)
|
1732
|
+
end
|
1733
|
+
|
1734
|
+
it "returns a sanizited error message" do
|
1735
|
+
expect(transaction).to have_error(
|
1736
|
+
"ActiveRecord::RecordNotUnique",
|
1737
|
+
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
|
1738
|
+
"\"example_constraint\"\nDETAIL: Key (email)=(?) already exists."
|
1739
|
+
)
|
1740
|
+
end
|
1741
|
+
end
|
1742
|
+
|
1743
|
+
context "with Rails module but without backtrace_cleaner method" do
|
1744
|
+
it "returns the backtrace uncleaned" do
|
1745
|
+
stub_const("Rails", Module.new)
|
1746
|
+
error = ExampleStandardError.new("error message")
|
1747
|
+
error.set_backtrace(["line 1", "line 2"])
|
1748
|
+
transaction.add_error(error)
|
1749
|
+
|
1750
|
+
expect(last_transaction).to have_error(
|
1751
|
+
"ExampleStandardError",
|
1752
|
+
"error message",
|
1753
|
+
["line 1", "line 2"]
|
1754
|
+
)
|
1755
|
+
end
|
1756
|
+
end
|
1757
|
+
|
1758
|
+
if rails_present?
|
1759
|
+
context "with Rails" do
|
1760
|
+
it "cleans the backtrace with the Rails backtrace cleaner" do
|
1761
|
+
::Rails.backtrace_cleaner.add_filter do |line|
|
1762
|
+
line.tr("2", "?")
|
1763
|
+
end
|
1764
|
+
|
1765
|
+
error = ExampleStandardError.new("error message")
|
1766
|
+
error.set_backtrace(["line 1", "line 2"])
|
1767
|
+
transaction.add_error(error)
|
1768
|
+
expect(last_transaction).to have_error(
|
1769
|
+
"ExampleStandardError",
|
1770
|
+
"error message",
|
1771
|
+
["line 1", "line ?"]
|
1772
|
+
)
|
1773
|
+
end
|
1774
|
+
end
|
1775
|
+
end
|
1700
1776
|
end
|
1701
1777
|
|
1702
1778
|
describe "#_set_error" do
|
1703
1779
|
let(:transaction) { new_transaction }
|
1704
1780
|
let(:env) { http_request_env_with_data }
|
1705
|
-
let(:error)
|
1781
|
+
let(:error) do
|
1782
|
+
ExampleStandardError.new("test message").tap do |e|
|
1783
|
+
e.set_backtrace(["line 1"])
|
1784
|
+
end
|
1785
|
+
end
|
1706
1786
|
|
1707
1787
|
it "responds to add_exception for backwards compatibility" do
|
1708
1788
|
expect(transaction).to respond_to(:add_exception)
|
@@ -1716,7 +1796,6 @@ describe Appsignal::Transaction do
|
|
1716
1796
|
|
1717
1797
|
context "for a http request" do
|
1718
1798
|
it "sets an error on the transaction" do
|
1719
|
-
allow(error).to receive(:backtrace).and_return(["line 1"])
|
1720
1799
|
transaction.send(:_set_error, error)
|
1721
1800
|
|
1722
1801
|
expect(transaction).to have_error(
|
@@ -1738,9 +1817,9 @@ describe Appsignal::Transaction do
|
|
1738
1817
|
context "when the error has multiple causes" do
|
1739
1818
|
let(:error) do
|
1740
1819
|
e = ExampleStandardError.new("test message")
|
1820
|
+
e.set_backtrace(["line 1"])
|
1741
1821
|
e2 = RuntimeError.new("cause message")
|
1742
1822
|
e3 = StandardError.new("cause message 2")
|
1743
|
-
allow(e).to receive(:backtrace).and_return(["line 1"])
|
1744
1823
|
allow(e).to receive(:cause).and_return(e2)
|
1745
1824
|
allow(e2).to receive(:cause).and_return(e3)
|
1746
1825
|
e
|
@@ -1795,8 +1874,7 @@ describe Appsignal::Transaction do
|
|
1795
1874
|
allow(next_e).to receive(:cause).and_return(e)
|
1796
1875
|
e = next_e
|
1797
1876
|
end
|
1798
|
-
|
1799
|
-
allow(e).to receive(:backtrace).and_return(["line 1"])
|
1877
|
+
e.set_backtrace(["line 1"])
|
1800
1878
|
e
|
1801
1879
|
end
|
1802
1880
|
|
@@ -1831,7 +1909,7 @@ describe Appsignal::Transaction do
|
|
1831
1909
|
let(:error) do
|
1832
1910
|
e = ExampleStandardError.new
|
1833
1911
|
allow(e).to receive(:message).and_return(nil)
|
1834
|
-
|
1912
|
+
e.set_backtrace(["line 1"])
|
1835
1913
|
e
|
1836
1914
|
end
|
1837
1915
|
|
@@ -1985,80 +2063,6 @@ describe Appsignal::Transaction do
|
|
1985
2063
|
|
1986
2064
|
# private
|
1987
2065
|
|
1988
|
-
describe "#cleaned_backtrace" do
|
1989
|
-
let(:transaction) { new_transaction }
|
1990
|
-
subject { transaction.send(:cleaned_backtrace, ["line 1", "line 2"]) }
|
1991
|
-
|
1992
|
-
it "returns the backtrace" do
|
1993
|
-
expect(subject).to eq ["line 1", "line 2"]
|
1994
|
-
end
|
1995
|
-
|
1996
|
-
context "with Rails module but without backtrace_cleaner method" do
|
1997
|
-
it "returns the backtrace uncleaned" do
|
1998
|
-
stub_const("Rails", Module.new)
|
1999
|
-
expect(subject).to eq ["line 1", "line 2"]
|
2000
|
-
end
|
2001
|
-
end
|
2002
|
-
|
2003
|
-
if rails_present?
|
2004
|
-
context "with rails" do
|
2005
|
-
it "cleans the backtrace with the Rails backtrace cleaner" do
|
2006
|
-
::Rails.backtrace_cleaner.add_filter do |line|
|
2007
|
-
line.tr("2", "?")
|
2008
|
-
end
|
2009
|
-
expect(subject).to eq ["line 1", "line ?"]
|
2010
|
-
end
|
2011
|
-
end
|
2012
|
-
end
|
2013
|
-
end
|
2014
|
-
|
2015
|
-
describe "#cleaned_error_message" do
|
2016
|
-
let(:transaction) { new_transaction }
|
2017
|
-
let(:error) { StandardError.new("Error message") }
|
2018
|
-
subject { transaction.send(:cleaned_error_message, error) }
|
2019
|
-
|
2020
|
-
it "returns the error message" do
|
2021
|
-
expect(subject).to eq "Error message"
|
2022
|
-
end
|
2023
|
-
|
2024
|
-
context "with a PG::UniqueViolation" do
|
2025
|
-
before do
|
2026
|
-
stub_const("PG::UniqueViolation", Class.new(StandardError))
|
2027
|
-
end
|
2028
|
-
|
2029
|
-
let(:error) do
|
2030
|
-
PG::UniqueViolation.new(
|
2031
|
-
"ERROR: duplicate key value violates unique constraint " \
|
2032
|
-
"\"index_users_on_email\" DETAIL: Key (email)=(test@test.com) already exists."
|
2033
|
-
)
|
2034
|
-
end
|
2035
|
-
|
2036
|
-
it "returns a sanizited error message" do
|
2037
|
-
expect(subject).to eq "ERROR: duplicate key value violates unique constraint " \
|
2038
|
-
"\"index_users_on_email\" DETAIL: Key (email)=(?) already exists."
|
2039
|
-
end
|
2040
|
-
end
|
2041
|
-
|
2042
|
-
context "with a ActiveRecord::RecordNotUnique" do
|
2043
|
-
before do
|
2044
|
-
stub_const("ActiveRecord::RecordNotUnique", Class.new(StandardError))
|
2045
|
-
end
|
2046
|
-
|
2047
|
-
let(:error) do
|
2048
|
-
ActiveRecord::RecordNotUnique.new(
|
2049
|
-
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
|
2050
|
-
"\"example_constraint\"\nDETAIL: Key (email)=(foo@example.com) already exists."
|
2051
|
-
)
|
2052
|
-
end
|
2053
|
-
|
2054
|
-
it "returns a sanizited error message" do
|
2055
|
-
expect(subject).to eq \
|
2056
|
-
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
|
2057
|
-
"\"example_constraint\"\nDETAIL: Key (email)=(?) already exists."
|
2058
|
-
end
|
2059
|
-
end
|
2060
|
-
end
|
2061
|
-
|
2062
2066
|
describe ".to_hash / .to_h" do
|
2063
2067
|
let(:transaction) { new_transaction }
|
2064
2068
|
subject { transaction.to_hash }
|
data/spec/spec_helper.rb
CHANGED
@@ -85,6 +85,10 @@ RSpec.configure do |config|
|
|
85
85
|
File.join(tmp_dir, "system-tmp")
|
86
86
|
end
|
87
87
|
|
88
|
+
config.before :suite do
|
89
|
+
WebMock.disable_net_connect!
|
90
|
+
end
|
91
|
+
|
88
92
|
config.before :context do
|
89
93
|
FileUtils.rm_rf(tmp_dir)
|
90
94
|
FileUtils.mkdir_p(spec_system_tmp_dir)
|
@@ -94,6 +98,8 @@ RSpec.configure do |config|
|
|
94
98
|
Appsignal.clear!
|
95
99
|
Appsignal::Testing.clear!
|
96
100
|
Appsignal::Loaders.clear!
|
101
|
+
Appsignal::CheckIn.clear!
|
102
|
+
|
97
103
|
clear_current_transaction!
|
98
104
|
stop_minutely_probes
|
99
105
|
ENV["RAILS_ENV"] ||= "test"
|
@@ -168,13 +174,6 @@ RSpec.configure do |config|
|
|
168
174
|
end
|
169
175
|
|
170
176
|
def stop_minutely_probes
|
171
|
-
thread =
|
172
|
-
begin
|
173
|
-
Appsignal::Probes.class_variable_get(:@@thread) # Fetch old thread
|
174
|
-
rescue NameError
|
175
|
-
nil
|
176
|
-
end
|
177
177
|
Appsignal::Probes.stop
|
178
|
-
thread&.join # Wait for old thread to exit
|
179
178
|
end
|
180
179
|
end
|
@@ -17,4 +17,44 @@ module ApiRequestHelper
|
|
17
17
|
endpoint = config[:endpoint] || Appsignal::Config::DEFAULT_CONFIG[:endpoint]
|
18
18
|
stub_request(:post, "#{endpoint}/1/#{path}").with(options)
|
19
19
|
end
|
20
|
+
|
21
|
+
def stub_check_in_request(events:, response: { :status => 200 })
|
22
|
+
config = Appsignal.config
|
23
|
+
options = {
|
24
|
+
:query => {
|
25
|
+
:api_key => config[:push_api_key],
|
26
|
+
:name => config[:name],
|
27
|
+
:environment => config.respond_to?(:env) ? config.env : config[:environment],
|
28
|
+
:hostname => config[:hostname],
|
29
|
+
:gem_version => Appsignal::VERSION
|
30
|
+
},
|
31
|
+
:headers => { "Content-Type" => "application/x-ndjson; charset=UTF-8" }
|
32
|
+
}
|
33
|
+
|
34
|
+
request_stub =
|
35
|
+
stub_request(
|
36
|
+
:post,
|
37
|
+
"#{config[:logging_endpoint]}/check_ins/json"
|
38
|
+
).with(options) do |request|
|
39
|
+
# Parse each line as JSON per the NDJSON format
|
40
|
+
payloads = request.body.split("\n").map { |line| JSON.parse(line) }
|
41
|
+
formatted_events =
|
42
|
+
events.map do |event|
|
43
|
+
{
|
44
|
+
"identifier" => nil,
|
45
|
+
"digest" => kind_of(String),
|
46
|
+
"kind" => "start",
|
47
|
+
"timestamp" => kind_of(Integer),
|
48
|
+
"check_in_type" => "cron"
|
49
|
+
}.merge(event)
|
50
|
+
end
|
51
|
+
expect(payloads).to include(*formatted_events)
|
52
|
+
end
|
53
|
+
|
54
|
+
if response.is_a?(Exception)
|
55
|
+
request_stub.to_raise(response)
|
56
|
+
else
|
57
|
+
request_stub.to_return(response)
|
58
|
+
end
|
59
|
+
end
|
20
60
|
end
|
@@ -46,7 +46,7 @@ module ConfigHelpers
|
|
46
46
|
end
|
47
47
|
module_function :build_config
|
48
48
|
|
49
|
-
def start_agent(env: "production", options: {})
|
49
|
+
def start_agent(env: "production", options: {}, internal_logger: nil)
|
50
50
|
env = "production" if env == :default
|
51
51
|
env ||= "production"
|
52
52
|
Appsignal.configure(env, :root_path => project_fixture_path) do |config|
|
@@ -55,6 +55,7 @@ module ConfigHelpers
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
Appsignal.start
|
58
|
+
Appsignal.internal_logger = internal_logger if internal_logger
|
58
59
|
end
|
59
60
|
|
60
61
|
def clear_integration_env_vars!
|
@@ -127,6 +127,11 @@ module DependencyHelper
|
|
127
127
|
dependency_present? "que"
|
128
128
|
end
|
129
129
|
|
130
|
+
def que2_present?
|
131
|
+
que_present? &&
|
132
|
+
Gem.loaded_specs["que"].version >= Gem::Version.new("2.0.0")
|
133
|
+
end
|
134
|
+
|
130
135
|
def hanami_present?
|
131
136
|
dependency_present? "hanami"
|
132
137
|
end
|
@@ -1,14 +1,21 @@
|
|
1
1
|
RSpec::Matchers.define :contains_log do |level, message|
|
2
|
-
|
2
|
+
log_level_prefix = level.upcase
|
3
3
|
|
4
4
|
match do |actual|
|
5
|
-
|
5
|
+
case message
|
6
|
+
when Regexp
|
7
|
+
/\[#{log_level_prefix}\] #{message}/.match?(actual)
|
8
|
+
else
|
9
|
+
expected_log_line = "[#{log_level_prefix}] #{message}"
|
10
|
+
actual.include?(expected_log_line)
|
11
|
+
end
|
6
12
|
end
|
7
13
|
|
8
14
|
failure_message do |actual|
|
9
15
|
<<~MESSAGE
|
10
16
|
Did not contain log line:
|
11
|
-
#{
|
17
|
+
Log level: #{log_level_prefix}
|
18
|
+
Message: #{message}
|
12
19
|
|
13
20
|
Received logs:
|
14
21
|
#{actual}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class PumaMock
|
2
|
+
module MiniSSL
|
3
|
+
class SSLError < StandardError
|
4
|
+
def self.to_s
|
5
|
+
"Puma::MiniSSL::SSLError"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class HttpParserError < StandardError
|
11
|
+
def self.to_s
|
12
|
+
"Puma::HttpParserError"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class HttpParserError501 < StandardError
|
17
|
+
def self.to_s
|
18
|
+
"Puma::HttpParserError501"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.stats
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.cli_config
|
26
|
+
@cli_config ||= CliConfig.new
|
27
|
+
end
|
28
|
+
|
29
|
+
class Server
|
30
|
+
end
|
31
|
+
|
32
|
+
module Const
|
33
|
+
VERSION = "6.0.0".freeze
|
34
|
+
end
|
35
|
+
|
36
|
+
class CliConfig
|
37
|
+
attr_accessor :options
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
@options = {}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|