appsignal 2.4.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,174 @@
1
+ if DependencyHelper.que_present?
2
+ require "appsignal/integrations/que"
3
+
4
+ describe Appsignal::Integrations::QuePlugin do
5
+ describe "#_run" do
6
+ let(:job_attrs) do
7
+ {
8
+ :job_id => 123,
9
+ :queue => "dfl",
10
+ :job_class => "MyQueJob",
11
+ :priority => 100,
12
+ :args => %w(1 birds),
13
+ :run_at => fixed_time,
14
+ :error_count => 0
15
+ }
16
+ end
17
+
18
+ let(:env) do
19
+ {
20
+ :class => "MyQueJob",
21
+ :method => "run",
22
+ :metadata => {
23
+ :id => 123,
24
+ :queue => "dfl",
25
+ :priority => 100,
26
+ :run_at => fixed_time.to_s,
27
+ :attempts => 0
28
+ },
29
+ :params => %w(1 birds)
30
+ }
31
+ end
32
+
33
+ let(:job) do
34
+ Class.new(::Que::Job) do
35
+ def run(*args)
36
+ end
37
+ end
38
+ end
39
+ let(:instance) { job.new(job_attrs) }
40
+ let(:transaction) do
41
+ Appsignal::Transaction.new(
42
+ SecureRandom.uuid,
43
+ Appsignal::Transaction::BACKGROUND_JOB,
44
+ Appsignal::Transaction::GenericRequest.new(env)
45
+ )
46
+ end
47
+
48
+ before do
49
+ allow(Que).to receive(:execute)
50
+
51
+ start_agent
52
+ expect(Appsignal.active?).to be_truthy
53
+ transaction
54
+
55
+ expect(Appsignal::Transaction).to receive(:create)
56
+ .with(
57
+ kind_of(String),
58
+ Appsignal::Transaction::BACKGROUND_JOB,
59
+ kind_of(Appsignal::Transaction::GenericRequest)
60
+ ).and_return(transaction)
61
+ allow(Appsignal::Transaction).to receive(:current).and_return(transaction)
62
+ expect(transaction.ext).to receive(:finish).and_return(true)
63
+ expect(transaction.ext).to receive(:complete)
64
+ end
65
+
66
+ subject { transaction.to_h }
67
+
68
+ context "success" do
69
+ it "creates a transaction for a job" do
70
+ expect do
71
+ instance._run
72
+ end.to_not raise_exception
73
+
74
+ expect(subject).to include(
75
+ "action" => "MyQueJob#run",
76
+ "id" => instance_of(String),
77
+ "namespace" => Appsignal::Transaction::BACKGROUND_JOB
78
+ )
79
+ expect(subject["error"]).to be_nil
80
+ expect(subject["events"].first).to include(
81
+ "allocation_count" => kind_of(Integer),
82
+ "body" => "",
83
+ "body_format" => Appsignal::EventFormatter::DEFAULT,
84
+ "child_allocation_count" => kind_of(Integer),
85
+ "child_duration" => kind_of(Float),
86
+ "child_gc_duration" => kind_of(Float),
87
+ "count" => 1,
88
+ "gc_duration" => kind_of(Float),
89
+ "start" => kind_of(Float),
90
+ "duration" => kind_of(Float),
91
+ "name" => "perform_job.que",
92
+ "title" => ""
93
+ )
94
+ expect(subject["sample_data"]).to include(
95
+ "params" => %w(1 birds),
96
+ "metadata" => {
97
+ "attempts" => 0,
98
+ "id" => 123,
99
+ "priority" => 100,
100
+ "queue" => "dfl",
101
+ "run_at" => fixed_time.to_s
102
+ }
103
+ )
104
+ end
105
+ end
106
+
107
+ context "with exception" do
108
+ let(:error) { ExampleException.new("oh no!") }
109
+
110
+ it "should report exceptions and re-raise them" do
111
+ allow(instance).to receive(:run).and_raise(error)
112
+
113
+ expect do
114
+ instance._run
115
+ end.to raise_error(ExampleException)
116
+
117
+ expect(subject).to include(
118
+ "action" => "MyQueJob#run",
119
+ "id" => instance_of(String),
120
+ "namespace" => Appsignal::Transaction::BACKGROUND_JOB
121
+ )
122
+ expect(subject["error"]).to include(
123
+ "backtrace" => kind_of(String),
124
+ "name" => error.class.name,
125
+ "message" => error.message
126
+ )
127
+ expect(subject["sample_data"]).to include(
128
+ "params" => %w(1 birds),
129
+ "metadata" => {
130
+ "attempts" => 0,
131
+ "id" => 123,
132
+ "priority" => 100,
133
+ "queue" => "dfl",
134
+ "run_at" => fixed_time.to_s
135
+ }
136
+ )
137
+ end
138
+ end
139
+
140
+ context "with error" do
141
+ let(:error) { ExampleStandardError.new("oh no!") }
142
+
143
+ it "should report errors and not re-raise them" do
144
+ allow(instance).to receive(:run).and_raise(error)
145
+
146
+ expect do
147
+ instance._run
148
+ end.to_not raise_error
149
+
150
+ expect(subject).to include(
151
+ "action" => "MyQueJob#run",
152
+ "id" => instance_of(String),
153
+ "namespace" => Appsignal::Transaction::BACKGROUND_JOB
154
+ )
155
+ expect(subject["error"]).to include(
156
+ "backtrace" => kind_of(String),
157
+ "name" => error.class.name,
158
+ "message" => error.message
159
+ )
160
+ expect(subject["sample_data"]).to include(
161
+ "params" => %w(1 birds),
162
+ "metadata" => {
163
+ "attempts" => 0,
164
+ "id" => 123,
165
+ "priority" => 100,
166
+ "queue" => "dfl",
167
+ "run_at" => fixed_time.to_s
168
+ }
169
+ )
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
@@ -1,3 +1,5 @@
1
+ require "appsignal/system"
2
+
1
3
  describe Appsignal::System do
