appsignal 2.5.0.alpha.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +33 -0
- data/.rspec +4 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +124 -0
- data/.travis.yml +72 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +639 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +264 -0
- data/Rakefile +214 -0
- data/appsignal.gemspec +42 -0
- data/benchmark.rake +77 -0
- data/bin/appsignal +13 -0
- data/ext/Rakefile +27 -0
- data/ext/agent.yml +64 -0
- data/ext/appsignal_extension.c +692 -0
- data/ext/base.rb +79 -0
- data/ext/extconf.rb +35 -0
- data/gemfiles/capistrano2.gemfile +7 -0
- data/gemfiles/capistrano3.gemfile +7 -0
- data/gemfiles/grape.gemfile +7 -0
- data/gemfiles/no_dependencies.gemfile +5 -0
- data/gemfiles/padrino.gemfile +7 -0
- data/gemfiles/que.gemfile +5 -0
- data/gemfiles/rails-3.2.gemfile +6 -0
- data/gemfiles/rails-4.0.gemfile +6 -0
- data/gemfiles/rails-4.1.gemfile +6 -0
- data/gemfiles/rails-4.2.gemfile +10 -0
- data/gemfiles/rails-5.0.gemfile +5 -0
- data/gemfiles/rails-5.1.gemfile +5 -0
- data/gemfiles/resque.gemfile +12 -0
- data/gemfiles/sequel-435.gemfile +11 -0
- data/gemfiles/sequel.gemfile +11 -0
- data/gemfiles/sinatra.gemfile +6 -0
- data/gemfiles/webmachine.gemfile +5 -0
- data/lib/appsignal.rb +804 -0
- data/lib/appsignal/auth_check.rb +65 -0
- data/lib/appsignal/capistrano.rb +10 -0
- data/lib/appsignal/cli.rb +108 -0
- data/lib/appsignal/cli/demo.rb +63 -0
- data/lib/appsignal/cli/diagnose.rb +500 -0
- data/lib/appsignal/cli/helpers.rb +72 -0
- data/lib/appsignal/cli/install.rb +277 -0
- data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
- data/lib/appsignal/config.rb +287 -0
- data/lib/appsignal/demo.rb +107 -0
- data/lib/appsignal/event_formatter.rb +74 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
- data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
- data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
- data/lib/appsignal/extension.rb +63 -0
- data/lib/appsignal/extension/jruby.rb +460 -0
- data/lib/appsignal/garbage_collection_profiler.rb +48 -0
- data/lib/appsignal/hooks.rb +105 -0
- data/lib/appsignal/hooks/action_cable.rb +113 -0
- data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
- data/lib/appsignal/hooks/celluloid.rb +30 -0
- data/lib/appsignal/hooks/data_mapper.rb +18 -0
- data/lib/appsignal/hooks/delayed_job.rb +19 -0
- data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
- data/lib/appsignal/hooks/net_http.rb +29 -0
- data/lib/appsignal/hooks/passenger.rb +22 -0
- data/lib/appsignal/hooks/puma.rb +35 -0
- data/lib/appsignal/hooks/que.rb +21 -0
- data/lib/appsignal/hooks/rake.rb +39 -0
- data/lib/appsignal/hooks/redis.rb +30 -0
- data/lib/appsignal/hooks/sequel.rb +60 -0
- data/lib/appsignal/hooks/shoryuken.rb +43 -0
- data/lib/appsignal/hooks/sidekiq.rb +144 -0
- data/lib/appsignal/hooks/unicorn.rb +40 -0
- data/lib/appsignal/hooks/webmachine.rb +23 -0
- data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
- data/lib/appsignal/integrations/data_mapper.rb +33 -0
- data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
- data/lib/appsignal/integrations/grape.rb +53 -0
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
- data/lib/appsignal/integrations/object.rb +35 -0
- data/lib/appsignal/integrations/padrino.rb +84 -0
- data/lib/appsignal/integrations/que.rb +43 -0
- data/lib/appsignal/integrations/railtie.rb +41 -0
- data/lib/appsignal/integrations/rake.rb +2 -0
- data/lib/appsignal/integrations/resque.rb +20 -0
- data/lib/appsignal/integrations/resque_active_job.rb +30 -0
- data/lib/appsignal/integrations/sinatra.rb +17 -0
- data/lib/appsignal/integrations/webmachine.rb +38 -0
- data/lib/appsignal/js_exception_transaction.rb +54 -0
- data/lib/appsignal/marker.rb +63 -0
- data/lib/appsignal/minutely.rb +42 -0
- data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
- data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
- data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
- data/lib/appsignal/rack/streaming_listener.rb +73 -0
- data/lib/appsignal/system.rb +81 -0
- data/lib/appsignal/transaction.rb +498 -0
- data/lib/appsignal/transmitter.rb +107 -0
- data/lib/appsignal/utils.rb +127 -0
- data/lib/appsignal/utils/params_sanitizer.rb +59 -0
- data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
- data/lib/appsignal/version.rb +3 -0
- data/lib/sequel/extensions/appsignal_integration.rb +3 -0
- data/resources/appsignal.yml.erb +39 -0
- data/resources/cacert.pem +3866 -0
- data/spec/.rubocop.yml +7 -0
- data/spec/lib/appsignal/auth_check_spec.rb +80 -0
- data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
- data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
- data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
- data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
- data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
- data/spec/lib/appsignal/cli/install_spec.rb +632 -0
- data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
- data/spec/lib/appsignal/cli_spec.rb +56 -0
- data/spec/lib/appsignal/config_spec.rb +637 -0
- data/spec/lib/appsignal/demo_spec.rb +87 -0
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
- data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
- data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
- data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
- data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
- data/spec/lib/appsignal/extension_spec.rb +137 -0
- data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
- data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
- data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
- data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
- data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
- data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
- data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
- data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
- data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
- data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
- data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
- data/spec/lib/appsignal/hooks_spec.rb +195 -0
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
- data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
- data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
- data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
- data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
- data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
- data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
- data/spec/lib/appsignal/marker_spec.rb +51 -0
- data/spec/lib/appsignal/minutely_spec.rb +50 -0
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
- data/spec/lib/appsignal/system_spec.rb +131 -0
- data/spec/lib/appsignal/transaction_spec.rb +1146 -0
- data/spec/lib/appsignal/transmitter_spec.rb +152 -0
- data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
- data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
- data/spec/lib/appsignal/utils_spec.rb +150 -0
- data/spec/lib/appsignal_spec.rb +1049 -0
- data/spec/spec_helper.rb +116 -0
- data/spec/support/fixtures/containers/cgroups/docker +14 -0
- data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
- data/spec/support/fixtures/containers/cgroups/lxc +10 -0
- data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
- data/spec/support/fixtures/containers/cgroups/none +1 -0
- data/spec/support/fixtures/generated_config.yml +24 -0
- data/spec/support/fixtures/uploaded_file.txt +0 -0
- data/spec/support/helpers/api_request_helper.rb +19 -0
- data/spec/support/helpers/cli_helpers.rb +26 -0
- data/spec/support/helpers/config_helpers.rb +21 -0
- data/spec/support/helpers/dependency_helper.rb +73 -0
- data/spec/support/helpers/directory_helper.rb +27 -0
- data/spec/support/helpers/env_helpers.rb +33 -0
- data/spec/support/helpers/example_exception.rb +13 -0
- data/spec/support/helpers/example_standard_error.rb +13 -0
- data/spec/support/helpers/log_helpers.rb +22 -0
- data/spec/support/helpers/std_streams_helper.rb +66 -0
- data/spec/support/helpers/system_helpers.rb +8 -0
- data/spec/support/helpers/time_helpers.rb +11 -0
- data/spec/support/helpers/transaction_helpers.rb +37 -0
- data/spec/support/matchers/contains_log.rb +7 -0
- data/spec/support/mocks/fake_gc_profiler.rb +19 -0
- data/spec/support/mocks/mock_extension.rb +6 -0
- data/spec/support/project_fixture/config/application.rb +0 -0
- data/spec/support/project_fixture/config/appsignal.yml +32 -0
- data/spec/support/project_fixture/config/environments/development.rb +0 -0
- data/spec/support/project_fixture/config/environments/production.rb +0 -0
- data/spec/support/project_fixture/config/environments/test.rb +0 -0
- data/spec/support/project_fixture/log/.gitkeep +0 -0
- data/spec/support/rails/my_app.rb +6 -0
- data/spec/support/shared_examples/instrument.rb +43 -0
- data/spec/support/stubs/delayed_job.rb +0 -0
- metadata +483 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
require "appsignal/cli"
|
|
2
|
+
|
|
3
|
+
describe Appsignal::CLI::NotifyOfDeploy do
|
|
4
|
+
include CLIHelpers
|
|
5
|
+
|
|
6
|
+
let(:out_stream) { std_stream }
|
|
7
|
+
let(:output) { out_stream.read }
|
|
8
|
+
|
|
9
|
+
define :include_deploy_notification do
|
|
10
|
+
match do |log|
|
|
11
|
+
log.include?("Notifying AppSignal of deploy with: ") &&
|
|
12
|
+
log.include?("AppSignal has been notified of this deploy!")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
define :include_deploy_notification_with do |options|
|
|
16
|
+
match do |log|
|
|
17
|
+
return false unless options
|
|
18
|
+
values = "revision: #{options[:revision]}, user: #{options[:user]}"
|
|
19
|
+
log.include?("Notifying AppSignal of deploy with: #{values}") &&
|
|
20
|
+
log.include?("AppSignal has been notified of this deploy!")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
define :include_config_error do
|
|
24
|
+
match do |log|
|
|
25
|
+
log.include? "Error: No valid config found."
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
define :include_missing_options do |options|
|
|
29
|
+
match do |log|
|
|
30
|
+
log.include? "Error: Missing options: #{options.join(", ")}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def run
|
|
35
|
+
capture_stdout(out_stream) do
|
|
36
|
+
run_cli("notify_of_deploy", options)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "without config" do
|
|
41
|
+
let(:config) { Appsignal::Config.new(tmp_dir, "production") }
|
|
42
|
+
let(:options) { {} }
|
|
43
|
+
around do |example|
|
|
44
|
+
Dir.chdir tmp_dir do
|
|
45
|
+
example.run
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "prints a config error" do
|
|
50
|
+
expect { run }.to raise_error(SystemExit)
|
|
51
|
+
expect(output).to include_config_error
|
|
52
|
+
expect(output).to_not include_deploy_notification
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "with config" do
|
|
57
|
+
let(:config) { project_fixture_config }
|
|
58
|
+
before do
|
|
59
|
+
config[:name] = options[:name] if options[:name]
|
|
60
|
+
stub_api_request config, "markers", :revision => options[:revision],
|
|
61
|
+
:user => options[:user]
|
|
62
|
+
end
|
|
63
|
+
around do |example|
|
|
64
|
+
Dir.chdir project_fixture_path do
|
|
65
|
+
example.run
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "without environment" do
|
|
70
|
+
let(:options) { { :environment => "", :revision => "foo", :user => "thijs" } }
|
|
71
|
+
before do
|
|
72
|
+
# Makes the config "active"
|
|
73
|
+
ENV["APPSIGNAL_PUSH_API_KEY"] = "foo"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "requires environment option" do
|
|
77
|
+
expect { run }.to raise_error(SystemExit)
|
|
78
|
+
expect(output).to include_missing_options(%w[environment])
|
|
79
|
+
expect(output).to_not include_deploy_notification
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "without known environment" do
|
|
84
|
+
let(:options) { { :environment => "foo" } }
|
|
85
|
+
|
|
86
|
+
it "prints a config error" do
|
|
87
|
+
expect { run }.to raise_error(SystemExit)
|
|
88
|
+
expect(output).to include_config_error
|
|
89
|
+
expect(output).to_not include_missing_options([])
|
|
90
|
+
expect(output).to_not include_deploy_notification
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context "with known environment" do
|
|
95
|
+
context "without required options" do
|
|
96
|
+
let(:options) { { :environment => "production" } }
|
|
97
|
+
|
|
98
|
+
it "prints a missing required options error" do
|
|
99
|
+
expect { run }.to raise_error(SystemExit)
|
|
100
|
+
expect(output).to_not include_config_error
|
|
101
|
+
expect(output).to include_missing_options(%w[revision user])
|
|
102
|
+
expect(output).to_not include_deploy_notification
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context "with empty required option" do
|
|
106
|
+
let(:options) { { :environment => "production", :revision => "foo", :user => "" } }
|
|
107
|
+
|
|
108
|
+
it "prints a missing required option error" do
|
|
109
|
+
expect { run }.to raise_error(SystemExit)
|
|
110
|
+
expect(output).to_not include_config_error
|
|
111
|
+
expect(output).to include_missing_options(%w[user])
|
|
112
|
+
expect(output).to_not include_deploy_notification
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context "with required options" do
|
|
118
|
+
let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs" } }
|
|
119
|
+
|
|
120
|
+
it "notifies of a deploy" do
|
|
121
|
+
run
|
|
122
|
+
expect(output).to_not include_config_error
|
|
123
|
+
expect(output).to_not include_missing_options([])
|
|
124
|
+
expect(output).to include_deploy_notification_with(options)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context "with no app name configured" do
|
|
128
|
+
before { ENV["APPSIGNAL_APP_NAME"] = "" }
|
|
129
|
+
|
|
130
|
+
context "without name option" do
|
|
131
|
+
let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs" } }
|
|
132
|
+
|
|
133
|
+
it "requires name option" do
|
|
134
|
+
expect { run }.to raise_error(SystemExit)
|
|
135
|
+
expect(output).to_not include_config_error
|
|
136
|
+
expect(output).to include_missing_options(%w[name])
|
|
137
|
+
expect(output).to_not include_deploy_notification
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
context "with name option" do
|
|
142
|
+
let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs", :name => "foo" } }
|
|
143
|
+
|
|
144
|
+
it "notifies of a deploy with a custom name" do
|
|
145
|
+
run
|
|
146
|
+
expect(output).to_not include_config_error
|
|
147
|
+
expect(output).to_not include_missing_options([])
|
|
148
|
+
expect(output).to include_deploy_notification_with(options)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context "with name option" do
|
|
154
|
+
let(:options) do
|
|
155
|
+
{ :environment => "production", :revision => "aaaaa", :user => "thijs", :name => "foo" }
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "notifies of a deploy with a custom name" do
|
|
159
|
+
run
|
|
160
|
+
expect(output).to_not include_config_error
|
|
161
|
+
expect(output).to_not include_missing_options([])
|
|
162
|
+
expect(output).to include_deploy_notification_with(options)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require "appsignal/cli"
|
|
2
|
+
|
|
3
|
+
describe Appsignal::CLI do
|
|
4
|
+
let(:out_stream) { std_stream }
|
|
5
|
+
let(:output) { out_stream.read }
|
|
6
|
+
let(:cli) { Appsignal::CLI }
|
|
7
|
+
before { allow(Dir).to receive(:pwd).and_return(project_fixture_path) }
|
|
8
|
+
|
|
9
|
+
it "should print the help with no arguments, -h and --help" do
|
|
10
|
+
[nil, "-h", "--help"].each do |arg|
|
|
11
|
+
expect do
|
|
12
|
+
capture_stdout(out_stream) do
|
|
13
|
+
cli.run([arg].compact)
|
|
14
|
+
end
|
|
15
|
+
end.to raise_error(SystemExit)
|
|
16
|
+
|
|
17
|
+
expect(output).to include "appsignal <command> [options]"
|
|
18
|
+
expect(output).to include \
|
|
19
|
+
"Available commands: demo, diagnose, install, notify_of_deploy"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should print the version with -v and --version" do
|
|
24
|
+
["-v", "--version"].each do |arg|
|
|
25
|
+
expect do
|
|
26
|
+
capture_stdout(out_stream) do
|
|
27
|
+
cli.run([arg])
|
|
28
|
+
end
|
|
29
|
+
end.to raise_error(SystemExit)
|
|
30
|
+
|
|
31
|
+
expect(output).to include "AppSignal"
|
|
32
|
+
expect(output).to include "."
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should print a notice if a command does not exist" do
|
|
37
|
+
expect do
|
|
38
|
+
capture_stdout(out_stream) do
|
|
39
|
+
cli.run(["nonsense"])
|
|
40
|
+
end
|
|
41
|
+
end.to raise_error(SystemExit)
|
|
42
|
+
|
|
43
|
+
expect(output).to include "Command 'nonsense' does not exist, run "\
|
|
44
|
+
"appsignal -h to see the help"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "diagnose" do
|
|
48
|
+
it "should call Appsignal::Diagnose.install" do
|
|
49
|
+
expect(Appsignal::CLI::Diagnose).to receive(:run)
|
|
50
|
+
|
|
51
|
+
cli.run([
|
|
52
|
+
"diagnose"
|
|
53
|
+
])
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
describe Appsignal::Config do
|
|
2
|
+
describe "#initialize" do
|
|
3
|
+
subject { config.env }
|
|
4
|
+
|
|
5
|
+
describe "environment" do
|
|
6
|
+
context "when environment is nil" do
|
|
7
|
+
let(:config) { described_class.new("", "") }
|
|
8
|
+
|
|
9
|
+
it "sets an empty string" do
|
|
10
|
+
expect(subject).to eq("")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "when environment is given" do
|
|
15
|
+
let(:config) { described_class.new("", "my_env") }
|
|
16
|
+
|
|
17
|
+
it "sets the environment" do
|
|
18
|
+
expect(subject).to eq("my_env")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "with APPSIGNAL_APP_ENV environment variable" do
|
|
22
|
+
before { ENV["APPSIGNAL_APP_ENV"] = "my_env_env" }
|
|
23
|
+
|
|
24
|
+
it "uses the environment variable" do
|
|
25
|
+
expect(subject).to eq("my_env_env")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "config based on the system" do
|
|
33
|
+
let(:config) { project_fixture_config(:none) }
|
|
34
|
+
|
|
35
|
+
describe ":active" do
|
|
36
|
+
subject { config[:active] }
|
|
37
|
+
|
|
38
|
+
context "with APPSIGNAL_PUSH_API_KEY env variable" do
|
|
39
|
+
before { ENV["APPSIGNAL_PUSH_API_KEY"] = "abc" }
|
|
40
|
+
|
|
41
|
+
it "becomes active" do
|
|
42
|
+
expect(subject).to be_truthy
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "without APPSIGNAL_PUSH_API_KEY env variable" do
|
|
47
|
+
it "remains inactive" do
|
|
48
|
+
expect(subject).to be_falsy
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe ":log" do
|
|
54
|
+
subject { config[:log] }
|
|
55
|
+
|
|
56
|
+
context "when running on Heroku" do
|
|
57
|
+
around { |example| recognize_as_heroku { example.run } }
|
|
58
|
+
|
|
59
|
+
it "is set to stdout" do
|
|
60
|
+
expect(subject).to eq("stdout")
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "when not running on Heroku" do
|
|
65
|
+
it "is set to file" do
|
|
66
|
+
expect(subject).to eq("file")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe "initial config" do
|
|
73
|
+
let(:config) do
|
|
74
|
+
described_class.new(
|
|
75
|
+
"non-existing-path",
|
|
76
|
+
"production",
|
|
77
|
+
:push_api_key => "abc",
|
|
78
|
+
:name => "TestApp",
|
|
79
|
+
:active => true
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "merges with the default config" do
|
|
84
|
+
expect(config.config_hash).to eq(
|
|
85
|
+
:debug => false,
|
|
86
|
+
:log => "file",
|
|
87
|
+
:ignore_actions => [],
|
|
88
|
+
:ignore_errors => [],
|
|
89
|
+
:ignore_namespaces => [],
|
|
90
|
+
:filter_parameters => [],
|
|
91
|
+
:instrument_net_http => true,
|
|
92
|
+
:instrument_redis => true,
|
|
93
|
+
:instrument_sequel => true,
|
|
94
|
+
:skip_session_data => false,
|
|
95
|
+
:send_params => true,
|
|
96
|
+
:endpoint => "https://push.appsignal.com",
|
|
97
|
+
:push_api_key => "abc",
|
|
98
|
+
:name => "TestApp",
|
|
99
|
+
:active => true,
|
|
100
|
+
:enable_frontend_error_catching => false,
|
|
101
|
+
:frontend_error_catching_path => "/appsignal_error_catcher",
|
|
102
|
+
:enable_allocation_tracking => true,
|
|
103
|
+
:enable_gc_instrumentation => false,
|
|
104
|
+
:enable_host_metrics => true,
|
|
105
|
+
:enable_minutely_probes => false,
|
|
106
|
+
:hostname => Socket.gethostname,
|
|
107
|
+
:ca_file_path => File.join(resources_dir, "cacert.pem"),
|
|
108
|
+
:dns_servers => [],
|
|
109
|
+
:files_world_accessible => true
|
|
110
|
+
)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe "overriding system detected config" do
|
|
114
|
+
describe ":running_in_container" do
|
|
115
|
+
let(:config) do
|
|
116
|
+
described_class.new(
|
|
117
|
+
"non-existing-path",
|
|
118
|
+
"production",
|
|
119
|
+
:running_in_container => true
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
subject { config[:running_in_container] }
|
|
123
|
+
|
|
124
|
+
it "overrides system detected config" do
|
|
125
|
+
expect(subject).to be_truthy
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
describe ":active" do
|
|
130
|
+
subject { config[:active] }
|
|
131
|
+
|
|
132
|
+
context "with APPSIGNAL_PUSH_API_KEY env variable" do
|
|
133
|
+
let(:config) do
|
|
134
|
+
described_class.new(
|
|
135
|
+
"non-existing-path",
|
|
136
|
+
"production",
|
|
137
|
+
:active => false
|
|
138
|
+
)
|
|
139
|
+
end
|
|
140
|
+
before { ENV["APPSIGNAL_PUSH_API_KEY"] = "abc" }
|
|
141
|
+
|
|
142
|
+
it "sets given config rather than env variable" do
|
|
143
|
+
expect(subject).to be_falsy
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
context "when root path is nil" do
|
|
151
|
+
let(:config) { described_class.new(nil, "production") }
|
|
152
|
+
|
|
153
|
+
it "is not valid or active" do
|
|
154
|
+
expect(config.valid?).to be_falsy
|
|
155
|
+
expect(config.active?).to be_falsy
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
context "without config file" do
|
|
160
|
+
let(:config) { described_class.new(tmp_dir, "production") }
|
|
161
|
+
|
|
162
|
+
it "is not valid or active" do
|
|
163
|
+
expect(config.valid?).to be_falsy
|
|
164
|
+
expect(config.active?).to be_falsy
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
context "with a config file" do
|
|
169
|
+
let(:config) { project_fixture_config("production") }
|
|
170
|
+
|
|
171
|
+
it "is not valid or active" do
|
|
172
|
+
expect(config.valid?).to be_truthy
|
|
173
|
+
expect(config.active?).to be_truthy
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "does not log an error" do
|
|
177
|
+
expect_any_instance_of(Logger).to_not receive(:error)
|
|
178
|
+
config
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
describe "overriding system and defaults config" do
|
|
182
|
+
let(:config) do
|
|
183
|
+
described_class.new(
|
|
184
|
+
"non-existing-path",
|
|
185
|
+
"production",
|
|
186
|
+
:running_in_container => true,
|
|
187
|
+
:debug => true
|
|
188
|
+
)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "overrides system detected and defaults config" do
|
|
192
|
+
expect(config[:running_in_container]).to be_truthy
|
|
193
|
+
expect(config[:debug]).to be_truthy
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
context "with the env name as a symbol" do
|
|
198
|
+
let(:config) { project_fixture_config(:production) }
|
|
199
|
+
|
|
200
|
+
it "loads the config" do
|
|
201
|
+
expect(config.valid?).to be_truthy
|
|
202
|
+
expect(config.active?).to be_truthy
|
|
203
|
+
|
|
204
|
+
expect(config[:push_api_key]).to eq("abc")
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
context "without the selected env" do
|
|
209
|
+
let(:config) { project_fixture_config("nonsense") }
|
|
210
|
+
|
|
211
|
+
it "is not valid or active" do
|
|
212
|
+
expect(config.valid?).to be_falsy
|
|
213
|
+
expect(config.active?).to be_falsy
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it "logs an error" do
|
|
217
|
+
expect_any_instance_of(Logger).to receive(:error).once
|
|
218
|
+
.with("Not loading from config file: config for 'nonsense' not found")
|
|
219
|
+
expect_any_instance_of(Logger).to receive(:error).once
|
|
220
|
+
.with("Push api key not set after loading config")
|
|
221
|
+
config
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
describe "support for old config keys" do
|
|
226
|
+
let(:config) { project_fixture_config(env, {}, test_logger(log)) }
|
|
227
|
+
let(:log) { StringIO.new }
|
|
228
|
+
|
|
229
|
+
describe ":api_key" do
|
|
230
|
+
context "without :push_api_key" do
|
|
231
|
+
let(:env) { "old_config" }
|
|
232
|
+
|
|
233
|
+
it "sets the :push_api_key with the old :api_key value" do
|
|
234
|
+
expect(config[:push_api_key]).to eq "def"
|
|
235
|
+
expect(config.config_hash).to_not have_key :api_key
|
|
236
|
+
expect(log_contents(log)).to contains_log :warn,
|
|
237
|
+
"Old configuration key found. Please update the 'api_key' to 'push_api_key'"
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
context "with :push_api_key" do
|
|
242
|
+
let(:env) { "old_config_mixed_with_new_config" }
|
|
243
|
+
|
|
244
|
+
it "ignores the :api_key config and deletes it" do
|
|
245
|
+
expect(config[:push_api_key]).to eq "ghi"
|
|
246
|
+
expect(config.config_hash).to_not have_key :api_key
|
|
247
|
+
expect(log_contents(log)).to contains_log :warn,
|
|
248
|
+
"Old configuration key found. Please update the 'api_key' to 'push_api_key'"
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
describe ":ignore_exceptions" do
|
|
254
|
+
context "without :ignore_errors" do
|
|
255
|
+
let(:env) { "old_config" }
|
|
256
|
+
|
|
257
|
+
it "sets :ignore_errors with the old :ignore_exceptions value" do
|
|
258
|
+
expect(config[:ignore_errors]).to eq ["StandardError"]
|
|
259
|
+
expect(config.config_hash).to_not have_key :ignore_exceptions
|
|
260
|
+
expect(log_contents(log)).to contains_log :warn,
|
|
261
|
+
"Old configuration key found. Please update the 'ignore_exceptions' to 'ignore_errors'"
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
context "with :ignore_errors" do
|
|
266
|
+
let(:env) { "old_config_mixed_with_new_config" }
|
|
267
|
+
|
|
268
|
+
it "ignores the :ignore_exceptions config" do
|
|
269
|
+
expect(config[:ignore_errors]).to eq ["NoMethodError"]
|
|
270
|
+
expect(config.config_hash).to_not have_key :ignore_exceptions
|
|
271
|
+
expect(log_contents(log)).to contains_log :warn,
|
|
272
|
+
"Old configuration key found. Please update the 'ignore_exceptions' to 'ignore_errors'"
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
context "with config in the environment" do
|
|
280
|
+
let(:config) do
|
|
281
|
+
described_class.new(
|
|
282
|
+
"non-existing-path",
|
|
283
|
+
"production",
|
|
284
|
+
:running_in_container => true,
|
|
285
|
+
:debug => true
|
|
286
|
+
)
|
|
287
|
+
end
|
|
288
|
+
before do
|
|
289
|
+
ENV["APPSIGNAL_RUNNING_IN_CONTAINER"] = "true"
|
|
290
|
+
ENV["APPSIGNAL_PUSH_API_KEY"] = "aaa-bbb-ccc"
|
|
291
|
+
ENV["APPSIGNAL_ACTIVE"] = "true"
|
|
292
|
+
ENV["APPSIGNAL_APP_NAME"] = "App name"
|
|
293
|
+
ENV["APPSIGNAL_DEBUG"] = "true"
|
|
294
|
+
ENV["APPSIGNAL_IGNORE_ACTIONS"] = "action1,action2"
|
|
295
|
+
ENV["APPSIGNAL_IGNORE_ERRORS"] = "ExampleStandardError,AnotherError"
|
|
296
|
+
ENV["APPSIGNAL_IGNORE_NAMESPACES"] = "admin,private_namespace"
|
|
297
|
+
ENV["APPSIGNAL_INSTRUMENT_NET_HTTP"] = "false"
|
|
298
|
+
ENV["APPSIGNAL_INSTRUMENT_REDIS"] = "false"
|
|
299
|
+
ENV["APPSIGNAL_INSTRUMENT_SEQUEL"] = "false"
|
|
300
|
+
ENV["APPSIGNAL_FILES_WORLD_ACCESSIBLE"] = "false"
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it "overrides config with environment values" do
|
|
304
|
+
expect(config.valid?).to be_truthy
|
|
305
|
+
expect(config.active?).to be_truthy
|
|
306
|
+
|
|
307
|
+
expect(config[:running_in_container]).to be_truthy
|
|
308
|
+
expect(config[:push_api_key]).to eq "aaa-bbb-ccc"
|
|
309
|
+
expect(config[:active]).to eq(true)
|
|
310
|
+
expect(config[:name]).to eq "App name"
|
|
311
|
+
expect(config[:debug]).to eq(true)
|
|
312
|
+
expect(config[:ignore_actions]).to eq %w[action1 action2]
|
|
313
|
+
expect(config[:ignore_errors]).to eq %w[ExampleStandardError AnotherError]
|
|
314
|
+
expect(config[:ignore_namespaces]).to eq %w[admin private_namespace]
|
|
315
|
+
expect(config[:instrument_net_http]).to eq(false)
|
|
316
|
+
expect(config[:instrument_redis]).to eq(false)
|
|
317
|
+
expect(config[:instrument_sequel]).to eq(false)
|
|
318
|
+
expect(config[:files_world_accessible]).to eq(false)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
context "with mixed case `true` env variables values" do
|
|
322
|
+
before do
|
|
323
|
+
ENV["APPSIGNAL_DEBUG"] = "TRUE"
|
|
324
|
+
ENV["APPSIGNAL_INSTRUMENT_SEQUEL"] = "True"
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
it "accepts mixed case `true` values" do
|
|
328
|
+
expect(config[:debug]).to eq(true)
|
|
329
|
+
expect(config[:instrument_sequel]).to eq(true)
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
describe "config keys" do
|
|
335
|
+
describe ":endpoint" do
|
|
336
|
+
subject { config[:endpoint] }
|
|
337
|
+
|
|
338
|
+
context "with an pre-0.12-style endpoint" do
|
|
339
|
+
let(:config) do
|
|
340
|
+
project_fixture_config("production", :endpoint => "https://push.appsignal.com/1")
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
it "strips off the path" do
|
|
344
|
+
expect(subject).to eq "https://push.appsignal.com"
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
context "with a non-standard port" do
|
|
349
|
+
let(:config) { project_fixture_config("production", :endpoint => "http://localhost:4567") }
|
|
350
|
+
|
|
351
|
+
it "keeps the port" do
|
|
352
|
+
expect(subject).to eq "http://localhost:4567"
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
describe "#[]" do
|
|
359
|
+
let(:config) { project_fixture_config(:none, :push_api_key => "foo") }
|
|
360
|
+
|
|
361
|
+
context "with existing key" do
|
|
362
|
+
it "gets the value" do
|
|
363
|
+
expect(config[:push_api_key]).to eq "foo"
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
context "without existing key" do
|
|
368
|
+
it "returns nil" do
|
|
369
|
+
expect(config[:nonsense]).to be_nil
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
describe "#[]=" do
|
|
375
|
+
let(:config) { project_fixture_config(:none) }
|
|
376
|
+
|
|
377
|
+
context "with existing key" do
|
|
378
|
+
it "changes the value" do
|
|
379
|
+
expect(config[:push_api_key]).to be_nil
|
|
380
|
+
config[:push_api_key] = "abcde"
|
|
381
|
+
expect(config[:push_api_key]).to eq "abcde"
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
context "with new key" do
|
|
386
|
+
it "sets the value" do
|
|
387
|
+
expect(config[:foo]).to be_nil
|
|
388
|
+
config[:foo] = "bar"
|
|
389
|
+
expect(config[:foo]).to eq "bar"
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
describe "#write_to_environment" do
|
|
395
|
+
let(:config) { project_fixture_config(:production) }
|
|
396
|
+
before do
|
|
397
|
+
config[:http_proxy] = "http://localhost"
|
|
398
|
+
config[:ignore_actions] = %w[action1 action2]
|
|
399
|
+
config[:ignore_errors] = %w[ExampleStandardError AnotherError]
|
|
400
|
+
config[:ignore_namespaces] = %w[admin private_namespace]
|
|
401
|
+
config[:log] = "stdout"
|
|
402
|
+
config[:log_path] = "/tmp"
|
|
403
|
+
config[:hostname] = "app1.local"
|
|
404
|
+
config[:filter_parameters] = %w[password confirm_password]
|
|
405
|
+
config[:running_in_container] = false
|
|
406
|
+
config[:dns_servers] = ["8.8.8.8", "8.8.4.4"]
|
|
407
|
+
config.write_to_environment
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
it "writes the current config to environment variables" do
|
|
411
|
+
expect(ENV["_APPSIGNAL_ACTIVE"]).to eq "true"
|
|
412
|
+
expect(ENV["_APPSIGNAL_APP_PATH"]).to end_with("spec/support/project_fixture")
|
|
413
|
+
expect(ENV["_APPSIGNAL_AGENT_PATH"]).to end_with("/ext")
|
|
414
|
+
expect(ENV["_APPSIGNAL_DEBUG_LOGGING"]).to eq "false"
|
|
415
|
+
expect(ENV["_APPSIGNAL_LOG"]).to eq "stdout"
|
|
416
|
+
expect(ENV["_APPSIGNAL_LOG_FILE_PATH"]).to end_with("/tmp/appsignal.log")
|
|
417
|
+
expect(ENV["_APPSIGNAL_PUSH_API_ENDPOINT"]).to eq "https://push.appsignal.com"
|
|
418
|
+
expect(ENV["_APPSIGNAL_PUSH_API_KEY"]).to eq "abc"
|
|
419
|
+
expect(ENV["_APPSIGNAL_APP_NAME"]).to eq "TestApp"
|
|
420
|
+
expect(ENV["_APPSIGNAL_ENVIRONMENT"]).to eq "production"
|
|
421
|
+
expect(ENV["_APPSIGNAL_AGENT_VERSION"]).to eq Appsignal::Extension.agent_version
|
|
422
|
+
expect(ENV["_APPSIGNAL_LANGUAGE_INTEGRATION_VERSION"]).to eq "ruby-#{Appsignal::VERSION}"
|
|
423
|
+
expect(ENV["_APPSIGNAL_HTTP_PROXY"]).to eq "http://localhost"
|
|
424
|
+
expect(ENV["_APPSIGNAL_IGNORE_ACTIONS"]).to eq "action1,action2"
|
|
425
|
+
expect(ENV["_APPSIGNAL_IGNORE_ERRORS"]).to eq "ExampleStandardError,AnotherError"
|
|
426
|
+
expect(ENV["_APPSIGNAL_IGNORE_NAMESPACES"]).to eq "admin,private_namespace"
|
|
427
|
+
expect(ENV["_APPSIGNAL_FILTER_PARAMETERS"]).to eq "password,confirm_password"
|
|
428
|
+
expect(ENV["_APPSIGNAL_SEND_PARAMS"]).to eq "true"
|
|
429
|
+
expect(ENV["_APPSIGNAL_RUNNING_IN_CONTAINER"]).to eq "false"
|
|
430
|
+
expect(ENV["_APPSIGNAL_ENABLE_HOST_METRICS"]).to eq "true"
|
|
431
|
+
expect(ENV["_APPSIGNAL_ENABLE_MINUTELY_PROBES"]).to eq "false"
|
|
432
|
+
expect(ENV["_APPSIGNAL_HOSTNAME"]).to eq "app1.local"
|
|
433
|
+
expect(ENV["_APPSIGNAL_PROCESS_NAME"]).to include "rspec"
|
|
434
|
+
expect(ENV["_APPSIGNAL_CA_FILE_PATH"]).to eq File.join(resources_dir, "cacert.pem")
|
|
435
|
+
expect(ENV["_APPSIGNAL_DNS_SERVERS"]).to eq "8.8.8.8,8.8.4.4"
|
|
436
|
+
expect(ENV["_APPSIGNAL_FILES_WORLD_ACCESSIBLE"]).to eq "true"
|
|
437
|
+
expect(ENV).to_not have_key("_APPSIGNAL_WORKING_DIR_PATH")
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
context "with :working_dir_path" do
|
|
441
|
+
before do
|
|
442
|
+
config[:working_dir_path] = "/tmp/appsignal2"
|
|
443
|
+
config.write_to_environment
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
it "sets the modified :working_dir_path" do
|
|
447
|
+
expect(ENV["_APPSIGNAL_WORKING_DIR_PATH"]).to eq "/tmp/appsignal2"
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
describe "#log_file_path" do
|
|
453
|
+
let(:out_stream) { std_stream }
|
|
454
|
+
let(:output) { out_stream.read }
|
|
455
|
+
let(:config) { project_fixture_config("production", :log_path => log_path) }
|
|
456
|
+
subject { capture_stdout(out_stream) { config.log_file_path } }
|
|
457
|
+
|
|
458
|
+
context "when path is writable" do
|
|
459
|
+
let(:log_path) { File.join(tmp_dir, "writable-path") }
|
|
460
|
+
before { FileUtils.mkdir_p(log_path, :mode => 0o755) }
|
|
461
|
+
after { FileUtils.rm_rf(log_path) }
|
|
462
|
+
|
|
463
|
+
it "returns log file path" do
|
|
464
|
+
expect(subject).to eq File.join(log_path, "appsignal.log")
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
it "prints no warning" do
|
|
468
|
+
subject
|
|
469
|
+
expect(output).to be_empty
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
shared_examples "#log_file_path: tmp path" do
|
|
474
|
+
let(:system_tmp_dir) { described_class.system_tmp_dir }
|
|
475
|
+
before { FileUtils.mkdir_p(system_tmp_dir) }
|
|
476
|
+
after { FileUtils.rm_rf(system_tmp_dir) }
|
|
477
|
+
|
|
478
|
+
context "when the /tmp fallback path is writable" do
|
|
479
|
+
before { FileUtils.chmod(0o777, system_tmp_dir) }
|
|
480
|
+
|
|
481
|
+
it "returns returns the tmp location" do
|
|
482
|
+
expect(subject).to eq(File.join(system_tmp_dir, "appsignal.log"))
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
it "prints a warning" do
|
|
486
|
+
subject
|
|
487
|
+
expect(output).to include "appsignal: Unable to log to '#{log_path}'. "\
|
|
488
|
+
"Logging to '#{system_tmp_dir}' instead."
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
context "when the /tmp fallback path is not writable" do
|
|
493
|
+
before { FileUtils.chmod(0o555, system_tmp_dir) }
|
|
494
|
+
|
|
495
|
+
it "returns nil" do
|
|
496
|
+
expect(subject).to be_nil
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
it "prints a warning" do
|
|
500
|
+
subject
|
|
501
|
+
expect(output).to include "appsignal: Unable to log to '#{log_path}' "\
|
|
502
|
+
"or the '#{system_tmp_dir}' fallback."
|
|
503
|
+
end
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
context "when path is nil" do
|
|
508
|
+
let(:log_path) { nil }
|
|
509
|
+
|
|
510
|
+
context "when root_path is nil" do
|
|
511
|
+
before { allow(config).to receive(:root_path).and_return(nil) }
|
|
512
|
+
|
|
513
|
+
include_examples "#log_file_path: tmp path"
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
context "when root_path is set" do
|
|
517
|
+
it "returns returns the project log location" do
|
|
518
|
+
expect(subject).to eq File.join(config.root_path, "log/appsignal.log")
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
it "prints no warning" do
|
|
522
|
+
subject
|
|
523
|
+
expect(output).to be_empty
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
context "when path does not exist" do
|
|
529
|
+
let(:log_path) { "/non-existing" }
|
|
530
|
+
|
|
531
|
+
include_examples "#log_file_path: tmp path"
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
context "when path is not writable" do
|
|
535
|
+
let(:log_path) { File.join(tmp_dir, "not-writable-path") }
|
|
536
|
+
before { FileUtils.mkdir_p(log_path, :mode => 0o555) }
|
|
537
|
+
after { FileUtils.rm_rf(log_path) }
|
|
538
|
+
|
|
539
|
+
include_examples "#log_file_path: tmp path"
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
context "when path is a symlink" do
|
|
543
|
+
context "when linked path does not exist" do
|
|
544
|
+
let(:real_path) { File.join(tmp_dir, "real-path") }
|
|
545
|
+
let(:log_path) { File.join(tmp_dir, "symlink-path") }
|
|
546
|
+
before { File.symlink(real_path, log_path) }
|
|
547
|
+
after { FileUtils.rm(log_path) }
|
|
548
|
+
|
|
549
|
+
include_examples "#log_file_path: tmp path"
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
context "when linked path exists" do
|
|
553
|
+
context "when linked path is not writable" do
|
|
554
|
+
let(:real_path) { File.join(tmp_dir, "real-path") }
|
|
555
|
+
let(:log_path) { File.join(tmp_dir, "symlink-path") }
|
|
556
|
+
before do
|
|
557
|
+
FileUtils.mkdir_p(real_path)
|
|
558
|
+
FileUtils.chmod(0o444, real_path)
|
|
559
|
+
File.symlink(real_path, log_path)
|
|
560
|
+
end
|
|
561
|
+
after do
|
|
562
|
+
FileUtils.rm_rf(real_path)
|
|
563
|
+
FileUtils.rm(log_path)
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
include_examples "#log_file_path: tmp path"
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
context "when linked path is writable" do
|
|
570
|
+
let(:real_path) { File.join(tmp_dir, "real-path") }
|
|
571
|
+
let(:log_path) { File.join(tmp_dir, "symlink-path") }
|
|
572
|
+
before do
|
|
573
|
+
FileUtils.mkdir_p(real_path)
|
|
574
|
+
File.symlink(real_path, log_path)
|
|
575
|
+
end
|
|
576
|
+
after do
|
|
577
|
+
FileUtils.rm_rf(real_path)
|
|
578
|
+
FileUtils.rm(log_path)
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
it "returns real path of log path" do
|
|
582
|
+
expect(subject).to eq(File.join(real_path, "appsignal.log"))
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
describe ".system_tmp_dir" do
|
|
590
|
+
before do
|
|
591
|
+
# To counteract the stub in spec_helper
|
|
592
|
+
expect(Appsignal::Config).to receive(:system_tmp_dir).and_call_original
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
context "when on a *NIX OS" do
|
|
596
|
+
before do
|
|
597
|
+
expect(Gem).to receive(:win_platform?).and_return(false)
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
it "returns the system's tmp dir" do
|
|
601
|
+
expect(described_class.system_tmp_dir).to eq(File.realpath("/tmp"))
|
|
602
|
+
end
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
context "when on Microsoft Windows" do
|
|
606
|
+
before do
|
|
607
|
+
expect(Gem).to receive(:win_platform?).and_return(true)
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
it "returns the system's tmp dir" do
|
|
611
|
+
expect(described_class.system_tmp_dir).to eq(Dir.tmpdir)
|
|
612
|
+
end
|
|
613
|
+
end
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
describe "#validate" do
|
|
617
|
+
before { config.validate }
|
|
618
|
+
subject { config.valid? }
|
|
619
|
+
let(:config) { described_class.new(Dir.pwd, "production", :push_api_key => push_api_key) }
|
|
620
|
+
|
|
621
|
+
context "with missing push_api_key" do
|
|
622
|
+
let(:push_api_key) { nil }
|
|
623
|
+
|
|
624
|
+
it "sets valid to false" do
|
|
625
|
+
is_expected.to eq(false)
|
|
626
|
+
end
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
context "with push_api_key present" do
|
|
630
|
+
let(:push_api_key) { "abc" }
|
|
631
|
+
|
|
632
|
+
it "sets valid to true" do
|
|
633
|
+
is_expected.to eq(true)
|
|
634
|
+
end
|
|
635
|
+
end
|
|
636
|
+
end
|
|
637
|
+
end
|