appsignal 2.1.0.alpha.3 → 2.1.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +43 -0
- data/.rubocop_todo.yml +289 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +11 -1
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/appsignal.gemspec +1 -0
- data/bin/appsignal +2 -2
- data/ext/agent.yml +11 -11
- data/ext/extconf.rb +33 -33
- data/gemfiles/rails-4.2.gemfile +4 -0
- data/gemfiles/resque.gemfile +4 -0
- data/lib/appsignal.rb +58 -54
- data/lib/appsignal/auth_check.rb +15 -16
- data/lib/appsignal/capistrano.rb +4 -4
- data/lib/appsignal/cli.rb +28 -28
- data/lib/appsignal/cli/diagnose.rb +11 -11
- data/lib/appsignal/cli/helpers.rb +1 -1
- data/lib/appsignal/cli/install.rb +38 -38
- data/lib/appsignal/cli/notify_of_deploy.rb +1 -1
- data/lib/appsignal/config.rb +73 -71
- data/lib/appsignal/event_formatter.rb +8 -8
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +4 -4
- data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +1 -1
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +1 -1
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +9 -7
- data/lib/appsignal/event_formatter/faraday/request_formatter.rb +1 -1
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +6 -6
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +56 -43
- data/lib/appsignal/extension.rb +5 -5
- data/lib/appsignal/hooks.rb +28 -26
- data/lib/appsignal/hooks/active_support_notifications.rb +2 -2
- data/lib/appsignal/hooks/celluloid.rb +1 -1
- data/lib/appsignal/hooks/data_mapper.rb +2 -2
- data/lib/appsignal/hooks/delayed_job.rb +1 -1
- data/lib/appsignal/hooks/mongo_ruby_driver.rb +1 -1
- data/lib/appsignal/hooks/net_http.rb +4 -4
- data/lib/appsignal/hooks/passenger.rb +2 -2
- data/lib/appsignal/hooks/puma.rb +4 -4
- data/lib/appsignal/hooks/rake.rb +1 -1
- data/lib/appsignal/hooks/redis.rb +1 -1
- data/lib/appsignal/hooks/sequel.rb +2 -2
- data/lib/appsignal/hooks/shoryuken.rb +8 -8
- data/lib/appsignal/hooks/sidekiq.rb +16 -15
- data/lib/appsignal/hooks/unicorn.rb +1 -1
- data/lib/appsignal/hooks/webmachine.rb +1 -1
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +6 -6
- data/lib/appsignal/integrations/data_mapper.rb +2 -3
- data/lib/appsignal/integrations/delayed_job_plugin.rb +5 -5
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +6 -6
- data/lib/appsignal/integrations/padrino.rb +8 -8
- data/lib/appsignal/integrations/railtie.rb +5 -5
- data/lib/appsignal/integrations/resque.rb +4 -5
- data/lib/appsignal/integrations/resque_active_job.rb +3 -6
- data/lib/appsignal/integrations/sinatra.rb +2 -2
- data/lib/appsignal/integrations/webmachine.rb +2 -3
- data/lib/appsignal/js_exception_transaction.rb +10 -10
- data/lib/appsignal/marker.rb +3 -3
- data/lib/appsignal/rack/generic_instrumentation.rb +10 -9
- data/lib/appsignal/rack/js_exception_catcher.rb +7 -6
- data/lib/appsignal/rack/rails_instrumentation.rb +9 -8
- data/lib/appsignal/rack/sinatra_instrumentation.rb +19 -17
- data/lib/appsignal/rack/streaming_listener.rb +9 -8
- data/lib/appsignal/system.rb +19 -17
- data/lib/appsignal/transaction.rb +97 -40
- data/lib/appsignal/transmitter.rb +23 -30
- data/lib/appsignal/utils.rb +3 -3
- data/lib/appsignal/utils/params_sanitizer.rb +1 -1
- data/lib/appsignal/utils/query_params_sanitizer.rb +1 -1
- data/lib/appsignal/version.rb +2 -2
- data/spec/.rubocop.yml +4 -0
- data/spec/lib/appsignal/auth_check_spec.rb +7 -7
- data/spec/lib/appsignal/capistrano2_spec.rb +41 -41
- data/spec/lib/appsignal/capistrano3_spec.rb +43 -44
- data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +9 -11
- data/spec/lib/appsignal/cli_spec.rb +9 -9
- data/spec/lib/appsignal/config_spec.rb +88 -86
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +9 -9
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +4 -4
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +4 -4
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +12 -12
- data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +4 -4
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +23 -23
- data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +29 -30
- data/spec/lib/appsignal/event_formatter_spec.rb +28 -28
- data/spec/lib/appsignal/extension_spec.rb +15 -15
- data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +6 -5
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +12 -12
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +34 -34
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +3 -3
- data/spec/lib/appsignal/hooks/net_http_spec.rb +10 -10
- data/spec/lib/appsignal/hooks/rake_spec.rb +7 -7
- data/spec/lib/appsignal/hooks/redis_spec.rb +6 -6
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +21 -22
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +48 -45
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +2 -2
- data/spec/lib/appsignal/hooks_spec.rb +16 -17
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +7 -8
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +19 -19
- data/spec/lib/appsignal/integrations/object_spec.rb +3 -3
- data/spec/lib/appsignal/integrations/padrino_spec.rb +44 -44
- data/spec/lib/appsignal/integrations/railtie_spec.rb +13 -13
- data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +7 -7
- data/spec/lib/appsignal/integrations/resque_spec.rb +8 -8
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +7 -7
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +15 -15
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +23 -23
- data/spec/lib/appsignal/marker_spec.rb +8 -8
- data/spec/lib/appsignal/minutely_spec.rb +6 -6
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +7 -7
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +13 -13
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +11 -11
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +21 -21
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +36 -36
- data/spec/lib/appsignal/system/container_spec.rb +1 -1
- data/spec/lib/appsignal/transaction_spec.rb +213 -184
- data/spec/lib/appsignal/transmitter_spec.rb +20 -20
- data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +19 -19
- data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +41 -41
- data/spec/lib/appsignal/utils_spec.rb +41 -37
- data/spec/lib/appsignal_spec.rb +150 -142
- data/spec/spec_helper.rb +18 -18
- data/spec/support/delegate_matcher.rb +6 -6
- data/spec/support/helpers/api_request_helper.rb +2 -2
- data/spec/support/helpers/config_helpers.rb +3 -3
- data/spec/support/helpers/dependency_helper.rb +13 -13
- data/spec/support/helpers/directory_helper.rb +5 -5
- data/spec/support/helpers/env_helpers.rb +14 -14
- data/spec/support/helpers/system_helpers.rb +3 -3
- data/spec/support/helpers/transaction_helpers.rb +10 -10
- metadata +20 -2
@@ -43,7 +43,7 @@ describe Appsignal::System::Container do
|
|
43
43
|
context "when no permission to read cgroup file" do
|
44
44
|
let(:out_stream) { StringIO.new }
|
45
45
|
let(:no_permission_file) do
|
46
|
-
File.join(fixtures_dir,
|
46
|
+
File.join(fixtures_dir, "containers", "cgroups", "no_permission")
|
47
47
|
end
|
48
48
|
before do
|
49
49
|
File.chmod 0333, no_permission_file
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "../../support/mocks/fake_gc_profiler"
|
2
2
|
|
3
3
|
class Smash < Hash
|
4
|
-
def []=(
|
5
|
-
raise
|
4
|
+
def []=(_key, _val)
|
5
|
+
raise "the roof"
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
@@ -17,27 +17,27 @@ describe Appsignal::Transaction do
|
|
17
17
|
let(:merged_env) { http_request_env_with_data(env) }
|
18
18
|
let(:options) { {} }
|
19
19
|
let(:request) { Rack::Request.new(merged_env) }
|
20
|
-
let(:transaction) { Appsignal::Transaction.new(
|
20
|
+
let(:transaction) { Appsignal::Transaction.new("1", namespace, request, options) }
|
21
21
|
|
22
22
|
before { Timecop.freeze(time) }
|
23
23
|
after { Timecop.return }
|
24
24
|
|
25
|
-
|
25
|
+
describe "class methods" do
|
26
26
|
describe ".create" do
|
27
27
|
it "should add the transaction to thread local" do
|
28
|
-
Appsignal::Extension.should_receive(:start_transaction).with(
|
28
|
+
Appsignal::Extension.should_receive(:start_transaction).with("1", "http_request", 0)
|
29
29
|
|
30
|
-
created_transaction = Appsignal::Transaction.create(
|
30
|
+
created_transaction = Appsignal::Transaction.create("1", namespace, request, options)
|
31
31
|
|
32
32
|
Thread.current[:appsignal_transaction].should eq created_transaction
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should create a transaction" do
|
36
|
-
created_transaction = Appsignal::Transaction.create(
|
36
|
+
created_transaction = Appsignal::Transaction.create("1", namespace, request, options)
|
37
37
|
|
38
38
|
created_transaction.should be_a Appsignal::Transaction
|
39
|
-
created_transaction.transaction_id.should eq
|
40
|
-
created_transaction.namespace.should eq
|
39
|
+
created_transaction.transaction_id.should eq "1"
|
40
|
+
created_transaction.namespace.should eq "http_request"
|
41
41
|
end
|
42
42
|
|
43
43
|
context "when a transaction is already running" do
|
@@ -46,36 +46,35 @@ describe Appsignal::Transaction do
|
|
46
46
|
|
47
47
|
it "should not create a new transaction" do
|
48
48
|
expect(
|
49
|
-
Appsignal::Transaction.create(
|
49
|
+
Appsignal::Transaction.create("1", namespace, request, options)
|
50
50
|
).to eq(running_transaction)
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should output a debug message" do
|
54
|
-
expect(
|
54
|
+
expect(Appsignal.logger).to receive(:debug)
|
55
55
|
.with("Trying to start new transaction 1 but 2 is already running. Using 2")
|
56
56
|
|
57
|
-
Appsignal::Transaction.create(
|
57
|
+
Appsignal::Transaction.create("1", namespace, request, options)
|
58
58
|
end
|
59
59
|
|
60
60
|
context "with option to force a new transaction" do
|
61
|
-
let(:options) { {:force => true} }
|
61
|
+
let(:options) { { :force => true } }
|
62
62
|
it "should not create a new transaction" do
|
63
63
|
expect(
|
64
|
-
Appsignal::Transaction.create(
|
64
|
+
Appsignal::Transaction.create("1", namespace, request, options)
|
65
65
|
).to_not eq(running_transaction)
|
66
66
|
end
|
67
67
|
end
|
68
|
-
|
69
68
|
end
|
70
69
|
end
|
71
70
|
|
72
|
-
describe
|
71
|
+
describe ".current" do
|
73
72
|
before { Thread.current[:appsignal_transaction] = transaction }
|
74
73
|
|
75
74
|
subject { Appsignal::Transaction.current }
|
76
75
|
|
77
76
|
context "if there is a transaction" do
|
78
|
-
before { Appsignal::Transaction.create(
|
77
|
+
before { Appsignal::Transaction.create("1", namespace, request, options) }
|
79
78
|
|
80
79
|
it "should return the correct transaction" do
|
81
80
|
should eq transaction
|
@@ -102,7 +101,7 @@ describe Appsignal::Transaction do
|
|
102
101
|
end
|
103
102
|
|
104
103
|
describe "complete_current!" do
|
105
|
-
before { Appsignal::Transaction.create(
|
104
|
+
before { Appsignal::Transaction.create("2", Appsignal::Transaction::HTTP_REQUEST, {}) }
|
106
105
|
|
107
106
|
it "should complete the current transaction and set the thread appsignal_transaction to nil" do
|
108
107
|
Appsignal::Transaction.current.should_receive(:complete)
|
@@ -113,7 +112,7 @@ describe Appsignal::Transaction do
|
|
113
112
|
end
|
114
113
|
|
115
114
|
it "should still clear the transaction if there is an error" do
|
116
|
-
Appsignal::Transaction.current.should_receive(:complete).and_raise
|
115
|
+
Appsignal::Transaction.current.should_receive(:complete).and_raise "Error"
|
117
116
|
|
118
117
|
Appsignal::Transaction.complete_current!
|
119
118
|
|
@@ -163,9 +162,9 @@ describe Appsignal::Transaction do
|
|
163
162
|
context "pausing" do
|
164
163
|
describe "#pause!" do
|
165
164
|
it "should change the pause flag to true" do
|
166
|
-
expect
|
165
|
+
expect do
|
167
166
|
transaction.pause!
|
168
|
-
|
167
|
+
end.to change(transaction, :paused).from(false).to(true)
|
169
168
|
end
|
170
169
|
end
|
171
170
|
|
@@ -173,23 +172,22 @@ describe Appsignal::Transaction do
|
|
173
172
|
before { transaction.pause! }
|
174
173
|
|
175
174
|
it "should change the pause flag to false" do
|
176
|
-
expect
|
175
|
+
expect do
|
177
176
|
transaction.resume!
|
178
|
-
|
177
|
+
end.to change(transaction, :paused).from(true).to(false)
|
179
178
|
end
|
180
179
|
end
|
181
180
|
|
182
181
|
describe "#paused?" do
|
183
|
-
|
184
182
|
it "should return the pause state" do
|
185
|
-
expect(
|
183
|
+
expect(transaction.paused?).to be_false
|
186
184
|
end
|
187
185
|
|
188
186
|
context "when paused" do
|
189
187
|
before { transaction.pause! }
|
190
188
|
|
191
189
|
it "should return the pause state" do
|
192
|
-
expect(
|
190
|
+
expect(transaction.paused?).to be_true
|
193
191
|
end
|
194
192
|
end
|
195
193
|
end
|
@@ -200,8 +198,8 @@ describe Appsignal::Transaction do
|
|
200
198
|
subject { transaction }
|
201
199
|
|
202
200
|
its(:ext) { should_not be_nil }
|
203
|
-
its(:transaction_id) { should eq
|
204
|
-
its(:namespace) { should eq
|
201
|
+
its(:transaction_id) { should eq "1" }
|
202
|
+
its(:namespace) { should eq "http_request" }
|
205
203
|
its(:request) { should_not be_nil }
|
206
204
|
its(:paused) { should be_false }
|
207
205
|
its(:tags) { should eq({}) }
|
@@ -212,7 +210,7 @@ describe Appsignal::Transaction do
|
|
212
210
|
its([:params_method]) { should eq :params }
|
213
211
|
|
214
212
|
context "with overridden options" do
|
215
|
-
let(:options) { {:params_method => :filtered_params} }
|
213
|
+
let(:options) { { :params_method => :filtered_params } }
|
216
214
|
|
217
215
|
its([:params_method]) { should eq :filtered_params }
|
218
216
|
end
|
@@ -221,32 +219,32 @@ describe Appsignal::Transaction do
|
|
221
219
|
|
222
220
|
describe "#store" do
|
223
221
|
it "should return an empty store when it's not already present" do
|
224
|
-
expect(
|
222
|
+
expect(transaction.store("test")).to eql({})
|
225
223
|
end
|
226
224
|
|
227
225
|
it "should store changes to the store" do
|
228
|
-
transaction_store = transaction.store(
|
229
|
-
transaction_store[
|
226
|
+
transaction_store = transaction.store("test")
|
227
|
+
transaction_store["transaction"] = "value"
|
230
228
|
|
231
|
-
expect(
|
229
|
+
expect(transaction.store("test")).to eql("transaction" => "value")
|
232
230
|
end
|
233
231
|
end
|
234
232
|
|
235
233
|
describe "#set_tags" do
|
236
234
|
it "should add tags to transaction" do
|
237
|
-
expect
|
238
|
-
transaction.set_tags(
|
239
|
-
|
235
|
+
expect do
|
236
|
+
transaction.set_tags("a" => "b")
|
237
|
+
end.to change(transaction, :tags).to("a" => "b")
|
240
238
|
end
|
241
239
|
end
|
242
240
|
|
243
241
|
describe "set_action" do
|
244
242
|
it "should set the action in extension" do
|
245
|
-
|
246
|
-
|
247
|
-
|
243
|
+
transaction.ext.should_receive(:set_action).with(
|
244
|
+
"PagesController#show"
|
245
|
+
).once
|
248
246
|
|
249
|
-
|
247
|
+
transaction.set_action("PagesController#show")
|
250
248
|
end
|
251
249
|
|
252
250
|
it "should not set the action in extension when value is nil" do
|
@@ -258,26 +256,26 @@ describe Appsignal::Transaction do
|
|
258
256
|
|
259
257
|
describe "#set_http_or_background_action" do
|
260
258
|
context "for a hash with controller and action" do
|
261
|
-
let(:from) { {:controller =>
|
259
|
+
let(:from) { { :controller => "HomeController", :action => "show" } }
|
262
260
|
|
263
261
|
it "should set the action" do
|
264
|
-
transaction.should_receive(:set_action).with(
|
262
|
+
transaction.should_receive(:set_action).with("HomeController#show")
|
265
263
|
end
|
266
264
|
end
|
267
265
|
|
268
266
|
context "for a hash with just action" do
|
269
|
-
let(:from) { {:action =>
|
267
|
+
let(:from) { { :action => "show" } }
|
270
268
|
|
271
269
|
it "should set the action" do
|
272
|
-
transaction.should_receive(:set_action).with(
|
270
|
+
transaction.should_receive(:set_action).with("show")
|
273
271
|
end
|
274
272
|
end
|
275
273
|
|
276
274
|
context "for a hash with class and method" do
|
277
|
-
let(:from) { {:class =>
|
275
|
+
let(:from) { { :class => "Worker", :method => "perform" } }
|
278
276
|
|
279
277
|
it "should set the action" do
|
280
|
-
transaction.should_receive(:set_action).with(
|
278
|
+
transaction.should_receive(:set_action).with("Worker#perform")
|
281
279
|
end
|
282
280
|
end
|
283
281
|
|
@@ -304,19 +302,19 @@ describe Appsignal::Transaction do
|
|
304
302
|
|
305
303
|
Appsignal.logger.should_receive(:warn).with("Queue start value 10 is too big")
|
306
304
|
|
307
|
-
lambda
|
305
|
+
lambda do
|
308
306
|
transaction.set_queue_start(10)
|
309
|
-
|
307
|
+
end.should_not raise_error
|
310
308
|
end
|
311
309
|
end
|
312
310
|
|
313
311
|
describe "#set_http_or_background_queue_start" do
|
314
312
|
context "for a http transaction" do
|
315
313
|
let(:namespace) { Appsignal::Transaction::HTTP_REQUEST }
|
316
|
-
let(:env) { {
|
314
|
+
let(:env) { { "HTTP_X_REQUEST_START" => (fixed_time * 1000).to_s } }
|
317
315
|
|
318
316
|
it "should set the queue start on the transaction" do
|
319
|
-
transaction.should_receive(:set_queue_start).with(
|
317
|
+
transaction.should_receive(:set_queue_start).with(13_897_836_000)
|
320
318
|
|
321
319
|
transaction.set_http_or_background_queue_start
|
322
320
|
end
|
@@ -324,10 +322,10 @@ describe Appsignal::Transaction do
|
|
324
322
|
|
325
323
|
context "for a background transaction" do
|
326
324
|
let(:namespace) { Appsignal::Transaction::BACKGROUND_JOB }
|
327
|
-
let(:env) { {:queue_start => fixed_time} }
|
325
|
+
let(:env) { { :queue_start => fixed_time } }
|
328
326
|
|
329
327
|
it "should set the queue start on the transaction" do
|
330
|
-
transaction.should_receive(:set_queue_start).with(
|
328
|
+
transaction.should_receive(:set_queue_start).with(1_389_783_600_000)
|
331
329
|
|
332
330
|
transaction.set_http_or_background_queue_start
|
333
331
|
end
|
@@ -337,73 +335,71 @@ describe Appsignal::Transaction do
|
|
337
335
|
describe "#set_metadata" do
|
338
336
|
it "should set the metdata in extension" do
|
339
337
|
transaction.ext.should_receive(:set_metadata).with(
|
340
|
-
|
341
|
-
|
338
|
+
"request_method",
|
339
|
+
"GET"
|
342
340
|
).once
|
343
341
|
|
344
|
-
transaction.set_metadata(
|
342
|
+
transaction.set_metadata("request_method", "GET")
|
345
343
|
end
|
346
344
|
|
347
345
|
it "should not set the metdata in extension when value is nil" do
|
348
346
|
transaction.ext.should_not_receive(:set_metadata)
|
349
347
|
|
350
|
-
transaction.set_metadata(
|
348
|
+
transaction.set_metadata("request_method", nil)
|
351
349
|
end
|
352
350
|
end
|
353
351
|
|
354
352
|
describe "set_sample_data" do
|
355
353
|
it "should set the data" do
|
356
354
|
transaction.ext.should_receive(:set_sample_data).with(
|
357
|
-
|
358
|
-
Appsignal::Utils.data_generate(
|
355
|
+
"params",
|
356
|
+
Appsignal::Utils.data_generate("controller" => "blog_posts", "action" => "show", "id" => "1")
|
359
357
|
).once
|
360
358
|
|
361
359
|
transaction.set_sample_data(
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
:id => '1'
|
367
|
-
}
|
360
|
+
"params",
|
361
|
+
:controller => "blog_posts",
|
362
|
+
:action => "show",
|
363
|
+
:id => "1"
|
368
364
|
)
|
369
365
|
end
|
370
366
|
|
371
367
|
it "should do nothing if the data cannot be converted to json" do
|
372
368
|
transaction.ext.should_not_receive(:set_sample_data).with(
|
373
|
-
|
369
|
+
"params",
|
374
370
|
kind_of(String)
|
375
371
|
)
|
376
372
|
|
377
|
-
transaction.set_sample_data(
|
373
|
+
transaction.set_sample_data("params", "string")
|
378
374
|
end
|
379
375
|
end
|
380
376
|
|
381
377
|
describe "#sample_data" do
|
382
378
|
it "should sample data" do
|
383
379
|
transaction.ext.should_receive(:set_sample_data).with(
|
384
|
-
|
385
|
-
Appsignal::Utils.data_generate(
|
380
|
+
"environment",
|
381
|
+
Appsignal::Utils.data_generate(
|
386
382
|
"CONTENT_LENGTH" => "0",
|
387
383
|
"REQUEST_METHOD" => "GET",
|
388
384
|
"SERVER_NAME" => "example.org",
|
389
385
|
"SERVER_PORT" => "80",
|
390
386
|
"PATH_INFO" => "/blog"
|
391
|
-
|
387
|
+
)
|
392
388
|
).once
|
393
389
|
transaction.ext.should_receive(:set_sample_data).with(
|
394
|
-
|
390
|
+
"session_data",
|
395
391
|
Appsignal::Utils.data_generate({})
|
396
392
|
).once
|
397
393
|
transaction.ext.should_receive(:set_sample_data).with(
|
398
|
-
|
399
|
-
Appsignal::Utils.data_generate(
|
394
|
+
"params",
|
395
|
+
Appsignal::Utils.data_generate("controller" => "blog_posts", "action" => "show", "id" => "1")
|
400
396
|
).once
|
401
397
|
transaction.ext.should_receive(:set_sample_data).with(
|
402
|
-
|
403
|
-
Appsignal::Utils.data_generate(
|
398
|
+
"metadata",
|
399
|
+
Appsignal::Utils.data_generate("key" => "value")
|
404
400
|
).once
|
405
401
|
transaction.ext.should_receive(:set_sample_data).with(
|
406
|
-
|
402
|
+
"tags",
|
407
403
|
Appsignal::Utils.data_generate({})
|
408
404
|
).once
|
409
405
|
|
@@ -411,21 +407,14 @@ describe Appsignal::Transaction do
|
|
411
407
|
end
|
412
408
|
end
|
413
409
|
|
414
|
-
describe
|
410
|
+
describe "#set_error" do
|
415
411
|
let(:env) { http_request_env_with_data }
|
416
|
-
let(:error) { double(:error, :message =>
|
412
|
+
let(:error) { double(:error, :message => "test message", :backtrace => ["line 1"]) }
|
417
413
|
|
418
414
|
it "should also respond to add_exception for backwords compatibility" do
|
419
415
|
transaction.should respond_to(:add_exception)
|
420
416
|
end
|
421
417
|
|
422
|
-
it "should not add the error if it's in the ignored list" do
|
423
|
-
Appsignal.stub(:is_ignored_error? => true)
|
424
|
-
transaction.ext.should_not_receive(:set_error)
|
425
|
-
|
426
|
-
transaction.set_error(error)
|
427
|
-
end
|
428
|
-
|
429
418
|
it "should not add the error if appsignal is not active" do
|
430
419
|
Appsignal.stub(:active? => false)
|
431
420
|
transaction.ext.should_not_receive(:set_error)
|
@@ -436,9 +425,9 @@ describe Appsignal::Transaction do
|
|
436
425
|
context "for a http request" do
|
437
426
|
it "should set an error in the extension" do
|
438
427
|
transaction.ext.should_receive(:set_error).with(
|
439
|
-
|
440
|
-
|
441
|
-
Appsignal::Utils.data_generate([
|
428
|
+
"RSpec::Mocks::Mock",
|
429
|
+
"test message",
|
430
|
+
Appsignal::Utils.data_generate(["line 1"])
|
442
431
|
)
|
443
432
|
|
444
433
|
transaction.set_error(error)
|
@@ -446,17 +435,17 @@ describe Appsignal::Transaction do
|
|
446
435
|
end
|
447
436
|
|
448
437
|
context "when error message is nil" do
|
449
|
-
let(:error) { double(:error, :message => nil, :backtrace => [
|
438
|
+
let(:error) { double(:error, :message => nil, :backtrace => ["line 1"]) }
|
450
439
|
|
451
440
|
it "should not raise an error" do
|
452
|
-
expect{ transaction.set_error(error) }.to_not raise_error
|
441
|
+
expect { transaction.set_error(error) }.to_not raise_error
|
453
442
|
end
|
454
443
|
|
455
444
|
it "should set an error in the extension" do
|
456
445
|
transaction.ext.should_receive(:set_error).with(
|
457
|
-
|
458
|
-
|
459
|
-
Appsignal::Utils.data_generate([
|
446
|
+
"RSpec::Mocks::Mock",
|
447
|
+
"",
|
448
|
+
Appsignal::Utils.data_generate(["line 1"])
|
460
449
|
)
|
461
450
|
|
462
451
|
transaction.set_error(error)
|
@@ -475,32 +464,32 @@ describe Appsignal::Transaction do
|
|
475
464
|
describe "#finish_event" do
|
476
465
|
it "should finish the event in the extension" do
|
477
466
|
transaction.ext.should_receive(:finish_event).with(
|
478
|
-
|
479
|
-
|
480
|
-
|
467
|
+
"name",
|
468
|
+
"title",
|
469
|
+
"body",
|
481
470
|
1,
|
482
471
|
0
|
483
472
|
)
|
484
473
|
|
485
474
|
transaction.finish_event(
|
486
|
-
|
487
|
-
|
488
|
-
|
475
|
+
"name",
|
476
|
+
"title",
|
477
|
+
"body",
|
489
478
|
1
|
490
479
|
)
|
491
480
|
end
|
492
481
|
|
493
482
|
it "should finish the event in the extension with nil arguments" do
|
494
483
|
transaction.ext.should_receive(:finish_event).with(
|
495
|
-
|
496
|
-
|
497
|
-
|
484
|
+
"name",
|
485
|
+
"",
|
486
|
+
"",
|
498
487
|
0,
|
499
488
|
0
|
500
489
|
)
|
501
490
|
|
502
491
|
transaction.finish_event(
|
503
|
-
|
492
|
+
"name",
|
504
493
|
nil,
|
505
494
|
nil,
|
506
495
|
nil
|
@@ -512,24 +501,24 @@ describe Appsignal::Transaction do
|
|
512
501
|
.to receive(:internal_profiler)
|
513
502
|
.and_return(FakeGCProfiler.new(0.12345))
|
514
503
|
|
515
|
-
transaction.finish_event(
|
504
|
+
transaction.finish_event("name", nil, nil, nil)
|
516
505
|
end
|
517
506
|
end
|
518
507
|
|
519
508
|
describe "#record_event" do
|
520
509
|
it "should record the event in the extension" do
|
521
510
|
transaction.ext.should_receive(:record_event).with(
|
522
|
-
|
523
|
-
|
524
|
-
|
511
|
+
"name",
|
512
|
+
"title",
|
513
|
+
"body",
|
525
514
|
1000,
|
526
515
|
1
|
527
516
|
)
|
528
517
|
|
529
518
|
transaction.record_event(
|
530
|
-
|
531
|
-
|
532
|
-
|
519
|
+
"name",
|
520
|
+
"title",
|
521
|
+
"body",
|
533
522
|
1000,
|
534
523
|
1
|
535
524
|
)
|
@@ -537,15 +526,15 @@ describe Appsignal::Transaction do
|
|
537
526
|
|
538
527
|
it "should finish the event in the extension with nil arguments" do
|
539
528
|
transaction.ext.should_receive(:record_event).with(
|
540
|
-
|
541
|
-
|
542
|
-
|
529
|
+
"name",
|
530
|
+
"",
|
531
|
+
"",
|
543
532
|
1000,
|
544
533
|
0
|
545
534
|
)
|
546
535
|
|
547
536
|
transaction.record_event(
|
548
|
-
|
537
|
+
"name",
|
549
538
|
nil,
|
550
539
|
nil,
|
551
540
|
1000,
|
@@ -557,19 +546,19 @@ describe Appsignal::Transaction do
|
|
557
546
|
describe "#instrument" do
|
558
547
|
it "should start and finish an event around the given block" do
|
559
548
|
stub = double
|
560
|
-
stub.should_receive(:method_call).and_return(
|
549
|
+
stub.should_receive(:method_call).and_return("return value")
|
561
550
|
|
562
551
|
transaction.should_receive(:start_event)
|
563
552
|
transaction.should_receive(:finish_event).with(
|
564
|
-
|
565
|
-
|
566
|
-
|
553
|
+
"name",
|
554
|
+
"title",
|
555
|
+
"body",
|
567
556
|
0
|
568
557
|
)
|
569
558
|
|
570
|
-
transaction.instrument
|
559
|
+
transaction.instrument "name", "title", "body" do
|
571
560
|
stub.method_call
|
572
|
-
end.should eq
|
561
|
+
end.should eq "return value"
|
573
562
|
end
|
574
563
|
end
|
575
564
|
|
@@ -584,13 +573,13 @@ describe Appsignal::Transaction do
|
|
584
573
|
context "with a filled env" do
|
585
574
|
let(:env) do
|
586
575
|
{
|
587
|
-
:params => {:id => 1},
|
576
|
+
:params => { :id => 1 },
|
588
577
|
:queue_start => 10
|
589
578
|
}
|
590
579
|
end
|
591
580
|
|
592
581
|
its(:env) { should eq env }
|
593
|
-
its(:params) { should eq(
|
582
|
+
its(:params) { should eq(:id => 1) }
|
594
583
|
end
|
595
584
|
end
|
596
585
|
|
@@ -599,6 +588,18 @@ describe Appsignal::Transaction do
|
|
599
588
|
describe "#background_queue_start" do
|
600
589
|
subject { transaction.send(:background_queue_start) }
|
601
590
|
|
591
|
+
context "when request is nil" do
|
592
|
+
let(:request) { nil }
|
593
|
+
|
594
|
+
it { should eq nil }
|
595
|
+
end
|
596
|
+
|
597
|
+
context "when env is nil" do
|
598
|
+
before { expect(transaction.request).to receive(:env).and_return(nil) }
|
599
|
+
|
600
|
+
it { should eq nil }
|
601
|
+
end
|
602
|
+
|
602
603
|
context "when queue start is nil" do
|
603
604
|
it { should eq nil }
|
604
605
|
end
|
@@ -606,7 +607,7 @@ describe Appsignal::Transaction do
|
|
606
607
|
context "when queue start is set" do
|
607
608
|
let(:env) { background_env_with_data }
|
608
609
|
|
609
|
-
it { should eq
|
610
|
+
it { should eq 1_389_783_590_000 }
|
610
611
|
end
|
611
612
|
end
|
612
613
|
|
@@ -616,8 +617,14 @@ describe Appsignal::Transaction do
|
|
616
617
|
subject { transaction.send(:http_queue_start) }
|
617
618
|
|
618
619
|
shared_examples "http queue start" do
|
620
|
+
context "when request is nil" do
|
621
|
+
let(:request) { nil }
|
622
|
+
|
623
|
+
it { should be_nil }
|
624
|
+
end
|
625
|
+
|
619
626
|
context "when env is nil" do
|
620
|
-
before { transaction.request.
|
627
|
+
before { expect(transaction.request).to receive(:env).and_return(nil) }
|
621
628
|
|
622
629
|
it { should be_nil }
|
623
630
|
end
|
@@ -629,32 +636,32 @@ describe Appsignal::Transaction do
|
|
629
636
|
end
|
630
637
|
|
631
638
|
context "with the HTTP_X_REQUEST_START header set" do
|
632
|
-
let(:env) { {
|
639
|
+
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{slightly_earlier_time_value}" } }
|
633
640
|
|
634
|
-
it { should eq
|
641
|
+
it { should eq 1_389_783_599_600 }
|
635
642
|
|
636
643
|
context "with unparsable content" do
|
637
|
-
let(:env) { {
|
644
|
+
let(:env) { { "HTTP_X_REQUEST_START" => "something" } }
|
638
645
|
|
639
646
|
it { should be_nil }
|
640
647
|
end
|
641
648
|
|
642
649
|
context "with some cruft" do
|
643
|
-
let(:env) { {
|
650
|
+
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{slightly_earlier_time_value}aaaa" } }
|
644
651
|
|
645
|
-
it { should eq
|
652
|
+
it { should eq 1_389_783_599_600 }
|
646
653
|
end
|
647
654
|
|
648
655
|
context "with a really low number" do
|
649
|
-
let(:env) { {
|
656
|
+
let(:env) { { "HTTP_X_REQUEST_START" => "t=100" } }
|
650
657
|
|
651
658
|
it { should be_nil }
|
652
659
|
end
|
653
660
|
|
654
661
|
context "with the alternate HTTP_X_QUEUE_START header set" do
|
655
|
-
let(:env) { {
|
662
|
+
let(:env) { { "HTTP_X_QUEUE_START" => "t=#{slightly_earlier_time_value}" } }
|
656
663
|
|
657
|
-
it { should eq
|
664
|
+
it { should eq 1_389_783_599_600 }
|
658
665
|
end
|
659
666
|
end
|
660
667
|
end
|
@@ -688,7 +695,7 @@ describe Appsignal::Transaction do
|
|
688
695
|
end
|
689
696
|
|
690
697
|
context "when params method does not exist" do
|
691
|
-
let(:options) { {:params_method => :nonsense} }
|
698
|
+
let(:options) { { :params_method => :nonsense } }
|
692
699
|
|
693
700
|
it { should be_nil }
|
694
701
|
end
|
@@ -702,16 +709,16 @@ describe Appsignal::Transaction do
|
|
702
709
|
|
703
710
|
context "with an array" do
|
704
711
|
let(:request) do
|
705
|
-
Appsignal::Transaction::GenericRequest.new(background_env_with_data(:params => [
|
712
|
+
Appsignal::Transaction::GenericRequest.new(background_env_with_data(:params => ["arg1", "arg2"]))
|
706
713
|
end
|
707
714
|
|
708
|
-
it { should eq [
|
715
|
+
it { should eq ["arg1", "arg2"] }
|
709
716
|
|
710
717
|
context "with AppSignal filtering" do
|
711
718
|
before { Appsignal.config.config_hash[:filter_parameters] = %w(foo) }
|
712
719
|
after { Appsignal.config.config_hash[:filter_parameters] = [] }
|
713
720
|
|
714
|
-
it { should eq [
|
721
|
+
it { should eq ["arg1", "arg2"] }
|
715
722
|
end
|
716
723
|
end
|
717
724
|
|
@@ -724,7 +731,7 @@ describe Appsignal::Transaction do
|
|
724
731
|
|
725
732
|
it "should call the params sanitizer" do
|
726
733
|
puts Appsignal.config.config_hash[:filter_parameters].inspect
|
727
|
-
subject.should eq(
|
734
|
+
subject.should eq(:foo => :bar)
|
728
735
|
end
|
729
736
|
end
|
730
737
|
|
@@ -737,10 +744,7 @@ describe Appsignal::Transaction do
|
|
737
744
|
after { Appsignal.config.config_hash[:filter_parameters] = [] }
|
738
745
|
|
739
746
|
it "should call the params sanitizer with filtering" do
|
740
|
-
subject.should eq(
|
741
|
-
:foo => '[FILTERED]',
|
742
|
-
:baz => :bat
|
743
|
-
})
|
747
|
+
subject.should eq(:foo => "[FILTERED]", :baz => :bat)
|
744
748
|
end
|
745
749
|
end
|
746
750
|
end
|
@@ -751,18 +755,26 @@ describe Appsignal::Transaction do
|
|
751
755
|
|
752
756
|
subject { transaction.send(:sanitized_environment) }
|
753
757
|
|
758
|
+
context "when request is nil" do
|
759
|
+
let(:request) { nil }
|
760
|
+
|
761
|
+
it "returns nil" do
|
762
|
+
expect(subject).to be_nil
|
763
|
+
end
|
764
|
+
end
|
765
|
+
|
754
766
|
context "when env is nil" do
|
755
|
-
before { transaction.request.
|
767
|
+
before { expect(transaction.request).to receive(:env).and_return(nil) }
|
756
768
|
|
757
769
|
it { should be_nil }
|
758
770
|
end
|
759
771
|
|
760
772
|
context "when env is present" do
|
761
773
|
let(:env) do
|
762
|
-
|
774
|
+
{}.tap do |hash|
|
763
775
|
whitelisted_keys.each { |o| hash[o] = 1 } # use all whitelisted keys
|
764
776
|
hash[whitelisted_keys] = nil # don't add if nil
|
765
|
-
hash[:not_whitelisted] =
|
777
|
+
hash[:not_whitelisted] = "I will be sanitized"
|
766
778
|
end
|
767
779
|
end
|
768
780
|
|
@@ -770,17 +782,25 @@ describe Appsignal::Transaction do
|
|
770
782
|
end
|
771
783
|
end
|
772
784
|
|
773
|
-
describe
|
785
|
+
describe "#sanitized_session_data" do
|
774
786
|
subject { transaction.send(:sanitized_session_data) }
|
775
787
|
|
776
|
-
context "when
|
777
|
-
|
788
|
+
context "when request is nil" do
|
789
|
+
let(:request) { nil }
|
790
|
+
|
791
|
+
it "returns nil" do
|
792
|
+
expect(subject).to be_nil
|
793
|
+
end
|
794
|
+
end
|
795
|
+
|
796
|
+
context "when session is nil" do
|
797
|
+
before { expect(transaction.request).to receive(:session).and_return(nil) }
|
778
798
|
|
779
799
|
it { should be_nil }
|
780
800
|
end
|
781
801
|
|
782
|
-
context "when
|
783
|
-
before { transaction.request.
|
802
|
+
context "when session is empty" do
|
803
|
+
before { expect(transaction.request).to receive(:session).and_return({}) }
|
784
804
|
|
785
805
|
it { should eq({}) }
|
786
806
|
end
|
@@ -794,13 +814,13 @@ describe Appsignal::Transaction do
|
|
794
814
|
context "when there is a session" do
|
795
815
|
before do
|
796
816
|
transaction.should respond_to(:request)
|
797
|
-
transaction.stub_chain(:request, :session => {:foo => :bar})
|
817
|
+
transaction.stub_chain(:request, :session => { :foo => :bar })
|
798
818
|
transaction.stub_chain(:request, :fullpath => :bar)
|
799
819
|
end
|
800
820
|
|
801
821
|
it "passes the session data into the params sanitizer" do
|
802
|
-
Appsignal::Utils::ParamsSanitizer.should_receive(:sanitize).with(
|
803
|
-
and_return(:sanitized_foo)
|
822
|
+
Appsignal::Utils::ParamsSanitizer.should_receive(:sanitize).with(:foo => :bar)
|
823
|
+
.and_return(:sanitized_foo)
|
804
824
|
subject.should eq :sanitized_foo
|
805
825
|
end
|
806
826
|
|
@@ -813,24 +833,29 @@ describe Appsignal::Transaction do
|
|
813
833
|
end
|
814
834
|
|
815
835
|
it "should return an session hash" do
|
816
|
-
Appsignal::Utils::ParamsSanitizer.should_receive(:sanitize).with(
|
817
|
-
and_return(:sanitized_foo)
|
836
|
+
Appsignal::Utils::ParamsSanitizer.should_receive(:sanitize).with("foo" => :bar)
|
837
|
+
.and_return(:sanitized_foo)
|
818
838
|
subject
|
819
839
|
end
|
820
840
|
|
821
841
|
def action_dispatch_session
|
822
|
-
store = Class.new
|
823
|
-
def load_session(
|
824
|
-
|
825
|
-
|
826
|
-
|
842
|
+
store = Class.new do
|
843
|
+
def load_session(_env)
|
844
|
+
[1, { :foo => :bar }]
|
845
|
+
end
|
846
|
+
|
847
|
+
def session_exists?(_env)
|
848
|
+
true
|
849
|
+
end
|
850
|
+
end.new
|
851
|
+
ActionDispatch::Request::Session.create(store, ActionDispatch::Request.new("rack.input" => StringIO.new), {})
|
827
852
|
end
|
828
853
|
end
|
829
854
|
end
|
830
855
|
|
831
856
|
context "when skipping session data" do
|
832
857
|
before do
|
833
|
-
Appsignal.config = {:skip_session_data => true}
|
858
|
+
Appsignal.config = { :skip_session_data => true }
|
834
859
|
end
|
835
860
|
|
836
861
|
it "does not pass the session data into the params sanitizer" do
|
@@ -844,33 +869,37 @@ describe Appsignal::Transaction do
|
|
844
869
|
describe "#metadata" do
|
845
870
|
subject { transaction.send(:metadata) }
|
846
871
|
|
872
|
+
context "when request is nil" do
|
873
|
+
let(:request) { nil }
|
874
|
+
|
875
|
+
it { should be_nil }
|
876
|
+
end
|
877
|
+
|
847
878
|
context "when env is nil" do
|
848
|
-
before { transaction.request.
|
879
|
+
before { expect(transaction.request).to receive(:env).and_return(nil) }
|
849
880
|
|
850
881
|
it { should be_nil }
|
851
882
|
end
|
852
883
|
|
853
884
|
context "when env is present" do
|
854
|
-
let(:env) { {:metadata => {:key =>
|
885
|
+
let(:env) { { :metadata => { :key => "value" } } }
|
855
886
|
|
856
887
|
it { should eq env[:metadata] }
|
857
888
|
end
|
858
889
|
end
|
859
890
|
|
860
|
-
describe
|
891
|
+
describe "#sanitized_tags" do
|
861
892
|
before do
|
862
893
|
transaction.set_tags(
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
SecureRandom.urlsafe_base64(101) => 'to_long_key'
|
873
|
-
}
|
894
|
+
:valid_key => "valid_value",
|
895
|
+
"valid_string_key" => "valid_value",
|
896
|
+
:both_symbols => :valid_value,
|
897
|
+
:integer_value => 1,
|
898
|
+
:hash_value => { "invalid" => "hash" },
|
899
|
+
:array_value => ["invalid", "array"],
|
900
|
+
:to_long_value => SecureRandom.urlsafe_base64(101),
|
901
|
+
:object => Object.new,
|
902
|
+
SecureRandom.urlsafe_base64(101) => "to_long_key"
|
874
903
|
)
|
875
904
|
end
|
876
905
|
subject { transaction.send(:sanitized_tags).keys }
|
@@ -878,7 +907,7 @@ describe Appsignal::Transaction do
|
|
878
907
|
it "should only return whitelisted data" do
|
879
908
|
should =~ [
|
880
909
|
:valid_key,
|
881
|
-
|
910
|
+
"valid_string_key",
|
882
911
|
:both_symbols,
|
883
912
|
:integer_value
|
884
913
|
]
|
@@ -886,10 +915,10 @@ describe Appsignal::Transaction do
|
|
886
915
|
end
|
887
916
|
|
888
917
|
describe "#cleaned_backtrace" do
|
889
|
-
subject { transaction.send(:cleaned_backtrace, [
|
918
|
+
subject { transaction.send(:cleaned_backtrace, ["line 1", "line 2"]) }
|
890
919
|
|
891
920
|
it "returns the backtrace" do
|
892
|
-
expect(subject).to eq [
|
921
|
+
expect(subject).to eq ["line 1", "line 2"]
|
893
922
|
end
|
894
923
|
|
895
924
|
if rails_present?
|
@@ -898,7 +927,7 @@ describe Appsignal::Transaction do
|
|
898
927
|
::Rails.backtrace_cleaner.add_filter do |line|
|
899
928
|
line.tr("2", "?")
|
900
929
|
end
|
901
|
-
expect(subject).to eq [
|
930
|
+
expect(subject).to eq ["line 1", "line ?"]
|
902
931
|
end
|
903
932
|
end
|
904
933
|
end
|
@@ -909,22 +938,22 @@ describe Appsignal::Transaction do
|
|
909
938
|
subject { Appsignal::Transaction::NilTransaction.new }
|
910
939
|
|
911
940
|
it "should have method stubs" do
|
912
|
-
lambda
|
941
|
+
lambda do
|
913
942
|
subject.complete
|
914
943
|
subject.pause!
|
915
944
|
subject.resume!
|
916
945
|
subject.paused?
|
917
946
|
subject.store(:key)
|
918
947
|
subject.set_tags(:tag => 1)
|
919
|
-
subject.set_action(
|
948
|
+
subject.set_action("action")
|
920
949
|
subject.set_http_or_background_action
|
921
950
|
subject.set_queue_start(1)
|
922
951
|
subject.set_http_or_background_queue_start
|
923
|
-
subject.set_metadata(
|
924
|
-
subject.set_sample_data(
|
952
|
+
subject.set_metadata("key", "value")
|
953
|
+
subject.set_sample_data("key", "data")
|
925
954
|
subject.sample_data
|
926
|
-
subject.set_error(
|
927
|
-
|
955
|
+
subject.set_error("a")
|
956
|
+
end.should_not raise_error
|
928
957
|
end
|
929
958
|
end
|
930
959
|
end
|