2
4
  describe ".heroku?" do
3
5
  subject { described_class.heroku? }
@@ -16,4 +18,113 @@ describe Appsignal::System do
16
18
  end
17
19
  end
18
20
  end
21
+
22
+ describe ".installed_agent_platform" do
23
+ let(:const_name) { "GEM_EXT_PATH".freeze }
24
+ let(:tmp_ext_dir) { File.join(tmp_dir, "ext") }
25
+ let(:platform_file) { File.join(Appsignal::System::GEM_EXT_PATH, "appsignal.platform") }
26
+ around do |example|
27
+ original_gem_ext_path = Appsignal::System.const_get(const_name)
28
+ Appsignal::System.send(:remove_const, const_name)
29
+ Appsignal::System.const_set(const_name, tmp_ext_dir)
30
+ example.run
31
+ Appsignal::System.send(:remove_const, const_name)
32
+ Appsignal::System.const_set(const_name, original_gem_ext_path)
33
+ end
34
+ after { FileUtils.rm_rf(tmp_ext_dir) }
35
+ subject { described_class.installed_agent_platform }
36
+
37
+ context "with an ext/appsignal.platform file" do
38
+ before do
39
+ FileUtils.mkdir_p(Appsignal::System::GEM_EXT_PATH)
40
+ File.open(platform_file, "w") do |file|
41
+ file.write "foo"
42
+ end
43
+ end
44
+
45
+ it "returns the contents of the file" do
46
+ expect(subject).to eq("foo")
47
+ end
48
+ end
49
+
50
+ context "without an ext/appsignal.platform file" do
51
+ it "returns nil" do
52
+ expect(subject).to be_nil
53
+ end
54
+ end
55
+ end
56
+
57
+ describe ".agent_platform" do
58
+ let(:os) { "linux" }
59
+ let(:ldd_output) { "" }
60
+ before do
61
+ allow(described_class).to receive(:ldd_version_output).and_return(ldd_output)
62
+ allow(Gem::Platform.local).to receive(:os).and_return(os)
63
+ end
64
+ subject { described_class.agent_platform }
65
+
66
+ context "when the system detection doesn't work" do
67
+ it "returns the libc build" do
68
+ is_expected.to eq("linux")
69
+ end
70
+ end
71
+
72
+ context "when using the APPSIGNAL_BUILD_FOR_MUSL env var" do
73
+ it "returns the musl build" do
74
+ ENV["APPSIGNAL_BUILD_FOR_MUSL"] = "1"
75
+ is_expected.to eq("linux-musl")
76
+ ENV.delete("APPSIGNAL_BUILD_FOR_MUSL")
77
+ end
78
+ end
79
+
80
+ context "when on a musl system" do
81
+ let(:ldd_output) { "musl libc (x86_64)\nVersion 1.1.16" }
82
+
83
+ it "returns the musl build" do
84
+ is_expected.to eq("linux-musl")
85
+ end
86
+ end
87
+
88
+ context "when on a libc system" do
89
+ let(:ldd_output) { "ldd (Debian GLIBC 2.15-18+deb8u7) 2.15" }
90
+
91
+ it "returns the libc build" do
92
+ is_expected.to eq("linux")
93
+ end
94
+
95
+ context "when on an old libc system" do
96
+ let(:ldd_output) { "ldd (Debian GLIBC 2.14-18+deb8u7) 2.14" }
97
+
98
+ it "returns the musl build" do
99
+ is_expected.to eq("linux-musl")
100
+ end
101
+ end
102
+
103
+ context "when on a very old libc system" do
104
+ let(:ldd_output) { "ldd (Debian GLIBC 2.5-18+deb8u7) 2.5" }
105
+
106
+ it "returns the musl build" do
107
+ is_expected.to eq("linux-musl")
108
+ end
109
+ end
110
+ end
111
+
112
+ context "when on macOS" do
113
+ let(:os) { "darwin" }
114
+ let(:ldd_output) { "ldd: command not found" }
115
+
116
+ it "returns the darwin build" do
117
+ is_expected.to eq("darwin")
118
+ end
119
+ end
120
+
121
+ context "when on FreeBSD" do
122
+ let(:os) { "freebsd" }
123
+ let(:ldd_output) { "ldd: illegal option -- -" }
124
+
125
+ it "returns the darwin build" do
126
+ is_expected.to eq("freebsd")
127
+ end
128
+ end
129
+ end
19
130
  end
