appsignal 1.0.7 → 1.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/.travis.yml +1 -0
- data/CHANGELOG.md +5 -21
- data/Rakefile +2 -0
- data/circle.yml +2 -1
- data/ext/agent.yml +7 -7
- data/ext/appsignal_extension.c +3 -5
- data/ext/extconf.rb +6 -15
- data/gemfiles/grape.gemfile +7 -0
- data/lib/appsignal/config.rb +2 -5
- data/lib/appsignal/event_formatter.rb +0 -2
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +47 -1
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +29 -0
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +7 -6
- data/lib/appsignal/hooks.rb +33 -0
- data/lib/appsignal/hooks/net_http.rb +1 -1
- data/lib/appsignal/hooks/sequel.rb +7 -4
- data/lib/appsignal/hooks/sidekiq.rb +10 -19
- data/lib/appsignal/integrations/capistrano/appsignal.cap +1 -1
- data/lib/appsignal/integrations/delayed_job_plugin.rb +20 -11
- data/lib/appsignal/integrations/grape.rb +44 -0
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +5 -9
- data/lib/appsignal/integrations/railtie.rb +4 -0
- data/lib/appsignal/integrations/resque.rb +1 -1
- data/lib/appsignal/js_exception_transaction.rb +2 -3
- data/lib/appsignal/subscriber.rb +2 -3
- data/lib/appsignal/transaction.rb +2 -8
- data/lib/appsignal/transmitter.rb +1 -1
- data/lib/appsignal/utils.rb +7 -43
- data/lib/appsignal/version.rb +1 -1
- data/lib/tasks/diag.rake +75 -0
- data/spec/lib/appsignal/capistrano3_spec.rb +1 -21
- data/spec/lib/appsignal/config_spec.rb +0 -12
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +1 -1
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +186 -14
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +54 -0
- data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +4 -4
- data/spec/lib/appsignal/extension_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +49 -14
- data/spec/lib/appsignal/hooks/sequel_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +29 -62
- data/spec/lib/appsignal/hooks_spec.rb +115 -0
- data/spec/lib/appsignal/integrations/grape_spec.rb +94 -0
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +5 -8
- data/spec/lib/appsignal/integrations/resque_spec.rb +0 -1
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +0 -1
- data/spec/lib/appsignal/subscriber_spec.rb +5 -23
- data/spec/lib/appsignal/transaction_spec.rb +0 -21
- data/spec/lib/appsignal/utils_spec.rb +1 -68
- data/spec/spec_helper.rb +16 -0
- data/spec/support/helpers/env_helpers.rb +0 -1
- data/spec/support/stubs/delayed_job.rb +0 -0
- metadata +15 -11
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +0 -88
- data/lib/appsignal/event_formatter/sequel/sql_formatter.rb +0 -13
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -115
- data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +0 -22
@@ -4,7 +4,7 @@ describe Appsignal::EventFormatter::ActiveRecord::InstantiationFormatter do
|
|
4
4
|
let(:klass) { Appsignal::EventFormatter::ActiveRecord::InstantiationFormatter }
|
5
5
|
let(:formatter) { klass.new }
|
6
6
|
|
7
|
-
it "should register
|
7
|
+
it "should register request.net_http" do
|
8
8
|
Appsignal::EventFormatter.registered?('instantiation.active_record', klass).should be_true
|
9
9
|
end
|
10
10
|
|
@@ -1,23 +1,195 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
let(:formatter) { klass.new }
|
3
|
+
if active_record_present?
|
4
|
+
require 'active_record'
|
6
5
|
|
7
|
-
|
8
|
-
Appsignal::EventFormatter
|
9
|
-
|
6
|
+
describe Appsignal::EventFormatter::ActiveRecord::SqlFormatter do
|
7
|
+
let(:klass) { Appsignal::EventFormatter::ActiveRecord::SqlFormatter }
|
8
|
+
let(:formatter) { klass.new }
|
9
|
+
let(:connection_config) { {} }
|
10
|
+
before do
|
11
|
+
if ActiveRecord::Base.respond_to?(:connection_config)
|
12
|
+
# Rails 3.1+
|
13
|
+
ActiveRecord::Base.stub(
|
14
|
+
:connection_config => connection_config
|
15
|
+
)
|
16
|
+
else
|
17
|
+
# Rails 3.0
|
18
|
+
spec = double(:config => connection_config)
|
19
|
+
ActiveRecord::Base.stub(
|
20
|
+
:connection_pool => double(:spec => spec)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
pending "should register sql.activerecord" do
|
26
|
+
Appsignal::EventFormatter.registered?('sql.active_record', klass).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
context "if a connection cannot be established" do
|
30
|
+
before do
|
31
|
+
ActiveRecord::Base.stub(:connection_config).and_raise(ActiveRecord::ConnectionNotEstablished)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should log the error and unregister the formatter" do
|
35
|
+
Appsignal.logger.should_receive(:error).with(
|
36
|
+
'Error while getting ActiveRecord connection info, unregistering sql.active_record event formatter'
|
37
|
+
)
|
38
|
+
|
39
|
+
lambda {
|
40
|
+
formatter
|
41
|
+
}.should_not raise_error
|
10
42
|
|
11
|
-
|
12
|
-
|
13
|
-
{
|
14
|
-
name: 'User load',
|
15
|
-
sql: 'SELECT * FROM users'
|
16
|
-
}
|
43
|
+
Appsignal::EventFormatter.registered?('sql.active_record').should be_false
|
44
|
+
end
|
17
45
|
end
|
18
46
|
|
19
|
-
|
47
|
+
describe "#format" do
|
48
|
+
let(:name) { 'Model load' }
|
49
|
+
let(:payload) { {:sql => sql, :name => name} }
|
50
|
+
subject { formatter.format(payload) }
|
51
|
+
|
52
|
+
context "with backtick table names" do
|
53
|
+
before { formatter.stub(:adapter_uses_double_quoted_table_names => false) }
|
54
|
+
|
55
|
+
context "single quoted data value" do
|
56
|
+
let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret' ORDER BY `table`.`id` ASC LIMIT 1" }
|
57
|
+
|
58
|
+
it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ? ORDER BY `table`.`id` ASC LIMIT ?"] }
|
59
|
+
|
60
|
+
context "with escaped single quotes in the string" do
|
61
|
+
let(:sql) { "`id` = 'this is a \'big\' secret'" }
|
62
|
+
|
63
|
+
it { should == ['Model load', "`id` = ?"] }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "double quoted data value" do
|
68
|
+
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = "secret"' }
|
69
|
+
|
70
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
71
|
+
|
72
|
+
context "with escaped double quotes in the string" do
|
73
|
+
let(:sql) { '`id` = "this is a \"big\" secret"' }
|
74
|
+
|
75
|
+
it { should == ['Model load', "`id` = ?"] }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "numeric parameter" do
|
80
|
+
context "integer" do
|
81
|
+
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = 1' }
|
82
|
+
|
83
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
84
|
+
end
|
85
|
+
|
86
|
+
context "float" do
|
87
|
+
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `value` = 10.0' }
|
88
|
+
|
89
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `value` = ?'] }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "in operator with values" do
|
94
|
+
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` IN (1, 2)' }
|
95
|
+
|
96
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` IN (?)'] }
|
97
|
+
end
|
98
|
+
|
99
|
+
context "in operator with inner query" do
|
100
|
+
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` IN (SELECT `id` from `other_table` WHERE `value` = 10.0)' }
|
101
|
+
|
102
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` IN (SELECT `id` from `other_table` WHERE `value` = ?)'] }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "with double quote style table names" do
|
107
|
+
let(:connection_config) { {:adapter => 'postgresql'} }
|
108
|
+
|
109
|
+
context "single quoted data value" do
|
110
|
+
let(:sql) { "SELECT \"table\".* FROM \"table\" WHERE \"id\" = 'secret' ORDER BY \"table\".\"id\" ASC LIMIT 1" }
|
111
|
+
|
112
|
+
it { should == ['Model load', "SELECT \"table\".* FROM \"table\" WHERE \"id\" = ? ORDER BY \"table\".\"id\" ASC LIMIT ?"] }
|
20
113
|
|
21
|
-
|
114
|
+
context "with an escaped single quote" do
|
115
|
+
let(:sql) { "\"id\" = 'this is a \'big\' secret'" }
|
116
|
+
|
117
|
+
it { should == ['Model load', "\"id\" = ?"] }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "numeric parameter" do
|
122
|
+
context "integer" do
|
123
|
+
let(:sql) { 'SELECT "table".* FROM "table" WHERE "id"=1' }
|
124
|
+
|
125
|
+
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "id"=?'] }
|
126
|
+
end
|
127
|
+
|
128
|
+
context "float" do
|
129
|
+
let(:sql) { 'SELECT "table".* FROM "table" WHERE "value"=10.0' }
|
130
|
+
|
131
|
+
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "value"=?'] }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "return nil for schema queries" do
|
137
|
+
let(:name) { 'SCHEMA' }
|
138
|
+
let(:sql) { 'SET client_min_messages TO 22' }
|
139
|
+
|
140
|
+
it { should be_nil }
|
141
|
+
end
|
142
|
+
|
143
|
+
context "with a a frozen sql string" do
|
144
|
+
let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret'".freeze }
|
145
|
+
|
146
|
+
it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ?"] }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "#schema_query?" do
|
151
|
+
let(:payload) { {} }
|
152
|
+
subject { formatter.send(:schema_query?, payload) }
|
153
|
+
|
154
|
+
it { should be_false }
|
155
|
+
|
156
|
+
context "when name is schema" do
|
157
|
+
let(:payload) { {:name => 'SCHEMA'} }
|
158
|
+
|
159
|
+
it { should be_true }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "connection config" do
|
164
|
+
describe "#connection_config" do
|
165
|
+
let(:connection_config) { {:adapter => 'adapter'} }
|
166
|
+
|
167
|
+
subject { formatter.send(:connection_config) }
|
168
|
+
|
169
|
+
it { should == {:adapter => 'adapter'} }
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "#adapter_uses_double_quoted_table_names" do
|
173
|
+
subject { formatter.adapter_uses_double_quoted_table_names }
|
174
|
+
|
175
|
+
context "when using mysql" do
|
176
|
+
let(:connection_config) { {:adapter => 'mysql'} }
|
177
|
+
|
178
|
+
it { should be_false }
|
179
|
+
end
|
180
|
+
|
181
|
+
context "when using postgresql" do
|
182
|
+
let(:connection_config) { {:adapter => 'postgresql'} }
|
183
|
+
|
184
|
+
it { should be_true }
|
185
|
+
end
|
186
|
+
|
187
|
+
context "when using sqlite" do
|
188
|
+
let(:connection_config) { {:adapter => 'sqlite'} }
|
189
|
+
|
190
|
+
it { should be_true }
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
22
194
|
end
|
23
195
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Appsignal::EventFormatter::ElasticSearch::SearchFormatter do
|
4
|
+
let(:klass) { Appsignal::EventFormatter::ElasticSearch::SearchFormatter }
|
5
|
+
let(:formatter) { klass.new }
|
6
|
+
|
7
|
+
it "should register query.moped" do
|
8
|
+
expect(
|
9
|
+
Appsignal::EventFormatter.registered?('search.elasticsearch', klass)
|
10
|
+
).to be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#format" do
|
14
|
+
let(:payload) do
|
15
|
+
{
|
16
|
+
:name => 'Search',
|
17
|
+
:klass => 'User',
|
18
|
+
:search => {:index => 'users', :type => 'user', :q => 'John Doe'}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return a payload with name and sanitized body" do
|
23
|
+
expect( formatter.format(payload) ).to eql([
|
24
|
+
"Search: User",
|
25
|
+
"{:index=>\"users\", :type=>\"user\", :q=>\"?\"}"
|
26
|
+
])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#sanitized_search" do
|
31
|
+
let(:search) do
|
32
|
+
{
|
33
|
+
:index => 'users',
|
34
|
+
:type => 'user',
|
35
|
+
:q => 'John Doe',
|
36
|
+
:other => 'Other'
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should sanitize non-whitelisted params" do
|
41
|
+
expect(
|
42
|
+
formatter.sanitized_search(search)
|
43
|
+
).to eql({:index => 'users', :type => 'user', :q => '?', :other => '?'})
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return nil string when search is nil" do
|
47
|
+
expect( formatter.sanitized_search(nil) ).to be_nil
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return nil string when search is not a hash" do
|
51
|
+
expect( formatter.sanitized_search([]) ).to be_nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -22,12 +22,12 @@ describe Appsignal::EventFormatter::Moped::QueryFormatter do
|
|
22
22
|
let(:op) do
|
23
23
|
double(
|
24
24
|
:full_collection_name => 'database.collection',
|
25
|
-
:selector => {'
|
25
|
+
:selector => {'_id' => 'abc'},
|
26
26
|
:class => double(:to_s => 'Moped::Protocol::Command')
|
27
27
|
)
|
28
28
|
end
|
29
29
|
|
30
|
-
it { should == ['Command', '{:database=>"database.collection", :selector=>{"
|
30
|
+
it { should == ['Command', '{:database=>"database.collection", :selector=>{"_id"=>"?"}}'] }
|
31
31
|
end
|
32
32
|
|
33
33
|
context "Moped::Protocol::Query" do
|
@@ -80,13 +80,13 @@ describe Appsignal::EventFormatter::Moped::QueryFormatter do
|
|
80
80
|
double(
|
81
81
|
:full_collection_name => 'database.collection',
|
82
82
|
:selector => {'_id' => 'abc'},
|
83
|
-
:update => {'
|
83
|
+
:update => {'name' => 'James Bond'},
|
84
84
|
:flags => [],
|
85
85
|
:class => double(:to_s => 'Moped::Protocol::Update')
|
86
86
|
)
|
87
87
|
end
|
88
88
|
|
89
|
-
it { should == ['Update', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :update=>{"
|
89
|
+
it { should == ['Update', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :update=>{"name"=>"?"}, :flags=>[]}'] }
|
90
90
|
end
|
91
91
|
|
92
92
|
context "Moped::Protocol::KillCursors" do
|
@@ -46,7 +46,7 @@ describe "extension loading and operation" do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should have a finish_event method" do
|
49
|
-
subject.finish_event(1, 'name', 'title', 'body'
|
49
|
+
subject.finish_event(1, 'name', 'title', 'body')
|
50
50
|
end
|
51
51
|
|
52
52
|
it "should have a set_transaction_error method" do
|
@@ -28,17 +28,18 @@ describe Appsignal::Hooks::DelayedJobHook do
|
|
28
28
|
describe ".invoke_with_instrumentation" do
|
29
29
|
let(:plugin) { Appsignal::Hooks::DelayedJobPlugin }
|
30
30
|
let(:time) { Time.parse('01-01-2001 10:01:00UTC') }
|
31
|
-
let(:
|
32
|
-
|
31
|
+
let(:job_data) do
|
32
|
+
{
|
33
33
|
:id => 123,
|
34
34
|
:name => 'TestClass#perform',
|
35
35
|
:priority => 1,
|
36
36
|
:attempts => 1,
|
37
37
|
:queue => 'default',
|
38
38
|
:created_at => time - 60_000,
|
39
|
-
:payload_object => double
|
40
|
-
|
39
|
+
:payload_object => double(:args => ['argument']),
|
40
|
+
}
|
41
41
|
end
|
42
|
+
let(:job) { double(job_data) }
|
42
43
|
let(:invoked_block) { Proc.new { } }
|
43
44
|
let(:error) { StandardError.new }
|
44
45
|
|
@@ -54,6 +55,7 @@ describe Appsignal::Hooks::DelayedJobHook do
|
|
54
55
|
:queue => 'default',
|
55
56
|
:id => '123'
|
56
57
|
},
|
58
|
+
:params => ['argument'],
|
57
59
|
:queue_start => time - 60_000,
|
58
60
|
)
|
59
61
|
|
@@ -63,18 +65,19 @@ describe Appsignal::Hooks::DelayedJobHook do
|
|
63
65
|
end
|
64
66
|
|
65
67
|
context "with custom name call" do
|
66
|
-
let(:
|
67
|
-
|
68
|
+
let(:job_data) do
|
69
|
+
{
|
68
70
|
:payload_object => double(
|
69
|
-
:appsignal_name => 'CustomClass#perform'
|
71
|
+
:appsignal_name => 'CustomClass#perform',
|
72
|
+
:args => ['argument']
|
70
73
|
),
|
71
|
-
:id
|
72
|
-
:name
|
73
|
-
:priority
|
74
|
-
:attempts
|
75
|
-
:queue
|
76
|
-
:created_at
|
77
|
-
|
74
|
+
:id => '123',
|
75
|
+
:name => 'TestClass#perform',
|
76
|
+
:priority => 1,
|
77
|
+
:attempts => 1,
|
78
|
+
:queue => 'default',
|
79
|
+
:created_at => time - 60_000
|
80
|
+
}
|
78
81
|
end
|
79
82
|
it "should wrap in a transaction with the correct params" do
|
80
83
|
Appsignal.should_receive(:monitor_transaction).with(
|
@@ -87,6 +90,7 @@ describe Appsignal::Hooks::DelayedJobHook do
|
|
87
90
|
:queue => 'default',
|
88
91
|
:id => '123'
|
89
92
|
},
|
93
|
+
:params => ['argument'],
|
90
94
|
:queue_start => time - 60_000
|
91
95
|
)
|
92
96
|
|
@@ -95,6 +99,37 @@ describe Appsignal::Hooks::DelayedJobHook do
|
|
95
99
|
end
|
96
100
|
end
|
97
101
|
end
|
102
|
+
|
103
|
+
if active_job_present?
|
104
|
+
require 'active_job'
|
105
|
+
|
106
|
+
context "when wrapped by ActiveJob" do
|
107
|
+
before do
|
108
|
+
job_data[:args] = ['argument']
|
109
|
+
end
|
110
|
+
let(:job) { ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper.new(job_data) }
|
111
|
+
|
112
|
+
it "should wrap in a transaction with the correct params" do
|
113
|
+
Appsignal.should_receive(:monitor_transaction).with(
|
114
|
+
'perform_job.delayed_job',
|
115
|
+
:class => 'TestClass',
|
116
|
+
:method => 'perform',
|
117
|
+
:metadata => {
|
118
|
+
:priority => 1,
|
119
|
+
:attempts => 1,
|
120
|
+
:queue => 'default',
|
121
|
+
:id => '123'
|
122
|
+
},
|
123
|
+
:params => ['argument'],
|
124
|
+
:queue_start => time - 60_000,
|
125
|
+
)
|
126
|
+
|
127
|
+
Timecop.freeze(time) do
|
128
|
+
plugin.invoke_with_instrumentation(job, invoked_block)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
98
133
|
end
|
99
134
|
|
100
135
|
context "with an erroring call" do
|
@@ -15,7 +15,7 @@ describe "Sequel integration", if: sequel_present? do
|
|
15
15
|
.at_least(:once)
|
16
16
|
expect( Appsignal::Extension ).to receive(:finish_event)
|
17
17
|
.at_least(:once)
|
18
|
-
.with(kind_of(Integer), "sql.sequel", "",
|
18
|
+
.with(kind_of(Integer), "sql.sequel", "", "")
|
19
19
|
|
20
20
|
db['SELECT 1'].all
|
21
21
|
end
|
@@ -36,21 +36,35 @@ describe Appsignal::Hooks::SidekiqPlugin do
|
|
36
36
|
)
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
item
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
39
|
+
context "when wrapped by ActiveJob" do
|
40
|
+
let(:item) {{
|
41
|
+
"class" => "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper",
|
42
|
+
"wrapped" => "TestClass",
|
43
|
+
"queue" => "default",
|
44
|
+
"args"=> [{
|
45
|
+
"job_class" => "TestJob",
|
46
|
+
"job_id" => "23e79d48-6966-40d0-b2d4-f7938463a263",
|
47
|
+
"queue_name" => "default",
|
48
|
+
"arguments" => ['Model', 1],
|
49
|
+
}],
|
50
|
+
"retry" => true,
|
51
|
+
"jid" => "efb140489485999d32b5504c",
|
52
|
+
"created_at" => Time.parse('01-01-2001 10:00:00UTC').to_f,
|
53
|
+
"enqueued_at" => Time.parse('01-01-2001 10:00:00UTC').to_f
|
54
|
+
}}
|
55
|
+
|
56
|
+
it "should wrap in a transaction with the correct params" do
|
57
|
+
Appsignal.should_receive(:monitor_transaction).with(
|
58
|
+
'perform_job.sidekiq',
|
59
|
+
:class => 'TestClass',
|
60
|
+
:method => 'perform',
|
61
|
+
:metadata => {
|
62
|
+
'queue' => 'default'
|
63
|
+
},
|
64
|
+
:params => ['Model', "1"],
|
65
|
+
:queue_start => Time.parse('01-01-2001 10:00:00UTC').to_f
|
66
|
+
)
|
67
|
+
end
|
54
68
|
end
|
55
69
|
|
56
70
|
after do
|
@@ -92,53 +106,6 @@ describe Appsignal::Hooks::SidekiqPlugin do
|
|
92
106
|
plugin.formatted_metadata(item).should == {'foo' => 'bar'}
|
93
107
|
end
|
94
108
|
end
|
95
|
-
|
96
|
-
describe "#format_args" do
|
97
|
-
let(:object) { Object.new }
|
98
|
-
let(:args) do
|
99
|
-
[
|
100
|
-
'Model',
|
101
|
-
1,
|
102
|
-
object
|
103
|
-
]
|
104
|
-
end
|
105
|
-
|
106
|
-
it "should format the arguments" do
|
107
|
-
plugin.format_args(args).should == ['Model', '1', object.inspect]
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe "#truncate" do
|
112
|
-
let(:very_long_text) do
|
113
|
-
"a" * 400
|
114
|
-
end
|
115
|
-
|
116
|
-
it "should truncate the text to 200 chars max" do
|
117
|
-
plugin.truncate(very_long_text).should == "#{'a' * 197}..."
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe "#string_or_inspect" do
|
122
|
-
context "when string" do
|
123
|
-
it "should return the string" do
|
124
|
-
plugin.string_or_inspect('foo').should == 'foo'
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
context "when integer" do
|
129
|
-
it "should return the string" do
|
130
|
-
plugin.string_or_inspect(1).should == '1'
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
context "when object" do
|
135
|
-
let(:object) { Object.new }
|
136
|
-
|
137
|
-
it "should return the string" do
|
138
|
-
plugin.string_or_inspect(object).should == object.inspect
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
109
|
end
|
143
110
|
|
144
111
|
describe Appsignal::Hooks::SidekiqHook do
|