@@ -63,6 +63,10 @@ module DependencyHelper
63
63
  Gem.loaded_specs["capistrano"].version >= Gem::Version.new("3.0")
64
64
  end
65
65
 
66
+ def que_present?
67
+ dependency_present? "que"
68
+ end
69
+
66
70
  def dependency_present?(dependency_file)
67
71
  Gem.loaded_specs.key? dependency_file
68
72
  end
@@ -1,15 +1,20 @@
1
1
  module LogHelpers
2
2
  def use_logger_with(log)
3
- Appsignal.logger = Logger.new(log)
4
- Appsignal.logger.formatter =
5
- proc do |severity, _datetime, _progname, msg|
6
- # This format is used in the `contains_log` matcher.
7
- "[#{severity}] #{msg}\n"
8
- end
3
+ Appsignal.logger = test_logger(log)
9
4
  yield
10
5
  Appsignal.logger = nil
11
6
  end
12
7
 
8
+ def test_logger(log)
9
+ Logger.new(log).tap do |logger|
10
+ logger.formatter =
11
+ proc do |severity, _datetime, _progname, msg|
12
+ # This format is used in the `contains_log` matcher.
13
+ "[#{severity}] #{msg}\n"
14
+ end
15
+ end
16
+ end
17
+
13
18
  def log_contents(log)
14
19
  log.rewind
15
20
  log.read
@@ -28,4 +28,10 @@ module TransactionHelpers
28
28
  }.merge(args))
29
29
  )
30
30
  end
31
+
32
+ # Use when {Appsignal::Transaction.clear_current_transaction!} is stubbed to
33
+ # clear the current transaction on the current thread.
34
+ def clear_current_transaction!
35
+ Thread.current[:appsignal_transaction] = nil
36
+ end
31
37
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appsignal
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Beekman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-10-31 00:00:00.000000000 Z
12
+ date: 2017-11-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -154,6 +154,7 @@ files:
154
154
  - gemfiles/grape.gemfile
155
155
  - gemfiles/no_dependencies.gemfile
156
156
  - gemfiles/padrino.gemfile
157
+ - gemfiles/que.gemfile
157
158
  - gemfiles/rails-3.2.gemfile
158
159
  - gemfiles/rails-4.0.gemfile
159
160
  - gemfiles/rails-4.1.gemfile
@@ -196,6 +197,7 @@ files:
196
197
  - lib/appsignal/hooks/net_http.rb
197
198
  - lib/appsignal/hooks/passenger.rb
198
199
  - lib/appsignal/hooks/puma.rb
200
+ - lib/appsignal/hooks/que.rb
199
201
  - lib/appsignal/hooks/rake.rb
200
202
  - lib/appsignal/hooks/redis.rb
201
203
  - lib/appsignal/hooks/sequel.rb
@@ -211,6 +213,7 @@ files:
211
213
  - lib/appsignal/integrations/mongo_ruby_driver.rb
212
214
  - lib/appsignal/integrations/object.rb
213
215
  - lib/appsignal/integrations/padrino.rb
216
+ - lib/appsignal/integrations/que.rb
214
217
  - lib/appsignal/integrations/railtie.rb
215
218
  - lib/appsignal/integrations/rake.rb
216
219
  - lib/appsignal/integrations/resque.rb
@@ -266,6 +269,7 @@ files:
266
269
  - spec/lib/appsignal/hooks/net_http_spec.rb
267
270
  - spec/lib/appsignal/hooks/passenger_spec.rb
268
271
  - spec/lib/appsignal/hooks/puma_spec.rb
272
+ - spec/lib/appsignal/hooks/que_spec.rb
269
273
  - spec/lib/appsignal/hooks/rake_spec.rb
270
274
  - spec/lib/appsignal/hooks/redis_spec.rb
271
275
  - spec/lib/appsignal/hooks/sequel_spec.rb
@@ -279,6 +283,7 @@ files:
279
283
  - spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb
280
284
  - spec/lib/appsignal/integrations/object_spec.rb
281
285
  - spec/lib/appsignal/integrations/padrino_spec.rb
286
+ - spec/lib/appsignal/integrations/que_spec.rb
282
287
  - spec/lib/appsignal/integrations/railtie_spec.rb
283
288
  - spec/lib/appsignal/integrations/resque_active_job_spec.rb
284
289
  - spec/lib/appsignal/integrations/resque_spec.rb
@@ -389,6 +394,7 @@ test_files:
389
394
  - spec/lib/appsignal/hooks/net_http_spec.rb
390
395
  - spec/lib/appsignal/hooks/passenger_spec.rb
391
396
  - spec/lib/appsignal/hooks/puma_spec.rb
397
+ - spec/lib/appsignal/hooks/que_spec.rb
392
398
  - spec/lib/appsignal/hooks/rake_spec.rb
393
399
  - spec/lib/appsignal/hooks/redis_spec.rb
394
400
  - spec/lib/appsignal/hooks/sequel_spec.rb
@@ -402,6 +408,7 @@ test_files:
402
408
  - spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb
403
409
  - spec/lib/appsignal/integrations/object_spec.rb
404
410
  - spec/lib/appsignal/integrations/padrino_spec.rb
411
+ - spec/lib/appsignal/integrations/que_spec.rb
405
412
  - spec/lib/appsignal/integrations/railtie_spec.rb
406
413
  - spec/lib/appsignal/integrations/resque_active_job_spec.rb
407
414
  - spec/lib/appsignal/integrations/resque_spec.rb