appsignal 4.0.5 → 4.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/Rakefile +9 -9
- data/appsignal.gemspec +22 -1
- data/build_matrix.yml +2 -1
- data/ext/agent.rb +27 -27
- data/lib/appsignal/check_in/scheduler.rb +3 -4
- data/lib/appsignal/check_in.rb +1 -1
- data/lib/appsignal/config.rb +1 -3
- data/lib/appsignal/integrations/que.rb +8 -2
- data/lib/appsignal/integrations/resque.rb +1 -6
- data/lib/appsignal/utils/hash_sanitizer.rb +4 -0
- data/lib/appsignal/version.rb +1 -1
- metadata +2 -191
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
- data/.github/ISSUE_TEMPLATE/chore.md +0 -14
- data/.github/workflows/ci.yml +0 -3150
- data/.github/workflows/create_release_from_tag.yml +0 -62
- data/.gitignore +0 -35
- data/.gitmodules +0 -3
- data/.rspec +0 -4
- data/.yardopts +0 -8
- data/benchmark.rake +0 -139
- data/gemfiles/capistrano2.gemfile +0 -6
- data/gemfiles/capistrano3.gemfile +0 -7
- data/gemfiles/dry-monitor.gemfile +0 -5
- data/gemfiles/grape.gemfile +0 -5
- data/gemfiles/hanami-2.0.gemfile +0 -7
- data/gemfiles/hanami-2.1.gemfile +0 -7
- data/gemfiles/http5.gemfile +0 -5
- data/gemfiles/no_dependencies.gemfile +0 -10
- data/gemfiles/padrino.gemfile +0 -7
- data/gemfiles/psych-3.gemfile +0 -5
- data/gemfiles/psych-4.gemfile +0 -5
- data/gemfiles/que.gemfile +0 -5
- data/gemfiles/rails-6.0.gemfile +0 -10
- data/gemfiles/rails-6.1.gemfile +0 -11
- data/gemfiles/rails-7.0.gemfile +0 -11
- data/gemfiles/rails-7.1.gemfile +0 -11
- data/gemfiles/rails-7.2.gemfile +0 -11
- data/gemfiles/redis-4.gemfile +0 -5
- data/gemfiles/redis-5.gemfile +0 -6
- data/gemfiles/resque-2.gemfile +0 -6
- data/gemfiles/sequel.gemfile +0 -10
- data/gemfiles/sinatra.gemfile +0 -5
- data/gemfiles/webmachine1.gemfile +0 -7
- data/gemfiles/webmachine2.gemfile +0 -6
- data/mono.yml +0 -16
- data/spec/.rubocop.yml +0 -7
- data/spec/lib/appsignal/auth_check_spec.rb +0 -84
- data/spec/lib/appsignal/capistrano2_spec.rb +0 -227
- data/spec/lib/appsignal/capistrano3_spec.rb +0 -284
- data/spec/lib/appsignal/check_in/cron_spec.rb +0 -202
- data/spec/lib/appsignal/check_in/scheduler_spec.rb +0 -443
- data/spec/lib/appsignal/cli/demo_spec.rb +0 -46
- data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +0 -16
- data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +0 -86
- data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1553
- data/spec/lib/appsignal/cli/helpers_spec.rb +0 -179
- data/spec/lib/appsignal/cli/install_spec.rb +0 -848
- data/spec/lib/appsignal/cli_spec.rb +0 -56
- data/spec/lib/appsignal/config_spec.rb +0 -1380
- data/spec/lib/appsignal/demo_spec.rb +0 -83
- data/spec/lib/appsignal/environment_spec.rb +0 -190
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +0 -60
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +0 -21
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +0 -21
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +0 -52
- data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +0 -21
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -84
- data/spec/lib/appsignal/event_formatter/rom/sql_formatter_spec.rb +0 -22
- data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +0 -30
- data/spec/lib/appsignal/event_formatter/view_component/render_formatter_spec.rb +0 -41
- data/spec/lib/appsignal/event_formatter_spec.rb +0 -193
- data/spec/lib/appsignal/extension/jruby_spec.rb +0 -46
- data/spec/lib/appsignal/extension_install_failure_spec.rb +0 -20
- data/spec/lib/appsignal/extension_spec.rb +0 -178
- data/spec/lib/appsignal/garbage_collection_spec.rb +0 -98
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +0 -345
- data/spec/lib/appsignal/hooks/action_mailer_spec.rb +0 -55
- data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +0 -23
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +0 -99
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +0 -47
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +0 -47
- data/spec/lib/appsignal/hooks/activejob_spec.rb +0 -650
- data/spec/lib/appsignal/hooks/at_exit_spec.rb +0 -105
- data/spec/lib/appsignal/hooks/celluloid_spec.rb +0 -40
- data/spec/lib/appsignal/hooks/data_mapper_spec.rb +0 -40
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +0 -38
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +0 -83
- data/spec/lib/appsignal/hooks/excon_spec.rb +0 -67
- data/spec/lib/appsignal/hooks/gvl_spec.rb +0 -145
- data/spec/lib/appsignal/hooks/http_spec.rb +0 -37
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +0 -46
- data/spec/lib/appsignal/hooks/mri_spec.rb +0 -23
- data/spec/lib/appsignal/hooks/net_http_spec.rb +0 -18
- data/spec/lib/appsignal/hooks/passenger_spec.rb +0 -30
- data/spec/lib/appsignal/hooks/puma_spec.rb +0 -80
- data/spec/lib/appsignal/hooks/que_spec.rb +0 -19
- data/spec/lib/appsignal/hooks/rake_spec.rb +0 -144
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +0 -218
- data/spec/lib/appsignal/hooks/redis_spec.rb +0 -124
- data/spec/lib/appsignal/hooks/resque_spec.rb +0 -27
- data/spec/lib/appsignal/hooks/sequel_spec.rb +0 -44
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -29
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +0 -115
- data/spec/lib/appsignal/hooks/unicorn_spec.rb +0 -63
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +0 -24
- data/spec/lib/appsignal/hooks_spec.rb +0 -124
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +0 -74
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +0 -454
- data/spec/lib/appsignal/integrations/http_spec.rb +0 -111
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +0 -154
- data/spec/lib/appsignal/integrations/net_http_spec.rb +0 -33
- data/spec/lib/appsignal/integrations/object_spec.rb +0 -347
- data/spec/lib/appsignal/integrations/puma_spec.rb +0 -150
- data/spec/lib/appsignal/integrations/que_spec.rb +0 -152
- data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -457
- data/spec/lib/appsignal/integrations/resque_spec.rb +0 -155
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +0 -165
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +0 -640
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +0 -136
- data/spec/lib/appsignal/loaders/grape_spec.rb +0 -12
- data/spec/lib/appsignal/loaders/hanami_spec.rb +0 -92
- data/spec/lib/appsignal/loaders/padrino_spec.rb +0 -273
- data/spec/lib/appsignal/loaders/sinatra_spec.rb +0 -44
- data/spec/lib/appsignal/loaders_spec.rb +0 -144
- data/spec/lib/appsignal/logger_spec.rb +0 -205
- data/spec/lib/appsignal/marker_spec.rb +0 -51
- data/spec/lib/appsignal/probes/gvl_spec.rb +0 -164
- data/spec/lib/appsignal/probes/mri_spec.rb +0 -162
- data/spec/lib/appsignal/probes/sidekiq_spec.rb +0 -333
- data/spec/lib/appsignal/probes_spec.rb +0 -411
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +0 -370
- data/spec/lib/appsignal/rack/body_wrapper_spec.rb +0 -319
- data/spec/lib/appsignal/rack/event_handler_spec.rb +0 -441
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +0 -201
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +0 -36
- data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +0 -38
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +0 -126
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +0 -217
- data/spec/lib/appsignal/rack_spec.rb +0 -243
- data/spec/lib/appsignal/sample_data_spec.rb +0 -238
- data/spec/lib/appsignal/span_spec.rb +0 -141
- data/spec/lib/appsignal/system_spec.rb +0 -126
- data/spec/lib/appsignal/transaction_spec.rb +0 -2111
- data/spec/lib/appsignal/transmitter_spec.rb +0 -198
- data/spec/lib/appsignal/utils/data_spec.rb +0 -166
- data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +0 -182
- data/spec/lib/appsignal/utils/integration_logger_spec.rb +0 -21
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -153
- data/spec/lib/appsignal/utils/json_spec.rb +0 -44
- data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +0 -192
- data/spec/lib/appsignal_spec.rb +0 -1919
- data/spec/lib/puma/appsignal_spec.rb +0 -334
- data/spec/spec_helper.rb +0 -173
- data/spec/support/fixtures/generated_config.yml +0 -24
- data/spec/support/fixtures/projects/broken/config/appsignal.yml +0 -1
- data/spec/support/fixtures/projects/valid/config/appsignal.yml +0 -57
- data/spec/support/fixtures/projects/valid/log/.gitkeep +0 -0
- data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +0 -16
- data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +0 -56
- data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +0 -10
- data/spec/support/fixtures/projects/valid_with_rails_app/log/.gitkeep +0 -0
- data/spec/support/fixtures/uploaded_file.txt +0 -0
- data/spec/support/hanami/hanami_app.rb +0 -29
- data/spec/support/helpers/action_mailer_helpers.rb +0 -25
- data/spec/support/helpers/activejob_helpers.rb +0 -27
- data/spec/support/helpers/api_request_helper.rb +0 -20
- data/spec/support/helpers/cli_helpers.rb +0 -40
- data/spec/support/helpers/config_helpers.rb +0 -66
- data/spec/support/helpers/dependency_helper.rb +0 -150
- data/spec/support/helpers/directory_helper.rb +0 -27
- data/spec/support/helpers/env_helpers.rb +0 -41
- data/spec/support/helpers/environment_metdata_helper.rb +0 -16
- data/spec/support/helpers/example_exception.rb +0 -13
- data/spec/support/helpers/example_standard_error.rb +0 -13
- data/spec/support/helpers/loader_helper.rb +0 -21
- data/spec/support/helpers/log_helpers.rb +0 -36
- data/spec/support/helpers/rails_helper.rb +0 -28
- data/spec/support/helpers/std_streams_helper.rb +0 -94
- data/spec/support/helpers/system_helpers.rb +0 -8
- data/spec/support/helpers/take_at_most_helper.rb +0 -21
- data/spec/support/helpers/time_helpers.rb +0 -11
- data/spec/support/helpers/transaction_helpers.rb +0 -122
- data/spec/support/helpers/wait_for_helper.rb +0 -39
- data/spec/support/matchers/contains_log.rb +0 -26
- data/spec/support/matchers/have_colorized_text.rb +0 -28
- data/spec/support/matchers/transaction.rb +0 -200
- data/spec/support/mocks/appsignal_mock.rb +0 -18
- data/spec/support/mocks/dummy_app.rb +0 -20
- data/spec/support/mocks/fake_gc_profiler.rb +0 -19
- data/spec/support/mocks/fake_gvl_tools.rb +0 -28
- data/spec/support/mocks/hash_like.rb +0 -10
- data/spec/support/mocks/mock_probe.rb +0 -13
- data/spec/support/mocks/puma_mock.rb +0 -43
- data/spec/support/shared_examples/instrument.rb +0 -48
- data/spec/support/stubs/appsignal/loaders/loader_stub.rb +0 -7
- data/spec/support/stubs/delayed_job.rb +0 -0
- data/spec/support/stubs/sidekiq/api.rb +0 -4
- data/spec/support/testing.rb +0 -194
- data/support/bundler_wrapper +0 -12
- data/support/install_deps +0 -33
@@ -1,1553 +0,0 @@
|
|
1
|
-
require "bundler/cli"
|
2
|
-
require "bundler/cli/common"
|
3
|
-
require "appsignal/cli"
|
4
|
-
|
5
|
-
describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_input,
|
6
|
-
:color => false do
|
7
|
-
include CLIHelpers
|
8
|
-
|
9
|
-
class DiagnosticsReportEndpoint
|
10
|
-
class << self
|
11
|
-
attr_reader :received_report
|
12
|
-
|
13
|
-
def clear_report!
|
14
|
-
@received_report = nil
|
15
|
-
end
|
16
|
-
|
17
|
-
def call(env)
|
18
|
-
@received_report = JSON.parse(env["rack.input"].read)["diagnose"]
|
19
|
-
[200, {}, [JSON.generate(:token => "my_support_token")]]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe ".run" do
|
25
|
-
let(:out_stream) { std_stream }
|
26
|
-
let(:output) { out_stream.read }
|
27
|
-
let(:root_path) { project_fixture_path }
|
28
|
-
let(:app_name) { "TestApp" }
|
29
|
-
let(:push_api_key) { "abc" }
|
30
|
-
let(:environment) { "production" }
|
31
|
-
let(:config) do
|
32
|
-
{
|
33
|
-
:root_path => root_path,
|
34
|
-
:environment => environment.to_s,
|
35
|
-
:name => app_name,
|
36
|
-
:endpoint => Appsignal::Config::DEFAULT_CONFIG[:endpoint],
|
37
|
-
:push_api_key => push_api_key,
|
38
|
-
:hostname => nil
|
39
|
-
}
|
40
|
-
end
|
41
|
-
let(:cli_class) { described_class }
|
42
|
-
let(:options) { { :environment => environment } }
|
43
|
-
let(:gem_path) { Bundler::CLI::Common.select_spec("appsignal").full_gem_path.strip }
|
44
|
-
let(:received_report) { DiagnosticsReportEndpoint.received_report }
|
45
|
-
let(:process_user) { Etc.getpwuid(Process.uid).name }
|
46
|
-
let(:process_group) { Etc.getgrgid(Process.gid).name }
|
47
|
-
before(:context) { Appsignal.stop }
|
48
|
-
before do
|
49
|
-
# Clear previous reports
|
50
|
-
DiagnosticsReportEndpoint.clear_report!
|
51
|
-
if cli_class.instance_variable_defined? :@data
|
52
|
-
# Because this is saved on the class rather than an instance of the
|
53
|
-
# class we need to clear it like this in case a certain test doesn't
|
54
|
-
# generate a report.
|
55
|
-
cli_class.send :remove_instance_variable, :@data
|
56
|
-
end
|
57
|
-
|
58
|
-
if DependencyHelper.rails_present?
|
59
|
-
allow(Rails).to receive(:root).and_return(Pathname.new(config[:root_path]))
|
60
|
-
end
|
61
|
-
end
|
62
|
-
around do |example|
|
63
|
-
original_stdin = $stdin
|
64
|
-
$stdin = StringIO.new
|
65
|
-
example.run
|
66
|
-
$stdin = original_stdin
|
67
|
-
end
|
68
|
-
before { clear_integration_env_vars! }
|
69
|
-
before :api_stub => true do
|
70
|
-
stub_api_request config, "auth"
|
71
|
-
end
|
72
|
-
before(:color => false) { options["no-color"] = nil }
|
73
|
-
before(:color => true) { options["color"] = nil }
|
74
|
-
before(:send_report => :yes_cli_input) do
|
75
|
-
accept_prompt_to_send_diagnostics_report
|
76
|
-
capture_diagnatics_report_request
|
77
|
-
end
|
78
|
-
before(:send_report => :no_cli_input) { dont_accept_prompt_to_send_diagnostics_report }
|
79
|
-
before(:send_report => :yes_cli_option) do
|
80
|
-
options["send-report"] = nil
|
81
|
-
capture_diagnatics_report_request
|
82
|
-
end
|
83
|
-
before(:send_report => :no_cli_option) { options["no-send-report"] = nil }
|
84
|
-
|
85
|
-
def capture_diagnatics_report_request
|
86
|
-
stub_diagnostics_report_request.to_rack(DiagnosticsReportEndpoint)
|
87
|
-
end
|
88
|
-
|
89
|
-
def run
|
90
|
-
run_within_dir project_fixture_path
|
91
|
-
end
|
92
|
-
|
93
|
-
def run_within_dir(chdir)
|
94
|
-
prepare_cli_input
|
95
|
-
Dir.chdir chdir do
|
96
|
-
capture_stdout(out_stream) { run_cli("diagnose", options) }
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def stub_diagnostics_report_request
|
101
|
-
stub_request(:post, "https://appsignal.com/diag").with(
|
102
|
-
:query => {
|
103
|
-
:api_key => config[:push_api_key],
|
104
|
-
:environment => config[:environment],
|
105
|
-
:gem_version => Appsignal::VERSION,
|
106
|
-
:hostname => config[:hostname],
|
107
|
-
:name => config[:name]
|
108
|
-
},
|
109
|
-
:headers => { "Content-Type" => "application/json; charset=UTF-8" }
|
110
|
-
)
|
111
|
-
end
|
112
|
-
|
113
|
-
def accept_prompt_to_send_diagnostics_report
|
114
|
-
add_cli_input "y"
|
115
|
-
end
|
116
|
-
|
117
|
-
def dont_accept_prompt_to_send_diagnostics_report
|
118
|
-
add_cli_input "n"
|
119
|
-
end
|
120
|
-
|
121
|
-
it "outputs header and support text" do
|
122
|
-
run
|
123
|
-
expect(output).to include \
|
124
|
-
"AppSignal diagnose",
|
125
|
-
"https://docs.appsignal.com/",
|
126
|
-
"support@appsignal.com"
|
127
|
-
end
|
128
|
-
|
129
|
-
it "logs to the log file" do
|
130
|
-
run
|
131
|
-
log_contents = File.read(Appsignal.config.log_file_path)
|
132
|
-
expect(log_contents).to contains_log :info, "Starting AppSignal diagnose"
|
133
|
-
end
|
134
|
-
|
135
|
-
describe "report" do
|
136
|
-
context "when user wants to send report" do
|
137
|
-
it "sends report" do
|
138
|
-
run
|
139
|
-
expect(output).to include "Diagnostics report",
|
140
|
-
"Send diagnostics report to AppSignal? (Y/n): "
|
141
|
-
end
|
142
|
-
|
143
|
-
it "outputs the support token from the server" do
|
144
|
-
run
|
145
|
-
expect(output).to include "Your support token: my_support_token"
|
146
|
-
expect(output).to include "View this report: https://appsignal.com/diagnose/my_support_token"
|
147
|
-
end
|
148
|
-
|
149
|
-
context "when server response is invalid" do
|
150
|
-
before do
|
151
|
-
stub_diagnostics_report_request
|
152
|
-
.to_return(:status => 200, :body => %({ foo: "Invalid json", a: }))
|
153
|
-
run
|
154
|
-
end
|
155
|
-
|
156
|
-
it "outputs the server response in full" do
|
157
|
-
expect(output).to include "Error: Couldn't decode server response.",
|
158
|
-
%({ foo: "Invalid json", a: })
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
context "when server returns an error" do
|
163
|
-
before do
|
164
|
-
stub_diagnostics_report_request
|
165
|
-
.to_return(:status => 500, :body => "report: server error")
|
166
|
-
run
|
167
|
-
end
|
168
|
-
|
169
|
-
it "outputs the server response in full" do
|
170
|
-
expect(output).to include "report: server error"
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
context "when user uses the --send-report option", :send_report => :yes_cli_option do
|
176
|
-
it "sends the report without prompting" do
|
177
|
-
run
|
178
|
-
expect(output).to include "Diagnostics report",
|
179
|
-
"Confirmed sending report using --send-report option.",
|
180
|
-
"Transmitting diagnostics report"
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
context "when user uses the --no-send-report option", :send_report => :no_cli_option do
|
185
|
-
it "does not send the report" do
|
186
|
-
run
|
187
|
-
expect(output).to include "Diagnostics report",
|
188
|
-
"Not sending report. (Specified with the --no-send-report option.)",
|
189
|
-
"Not sending diagnostics information to AppSignal."
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
context "when user doesn't want to send report", :send_report => :no_cli_input do
|
194
|
-
it "does not send report" do
|
195
|
-
run
|
196
|
-
expect(output).to include "Diagnostics report",
|
197
|
-
"Send diagnostics report to AppSignal? (Y/n): ",
|
198
|
-
"Not sending diagnostics information to AppSignal."
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
describe "agent information" do
|
204
|
-
before { run }
|
205
|
-
|
206
|
-
it "outputs version numbers" do
|
207
|
-
expect(output).to include \
|
208
|
-
"Gem version: \"#{Appsignal::VERSION}\"",
|
209
|
-
"Agent version: \"#{Appsignal::Extension.agent_version}\""
|
210
|
-
end
|
211
|
-
|
212
|
-
it "transmits version numbers in report" do
|
213
|
-
expect(received_report).to include(
|
214
|
-
"library" => {
|
215
|
-
"language" => "ruby",
|
216
|
-
"package_version" => Appsignal::VERSION,
|
217
|
-
"agent_version" => Appsignal::Extension.agent_version,
|
218
|
-
"extension_loaded" => true
|
219
|
-
}
|
220
|
-
)
|
221
|
-
end
|
222
|
-
|
223
|
-
context "with extension" do
|
224
|
-
before { run }
|
225
|
-
|
226
|
-
it "outputs extension is loaded" do
|
227
|
-
expect(output).to include "Extension loaded: true"
|
228
|
-
end
|
229
|
-
|
230
|
-
it "transmits extension_loaded: true in report" do
|
231
|
-
expect(received_report["library"]["extension_loaded"]).to eq(true)
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
context "without extension" do
|
236
|
-
before do
|
237
|
-
# When the extension isn't loaded the Appsignal.start operation exits
|
238
|
-
# early and doesn't load the configuration.
|
239
|
-
# Happens when the extension wasn't installed properly.
|
240
|
-
Appsignal.extension_loaded = false
|
241
|
-
run
|
242
|
-
end
|
243
|
-
after { Appsignal.extension_loaded = true }
|
244
|
-
|
245
|
-
it "outputs extension is not loaded" do
|
246
|
-
expect(output).to include "Extension loaded: false"
|
247
|
-
expect(output).to include "Extension is not loaded. No agent report created."
|
248
|
-
end
|
249
|
-
|
250
|
-
context "with color", :color => true do
|
251
|
-
it "outputs extension is not loaded in color" do
|
252
|
-
expect(output).to have_colorized_text :red,
|
253
|
-
" Extension is not loaded. No agent report created."
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
it "transmits extension_loaded: false in report" do
|
258
|
-
expect(received_report["library"]["extension_loaded"]).to eq(false)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
describe "installation report" do
|
264
|
-
let(:rbconfig) { RbConfig::CONFIG }
|
265
|
-
|
266
|
-
it "adds the installation report to the diagnostics report" do
|
267
|
-
run
|
268
|
-
jruby = Appsignal::System.jruby?
|
269
|
-
language = {
|
270
|
-
"name" => "ruby",
|
271
|
-
"version" => "#{RUBY_VERSION}#{"-p#{rbconfig["PATCHLEVEL"]}" unless jruby}",
|
272
|
-
"implementation" => jruby ? "jruby" : "ruby"
|
273
|
-
}
|
274
|
-
language["implementation_version"] = JRUBY_VERSION if jruby
|
275
|
-
expect(received_report["installation"]).to match(
|
276
|
-
"result" => {
|
277
|
-
"status" => "success"
|
278
|
-
},
|
279
|
-
"language" => language,
|
280
|
-
"download" => {
|
281
|
-
"download_url" => kind_of(String),
|
282
|
-
"checksum" => "verified",
|
283
|
-
"http_proxy" => nil
|
284
|
-
},
|
285
|
-
"build" => {
|
286
|
-
"time" => kind_of(String),
|
287
|
-
"package_path" => File.expand_path("../../../..", __dir__),
|
288
|
-
"architecture" => Appsignal::System.agent_architecture,
|
289
|
-
"target" => Appsignal::System.agent_platform,
|
290
|
-
"musl_override" => false,
|
291
|
-
"linux_arm_override" => false,
|
292
|
-
"library_type" => jruby ? "dynamic" : "static",
|
293
|
-
"source" => "remote",
|
294
|
-
"dependencies" => kind_of(Hash),
|
295
|
-
"flags" => kind_of(Hash),
|
296
|
-
"agent_version" => Appsignal::Extension.agent_version
|
297
|
-
},
|
298
|
-
"host" => {
|
299
|
-
"root_user" => false,
|
300
|
-
"dependencies" => kind_of(Hash)
|
301
|
-
}
|
302
|
-
)
|
303
|
-
end
|
304
|
-
|
305
|
-
it "prints the extension installation report" do
|
306
|
-
run
|
307
|
-
jruby = Appsignal::System.jruby?
|
308
|
-
expect(output).to include(
|
309
|
-
"Extension installation report",
|
310
|
-
"Installation result",
|
311
|
-
" Status: success",
|
312
|
-
"Language details",
|
313
|
-
" Implementation: \"#{jruby ? "jruby" : "ruby"}\"",
|
314
|
-
" Ruby version: \"#{"#{rbconfig["RUBY_PROGRAM_VERSION"]}-p#{rbconfig["PATCHLEVEL"]}"}\"",
|
315
|
-
"Download details",
|
316
|
-
" Download URL: \"https://",
|
317
|
-
" Checksum: \"verified\"",
|
318
|
-
"Build details",
|
319
|
-
" Install time: \"20",
|
320
|
-
" Architecture: \"#{Appsignal::System.agent_architecture}\"",
|
321
|
-
" Target: \"#{Appsignal::System.agent_platform}\"",
|
322
|
-
" Musl override: false",
|
323
|
-
" Linux ARM override: false",
|
324
|
-
" Library type: \"#{jruby ? "dynamic" : "static"}\"",
|
325
|
-
" Dependencies: {",
|
326
|
-
" Flags: {",
|
327
|
-
"Host details",
|
328
|
-
" Root user: false",
|
329
|
-
" Dependencies: {"
|
330
|
-
)
|
331
|
-
end
|
332
|
-
|
333
|
-
context "with error in install report" do
|
334
|
-
let(:error) { RuntimeError.new("some error") }
|
335
|
-
before do
|
336
|
-
allow(File).to receive(:read).and_call_original
|
337
|
-
expect(File).to receive(:read)
|
338
|
-
.with(File.expand_path("../../../../ext/install.report", __dir__))
|
339
|
-
.and_return(
|
340
|
-
JSON.generate(
|
341
|
-
"result" => {
|
342
|
-
"status" => "error",
|
343
|
-
"error" => "RuntimeError: some error",
|
344
|
-
"backtrace" => error.backtrace
|
345
|
-
}
|
346
|
-
)
|
347
|
-
)
|
348
|
-
end
|
349
|
-
|
350
|
-
it "sends an error" do
|
351
|
-
run
|
352
|
-
expect(received_report["installation"]).to match(
|
353
|
-
"result" => {
|
354
|
-
"status" => "error",
|
355
|
-
"error" => "RuntimeError: some error",
|
356
|
-
"backtrace" => error.backtrace
|
357
|
-
}
|
358
|
-
)
|
359
|
-
end
|
360
|
-
|
361
|
-
it "prints the error" do
|
362
|
-
run
|
363
|
-
|
364
|
-
expect(output).to include(
|
365
|
-
"Extension installation report",
|
366
|
-
"Installation result",
|
367
|
-
"Status: error\n Error: RuntimeError: some error"
|
368
|
-
)
|
369
|
-
expect(output).to_not include("Raw report:")
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
context "without install report" do
|
374
|
-
let(:error) { RuntimeError.new("foo") }
|
375
|
-
before do
|
376
|
-
allow(File).to receive(:read).and_call_original
|
377
|
-
expect(File).to receive(:read)
|
378
|
-
.with(File.expand_path("../../../../ext/install.report", __dir__))
|
379
|
-
.and_raise(error)
|
380
|
-
end
|
381
|
-
|
382
|
-
it "sends an error" do
|
383
|
-
run
|
384
|
-
expect(received_report["installation"]).to match(
|
385
|
-
"parsing_error" => {
|
386
|
-
"error" => "RuntimeError: foo",
|
387
|
-
"backtrace" => error.backtrace
|
388
|
-
}
|
389
|
-
)
|
390
|
-
end
|
391
|
-
|
392
|
-
it "prints the error" do
|
393
|
-
run
|
394
|
-
expect(output).to include(
|
395
|
-
"Extension installation report",
|
396
|
-
" Error found while parsing the report.",
|
397
|
-
" Error: RuntimeError: foo"
|
398
|
-
)
|
399
|
-
expect(output).to_not include("Raw report:")
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
context "when report is invalid JSON" do
|
404
|
-
let(:raw_report) { "{}-" }
|
405
|
-
before do
|
406
|
-
allow(File).to receive(:read).and_call_original
|
407
|
-
expect(File).to receive(:read)
|
408
|
-
.with(File.expand_path("../../../../ext/install.report", __dir__))
|
409
|
-
.and_return(raw_report)
|
410
|
-
end
|
411
|
-
|
412
|
-
it "sends an error" do
|
413
|
-
run
|
414
|
-
expect(received_report["installation"]).to match(
|
415
|
-
"parsing_error" => {
|
416
|
-
"error" => kind_of(String),
|
417
|
-
"backtrace" => kind_of(Array),
|
418
|
-
"raw" => raw_report
|
419
|
-
}
|
420
|
-
)
|
421
|
-
end
|
422
|
-
|
423
|
-
it "prints the error" do
|
424
|
-
run
|
425
|
-
expect(output).to include(
|
426
|
-
"Extension installation report",
|
427
|
-
" Error found while parsing the report.",
|
428
|
-
" Error: ",
|
429
|
-
" Raw report:\n#{raw_report}"
|
430
|
-
)
|
431
|
-
end
|
432
|
-
end
|
433
|
-
end
|
434
|
-
|
435
|
-
describe "agent diagnostics" do
|
436
|
-
let(:working_directory_stat) { File.stat("/tmp/appsignal") }
|
437
|
-
|
438
|
-
it "starts the agent in diagnose mode and outputs the report" do
|
439
|
-
run
|
440
|
-
working_directory_stat = File.stat("/tmp/appsignal")
|
441
|
-
expect_valid_agent_diagnostics_report(output, working_directory_stat)
|
442
|
-
end
|
443
|
-
|
444
|
-
it "adds the agent diagnostics to the report" do
|
445
|
-
run
|
446
|
-
expect(received_report["agent"]).to eq(
|
447
|
-
"extension" => {
|
448
|
-
"config" => { "valid" => { "result" => true } }
|
449
|
-
},
|
450
|
-
"agent" => {
|
451
|
-
"boot" => { "started" => { "result" => true } },
|
452
|
-
"host" => {
|
453
|
-
"uid" => { "result" => Process.uid },
|
454
|
-
"gid" => { "result" => Process.gid },
|
455
|
-
"running_in_container" => { "result" => Appsignal::Extension.running_in_container? }
|
456
|
-
},
|
457
|
-
"config" => { "valid" => { "result" => true } },
|
458
|
-
"logger" => { "started" => { "result" => true } },
|
459
|
-
"working_directory_stat" => {
|
460
|
-
"uid" => { "result" => working_directory_stat.uid },
|
461
|
-
"gid" => { "result" => working_directory_stat.gid },
|
462
|
-
"mode" => { "result" => working_directory_stat.mode }
|
463
|
-
},
|
464
|
-
"lock_path" => { "created" => { "result" => true } }
|
465
|
-
}
|
466
|
-
)
|
467
|
-
end
|
468
|
-
|
469
|
-
context "when user config has active: false" do
|
470
|
-
before do
|
471
|
-
# ENV is leading so easiest to set in test to force user config with active: false
|
472
|
-
ENV["APPSIGNAL_ACTIVE"] = "false"
|
473
|
-
end
|
474
|
-
|
475
|
-
it "force starts the agent in diagnose mode and outputs a log" do
|
476
|
-
run
|
477
|
-
expect(output).to include("active: false")
|
478
|
-
expect_valid_agent_diagnostics_report(output, working_directory_stat)
|
479
|
-
end
|
480
|
-
end
|
481
|
-
|
482
|
-
context "when the extension returns invalid JSON" do
|
483
|
-
before do
|
484
|
-
expect(Appsignal::Extension).to receive(:diagnose).and_return("invalid agent\njson")
|
485
|
-
run
|
486
|
-
end
|
487
|
-
|
488
|
-
it "prints a JSON parse error and prints the returned value" do
|
489
|
-
expect(output).to include \
|
490
|
-
"Agent diagnostics",
|
491
|
-
" Error while parsing agent diagnostics report:",
|
492
|
-
" Output: invalid agent\njson"
|
493
|
-
expect(output).to match(/Error:( \d+:)? unexpected token at 'invalid agent\njson'/)
|
494
|
-
end
|
495
|
-
|
496
|
-
it "adds the output to the report" do
|
497
|
-
expect(received_report["agent"]["error"])
|
498
|
-
.to match(/unexpected token at 'invalid agent\njson'/)
|
499
|
-
expect(received_report["agent"]["output"]).to eq(["invalid agent", "json"])
|
500
|
-
end
|
501
|
-
end
|
502
|
-
|
503
|
-
context "when the extension is not loaded" do
|
504
|
-
before do
|
505
|
-
DiagnosticsReportEndpoint.clear_report!
|
506
|
-
expect(Appsignal).to receive(:extension_loaded?).and_return(false)
|
507
|
-
run
|
508
|
-
end
|
509
|
-
|
510
|
-
it "prints a warning" do
|
511
|
-
expect(output).to include \
|
512
|
-
"Agent diagnostics",
|
513
|
-
" Extension is not loaded. No agent report created."
|
514
|
-
end
|
515
|
-
|
516
|
-
it "adds the output to the report" do
|
517
|
-
expect(received_report["agent"]).to be_nil
|
518
|
-
end
|
519
|
-
end
|
520
|
-
|
521
|
-
context "when the report contains an error" do
|
522
|
-
let(:agent_report) do
|
523
|
-
{ "error" => "fatal error" }
|
524
|
-
end
|
525
|
-
before do
|
526
|
-
expect(Appsignal::Extension).to receive(:diagnose).and_return(JSON.generate(agent_report))
|
527
|
-
run
|
528
|
-
end
|
529
|
-
|
530
|
-
it "prints an error for the entire report" do
|
531
|
-
expect(output).to include "Agent diagnostics\n Error: fatal error"
|
532
|
-
end
|
533
|
-
|
534
|
-
it "adds the error to the report" do
|
535
|
-
expect(received_report["agent"]).to eq(agent_report)
|
536
|
-
end
|
537
|
-
end
|
538
|
-
|
539
|
-
context "when the report is incomplete (agent failed to start)" do
|
540
|
-
let(:agent_report) do
|
541
|
-
{
|
542
|
-
"extension" => {
|
543
|
-
"config" => { "valid" => { "result" => false } }
|
544
|
-
}
|
545
|
-
# missing agent section
|
546
|
-
}
|
547
|
-
end
|
548
|
-
before do
|
549
|
-
expect(Appsignal::Extension).to receive(:diagnose).and_return(JSON.generate(agent_report))
|
550
|
-
run
|
551
|
-
end
|
552
|
-
|
553
|
-
it "prints the tests, but shows a dash `-` for missed results" do
|
554
|
-
expect(output).to include \
|
555
|
-
"Agent diagnostics",
|
556
|
-
" Extension tests\n Configuration: invalid",
|
557
|
-
" Agent tests",
|
558
|
-
" Started: -",
|
559
|
-
" Configuration: -",
|
560
|
-
" Logger: -",
|
561
|
-
" Lock path: -"
|
562
|
-
end
|
563
|
-
|
564
|
-
it "adds the output to the report" do
|
565
|
-
expect(received_report["agent"]).to eq(agent_report)
|
566
|
-
end
|
567
|
-
end
|
568
|
-
|
569
|
-
context "when a test contains an error" do
|
570
|
-
let(:agent_report) do
|
571
|
-
{
|
572
|
-
"extension" => {
|
573
|
-
"config" => { "valid" => { "result" => true } }
|
574
|
-
},
|
575
|
-
"agent" => {
|
576
|
-
"boot" => {
|
577
|
-
"started" => { "result" => false, "error" => "some-error" }
|
578
|
-
}
|
579
|
-
}
|
580
|
-
}
|
581
|
-
end
|
582
|
-
before do
|
583
|
-
expect(Appsignal::Extension).to receive(:diagnose).and_return(JSON.generate(agent_report))
|
584
|
-
run
|
585
|
-
end
|
586
|
-
|
587
|
-
it "prints the error and output" do
|
588
|
-
expect(output).to include \
|
589
|
-
"Agent diagnostics",
|
590
|
-
" Extension tests\n Configuration: valid",
|
591
|
-
" Agent tests\n Started: not started\n Error: some-error"
|
592
|
-
end
|
593
|
-
|
594
|
-
it "adds the agent report to the diagnostics report" do
|
595
|
-
expect(received_report["agent"]).to eq(agent_report)
|
596
|
-
end
|
597
|
-
end
|
598
|
-
|
599
|
-
context "when a test contains command output" do
|
600
|
-
let(:agent_report) do
|
601
|
-
{
|
602
|
-
"extension" => {
|
603
|
-
"config" => { "valid" => { "result" => true } }
|
604
|
-
},
|
605
|
-
"agent" => {
|
606
|
-
"config" => { "valid" => { "result" => false, "output" => "some output" } }
|
607
|
-
}
|
608
|
-
}
|
609
|
-
end
|
610
|
-
|
611
|
-
it "prints the command output" do
|
612
|
-
expect(Appsignal::Extension).to receive(:diagnose).and_return(JSON.generate(agent_report))
|
613
|
-
run
|
614
|
-
expect(output).to include \
|
615
|
-
"Agent diagnostics",
|
616
|
-
" Extension tests\n Configuration: valid",
|
617
|
-
" Configuration: invalid\n Output: some output"
|
618
|
-
end
|
619
|
-
end
|
620
|
-
end
|
621
|
-
|
622
|
-
describe "host information" do
|
623
|
-
let(:rbconfig) { RbConfig::CONFIG }
|
624
|
-
let(:language_version) { "#{rbconfig["RUBY_PROGRAM_VERSION"]}-p#{rbconfig["PATCHLEVEL"]}" }
|
625
|
-
|
626
|
-
it "outputs host information" do
|
627
|
-
run
|
628
|
-
expect(output).to include \
|
629
|
-
"Host information",
|
630
|
-
"Architecture: \"#{rbconfig["host_cpu"]}\"",
|
631
|
-
"Operating System: \"#{rbconfig["host_os"]}\"",
|
632
|
-
"Ruby version: \"#{language_version}\""
|
633
|
-
end
|
634
|
-
|
635
|
-
context "when on Microsoft Windows" do
|
636
|
-
before do
|
637
|
-
expect(RbConfig::CONFIG).to receive(:[]).with("host_os").and_return("mingw32")
|
638
|
-
expect(RbConfig::CONFIG).to receive(:[]).at_least(:once).and_call_original
|
639
|
-
expect(Gem).to receive(:win_platform?).and_return(true)
|
640
|
-
run
|
641
|
-
end
|
642
|
-
|
643
|
-
it "adds the arch to the report" do
|
644
|
-
expect(received_report["host"]["os"]).to eq("mingw32")
|
645
|
-
end
|
646
|
-
|
647
|
-
it "prints warning that Microsoft Windows is not supported" do
|
648
|
-
expect(output).to match(/Operating System: .+ \(Microsoft Windows is not supported\.\)/)
|
649
|
-
end
|
650
|
-
end
|
651
|
-
|
652
|
-
it "transmits host information in report" do
|
653
|
-
run
|
654
|
-
host_report = received_report["host"]
|
655
|
-
host_report.delete("running_in_container") # Tested elsewhere
|
656
|
-
distribution_file = "/etc/os-release"
|
657
|
-
os_distribution = File.exist?(distribution_file) ? File.read(distribution_file) : ""
|
658
|
-
expect(host_report).to eq(
|
659
|
-
"architecture" => rbconfig["host_cpu"],
|
660
|
-
"os" => rbconfig["host_os"],
|
661
|
-
"os_distribution" => os_distribution,
|
662
|
-
"language_version" => language_version,
|
663
|
-
"heroku" => false,
|
664
|
-
"root" => false
|
665
|
-
)
|
666
|
-
end
|
667
|
-
|
668
|
-
describe "root user detection" do
|
669
|
-
context "when not root user" do
|
670
|
-
it "outputs false" do
|
671
|
-
run
|
672
|
-
expect(output).to include "Root user: false"
|
673
|
-
end
|
674
|
-
|
675
|
-
it "transmits root: false in report" do
|
676
|
-
run
|
677
|
-
expect(received_report["host"]["root"]).to eq(false)
|
678
|
-
end
|
679
|
-
end
|
680
|
-
|
681
|
-
context "when root user" do
|
682
|
-
before do
|
683
|
-
allow(Process).to receive(:uid).and_return(0)
|
684
|
-
run
|
685
|
-
end
|
686
|
-
|
687
|
-
it "outputs true, with warning" do
|
688
|
-
expect(output).to include "Root user: true (not recommended)"
|
689
|
-
end
|
690
|
-
|
691
|
-
it "transmits root: true in report" do
|
692
|
-
expect(received_report["host"]["root"]).to eq(true)
|
693
|
-
end
|
694
|
-
end
|
695
|
-
end
|
696
|
-
|
697
|
-
describe "Heroku detection" do
|
698
|
-
context "when not on Heroku" do
|
699
|
-
before { run }
|
700
|
-
|
701
|
-
it "does not output Heroku detection" do
|
702
|
-
expect(output).to_not include("Heroku:")
|
703
|
-
end
|
704
|
-
|
705
|
-
it "transmits heroku: false in report" do
|
706
|
-
expect(received_report["host"]["heroku"]).to eq(false)
|
707
|
-
end
|
708
|
-
end
|
709
|
-
|
710
|
-
context "when on Heroku" do
|
711
|
-
before { recognize_as_heroku { run } }
|
712
|
-
|
713
|
-
it "outputs Heroku detection" do
|
714
|
-
expect(output).to include("Heroku: true")
|
715
|
-
end
|
716
|
-
|
717
|
-
it "transmits heroku: true in report" do
|
718
|
-
expect(received_report["host"]["heroku"]).to eq(true)
|
719
|
-
end
|
720
|
-
end
|
721
|
-
end
|
722
|
-
|
723
|
-
describe "container detection" do
|
724
|
-
context "when not in container" do
|
725
|
-
before do
|
726
|
-
allow(Appsignal::Extension).to receive(:running_in_container?).and_return(false)
|
727
|
-
run
|
728
|
-
end
|
729
|
-
|
730
|
-
it "outputs: false" do
|
731
|
-
expect(output).to include("Running in container: false")
|
732
|
-
end
|
733
|
-
|
734
|
-
it "transmits running_in_container: false in report" do
|
735
|
-
expect(received_report["host"]["running_in_container"]).to eq(false)
|
736
|
-
end
|
737
|
-
end
|
738
|
-
|
739
|
-
context "when in container" do
|
740
|
-
before do
|
741
|
-
allow(Appsignal::Extension).to receive(:running_in_container?).and_return(true)
|
742
|
-
run
|
743
|
-
end
|
744
|
-
|
745
|
-
it "outputs: true" do
|
746
|
-
expect(output).to include("Running in container: true")
|
747
|
-
end
|
748
|
-
|
749
|
-
it "transmits running_in_container: true in report" do
|
750
|
-
expect(received_report["host"]["running_in_container"]).to eq(true)
|
751
|
-
end
|
752
|
-
end
|
753
|
-
end
|
754
|
-
end
|
755
|
-
|
756
|
-
describe "configuration" do
|
757
|
-
context "without environment" do
|
758
|
-
let(:app_name) { nil }
|
759
|
-
let(:environment) { nil }
|
760
|
-
let(:push_api_key) { nil }
|
761
|
-
let(:options) { {} }
|
762
|
-
let(:warning_message) do
|
763
|
-
" Warning: No environment set, no config loaded!\n" \
|
764
|
-
" Please make sure appsignal diagnose is run within your\n" \
|
765
|
-
" project directory with an environment.\n" \
|
766
|
-
" appsignal diagnose --environment=production"
|
767
|
-
end
|
768
|
-
before do
|
769
|
-
ENV.delete("RAILS_ENV") # From spec_helper
|
770
|
-
ENV.delete("RACK_ENV")
|
771
|
-
run_within_dir tmp_dir
|
772
|
-
end
|
773
|
-
|
774
|
-
it "outputs a warning that no config is loaded" do
|
775
|
-
expect(output).to include "environment: \"\"\n#{warning_message}"
|
776
|
-
expect(output).to_not have_color_markers
|
777
|
-
end
|
778
|
-
|
779
|
-
context "with color", :color => true do
|
780
|
-
it "outputs a warning that no config is loaded in color" do
|
781
|
-
expect(output).to include "environment: \"\"\n"
|
782
|
-
expect(output).to have_colorized_text :red, warning_message
|
783
|
-
end
|
784
|
-
end
|
785
|
-
|
786
|
-
it "outputs config defaults" do
|
787
|
-
expect(output).to include("Configuration")
|
788
|
-
expect_config_to_be_printed(Appsignal::Config::DEFAULT_CONFIG)
|
789
|
-
end
|
790
|
-
|
791
|
-
it "transmits validation in report" do
|
792
|
-
default_config = hash_with_string_keys(Appsignal::Config::DEFAULT_CONFIG)
|
793
|
-
expect(received_report["config"]).to eq(
|
794
|
-
"options" => default_config.merge("env" => "", "send_session_data" => true),
|
795
|
-
"sources" => {
|
796
|
-
"default" => default_config,
|
797
|
-
"system" => {},
|
798
|
-
"loaders" => {},
|
799
|
-
"initial" => { "env" => "" },
|
800
|
-
"file" => {},
|
801
|
-
"env" => {},
|
802
|
-
"override" => {},
|
803
|
-
"dsl" => {}
|
804
|
-
}
|
805
|
-
)
|
806
|
-
end
|
807
|
-
end
|
808
|
-
|
809
|
-
context "with configured environment" do
|
810
|
-
describe "environment" do
|
811
|
-
it "outputs environment" do
|
812
|
-
run
|
813
|
-
expect(output).to include(%(environment: "production"))
|
814
|
-
end
|
815
|
-
|
816
|
-
context "when the source is a single source" do
|
817
|
-
before { run }
|
818
|
-
|
819
|
-
it "outputs the label source after the value" do
|
820
|
-
expect(output).to include(
|
821
|
-
%(environment: "#{environment}" (Loaded from: initial)\n)
|
822
|
-
)
|
823
|
-
end
|
824
|
-
end
|
825
|
-
|
826
|
-
context "when the source is the RACK_ENV env variable", :send_report => :no_cli_option do
|
827
|
-
let(:environment) { "rack_env" }
|
828
|
-
let(:options) { {} }
|
829
|
-
before do
|
830
|
-
ENV["RACK_ENV"] = "rack_env"
|
831
|
-
run
|
832
|
-
end
|
833
|
-
after { ENV.delete("RACK_ENV") }
|
834
|
-
|
835
|
-
it "outputs the RACK_ENV variable value" do
|
836
|
-
expect(output).to include(
|
837
|
-
%(environment: "rack_env" (Loaded from: initial)\n)
|
838
|
-
)
|
839
|
-
end
|
840
|
-
end
|
841
|
-
|
842
|
-
context "when the source is the RAILS_ENV env variable", :send_report => :no_cli_option do
|
843
|
-
let(:environment) { "rails_env" }
|
844
|
-
let(:options) { {} }
|
845
|
-
before do
|
846
|
-
ENV["RAILS_ENV"] = "rails_env"
|
847
|
-
run
|
848
|
-
end
|
849
|
-
after { ENV.delete("RAILS_ENV") }
|
850
|
-
|
851
|
-
it "outputs the RAILS_ENV variable value" do
|
852
|
-
expect(output).to include(
|
853
|
-
%(environment: "rails_env" (Loaded from: initial)\n)
|
854
|
-
)
|
855
|
-
end
|
856
|
-
end
|
857
|
-
|
858
|
-
context "when the source is multiple sources" do
|
859
|
-
let(:options) { { :environment => "production" } }
|
860
|
-
before do
|
861
|
-
ENV["APPSIGNAL_APP_ENV"] = "development"
|
862
|
-
stub_api_request(config, "auth").to_return(:status => 200)
|
863
|
-
capture_diagnatics_report_request
|
864
|
-
run
|
865
|
-
end
|
866
|
-
|
867
|
-
it "outputs a list of sources with their values" do
|
868
|
-
expect(output).to include(
|
869
|
-
" environment: \"production\"\n" \
|
870
|
-
" Sources:\n" \
|
871
|
-
" initial: \"production\"\n" \
|
872
|
-
" env: \"development\"\n"
|
873
|
-
)
|
874
|
-
end
|
875
|
-
end
|
876
|
-
end
|
877
|
-
|
878
|
-
it "outputs configuration" do
|
879
|
-
run
|
880
|
-
expect(output).to include("Configuration")
|
881
|
-
expect_config_to_be_printed(Appsignal.config.config_hash)
|
882
|
-
end
|
883
|
-
|
884
|
-
describe "option sources" do
|
885
|
-
context "when the source is a single source" do
|
886
|
-
before { run }
|
887
|
-
|
888
|
-
it "outputs the label source after the value" do
|
889
|
-
expect(output).to include(
|
890
|
-
%(push_api_key: "#{Appsignal.config[:push_api_key]}" (Loaded from: file)\n)
|
891
|
-
)
|
892
|
-
end
|
893
|
-
|
894
|
-
context "when the source is only default" do
|
895
|
-
it "does not print a source" do
|
896
|
-
expect(output)
|
897
|
-
.to include("enable_host_metrics: #{Appsignal.config[:enable_host_metrics]}\n")
|
898
|
-
end
|
899
|
-
end
|
900
|
-
end
|
901
|
-
|
902
|
-
context "when the source is multiple sources" do
|
903
|
-
let(:app_name) { "MyApp" }
|
904
|
-
before do
|
905
|
-
ENV["APPSIGNAL_APP_NAME"] = app_name
|
906
|
-
run
|
907
|
-
end
|
908
|
-
|
909
|
-
it "outputs a list of sources with their values" do
|
910
|
-
expect(output).to include(
|
911
|
-
" name: \"MyApp\"\n" \
|
912
|
-
" Sources:\n" \
|
913
|
-
" file: \"TestApp\"\n" \
|
914
|
-
" env: \"MyApp\"\n"
|
915
|
-
)
|
916
|
-
end
|
917
|
-
end
|
918
|
-
|
919
|
-
if DependencyHelper.rails_present?
|
920
|
-
context "when is a Rails app" do
|
921
|
-
let(:root_path) { rails_project_fixture_path }
|
922
|
-
let(:app_name) { "TestApp" }
|
923
|
-
let(:environment) { "test" }
|
924
|
-
let(:options) { {} }
|
925
|
-
before do
|
926
|
-
# Workaround to not being able to require the railtie file
|
927
|
-
# multiple times and triggering the Rails initialization process.
|
928
|
-
# This will be used whtn the MyApp app has already been loaded.
|
929
|
-
Appsignal::Integrations::Railtie.load_default_config if defined?(MyApp)
|
930
|
-
run_within_dir(root_path)
|
931
|
-
end
|
932
|
-
|
933
|
-
it "includes the Rails default config in the output and transmitted report" do
|
934
|
-
expect(output).to include(
|
935
|
-
" name: \"TestApp\"\n" \
|
936
|
-
" Sources:\n" \
|
937
|
-
" loaders: \"MyApp\"\n" \
|
938
|
-
" file: \"TestApp\"\n"
|
939
|
-
)
|
940
|
-
# Outputs values from the DSL
|
941
|
-
expect(output).to include(
|
942
|
-
" ignore_actions: [\"Action from DSL\"]\n" \
|
943
|
-
" Sources:\n" \
|
944
|
-
" default: []\n" \
|
945
|
-
" dsl: [\"Action from DSL\"]\n"
|
946
|
-
)
|
947
|
-
|
948
|
-
expect(received_report["app"]["rails"]).to be(true)
|
949
|
-
expect(received_report["config"]["sources"]).to include(
|
950
|
-
"loaders" => {
|
951
|
-
"root_path" => root_path,
|
952
|
-
"env" => "test",
|
953
|
-
"log_path" => File.join(rails_project_fixture_path, "log"),
|
954
|
-
"name" => "MyApp"
|
955
|
-
}
|
956
|
-
)
|
957
|
-
# Includes values from the DSL
|
958
|
-
expect(received_report["config"]["sources"]).to include(
|
959
|
-
"dsl" => {
|
960
|
-
"ignore_actions" => ["Action from DSL"]
|
961
|
-
}
|
962
|
-
)
|
963
|
-
end
|
964
|
-
|
965
|
-
context "when there's a problem loading the app" do
|
966
|
-
before do
|
967
|
-
# A spot where we can mock an error raise
|
968
|
-
expect(Appsignal::Utils::RailsHelper).to receive(:environment_config_path)
|
969
|
-
.and_raise(ExampleStandardError, "error message", ["line 1", "line 2"])
|
970
|
-
run_within_dir(root_path)
|
971
|
-
end
|
972
|
-
|
973
|
-
it "includes a load error" do
|
974
|
-
expect(output).to include(
|
975
|
-
"ERROR: Error encountered while loading the Rails app\n" \
|
976
|
-
"ExampleStandardError: error message"
|
977
|
-
)
|
978
|
-
|
979
|
-
expect(received_report["app"]["load_error"])
|
980
|
-
.to eq("ExampleStandardError: error message\nline 1\nline 2")
|
981
|
-
end
|
982
|
-
end
|
983
|
-
end
|
984
|
-
end
|
985
|
-
end
|
986
|
-
|
987
|
-
it "transmits config in report" do
|
988
|
-
run
|
989
|
-
final_config = Appsignal.config.config_hash
|
990
|
-
.merge(:env => "production")
|
991
|
-
expect(received_report["config"]).to match(
|
992
|
-
"options" => hash_with_string_keys(final_config),
|
993
|
-
"sources" => {
|
994
|
-
"default" => hash_with_string_keys(Appsignal::Config::DEFAULT_CONFIG),
|
995
|
-
"system" => {},
|
996
|
-
"loaders" => {},
|
997
|
-
"initial" => hash_with_string_keys(Appsignal.config.initial_config),
|
998
|
-
"file" => hash_with_string_keys(Appsignal.config.file_config),
|
999
|
-
"env" => {},
|
1000
|
-
"override" => {},
|
1001
|
-
"dsl" => {}
|
1002
|
-
}
|
1003
|
-
)
|
1004
|
-
end
|
1005
|
-
end
|
1006
|
-
|
1007
|
-
context "with unconfigured environment" do
|
1008
|
-
let(:app_name) { nil }
|
1009
|
-
let(:push_api_key) { nil }
|
1010
|
-
let(:environment) { "foobar" }
|
1011
|
-
before { run_within_dir tmp_dir }
|
1012
|
-
|
1013
|
-
it "outputs environment" do
|
1014
|
-
expect(output).to include(%(environment: "foobar"))
|
1015
|
-
end
|
1016
|
-
|
1017
|
-
it "outputs config defaults" do
|
1018
|
-
expect(output).to include("Configuration")
|
1019
|
-
expect_config_to_be_printed(Appsignal::Config::DEFAULT_CONFIG)
|
1020
|
-
end
|
1021
|
-
|
1022
|
-
it "transmits config in report" do
|
1023
|
-
expect(received_report["config"]).to match(
|
1024
|
-
"options" => hash_with_string_keys(
|
1025
|
-
Appsignal.config.config_hash.merge("env" => "foobar")
|
1026
|
-
),
|
1027
|
-
"sources" => {
|
1028
|
-
"default" => hash_with_string_keys(Appsignal::Config::DEFAULT_CONFIG),
|
1029
|
-
"system" => {},
|
1030
|
-
"loaders" => {},
|
1031
|
-
"initial" => hash_with_string_keys(Appsignal.config.initial_config),
|
1032
|
-
"file" => hash_with_string_keys(Appsignal.config.file_config),
|
1033
|
-
"env" => {},
|
1034
|
-
"override" => {},
|
1035
|
-
"dsl" => {}
|
1036
|
-
}
|
1037
|
-
)
|
1038
|
-
end
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
def expect_config_to_be_printed(config)
|
1042
|
-
nil_options = config.select { |_, v| v.nil? }
|
1043
|
-
nil_options.each_key do |key|
|
1044
|
-
expect(output).to include(%(#{key}: nil))
|
1045
|
-
end
|
1046
|
-
string_options = config.select { |_, v| v.is_a?(String) }
|
1047
|
-
string_options.each do |key, value|
|
1048
|
-
expect(output).to include(%(#{key}: "#{value}"))
|
1049
|
-
end
|
1050
|
-
other_options = config.select do |k, _|
|
1051
|
-
!string_options.key?(k) && !nil_options.key?(k)
|
1052
|
-
end
|
1053
|
-
other_options.each do |key, value|
|
1054
|
-
expect(output).to include(%(#{key}: #{value}))
|
1055
|
-
end
|
1056
|
-
end
|
1057
|
-
end
|
1058
|
-
|
1059
|
-
describe "API key validation", :api_stub => false do
|
1060
|
-
context "with valid key" do
|
1061
|
-
before do
|
1062
|
-
stub_api_request(config, "auth").to_return(:status => 200)
|
1063
|
-
run
|
1064
|
-
end
|
1065
|
-
|
1066
|
-
it "outputs valid" do
|
1067
|
-
expect(output).to include "Validation",
|
1068
|
-
"Validating Push API key: valid"
|
1069
|
-
end
|
1070
|
-
|
1071
|
-
context "with color", :color => true do
|
1072
|
-
it "outputs valid in color" do
|
1073
|
-
expect(output).to include "Validation",
|
1074
|
-
"Validating Push API key: #{colorize("valid", :green)}"
|
1075
|
-
end
|
1076
|
-
end
|
1077
|
-
|
1078
|
-
it "transmits validation in report" do
|
1079
|
-
expect(received_report).to include(
|
1080
|
-
"validation" => {
|
1081
|
-
"push_api_key" => "valid"
|
1082
|
-
}
|
1083
|
-
)
|
1084
|
-
end
|
1085
|
-
end
|
1086
|
-
|
1087
|
-
context "with invalid key" do
|
1088
|
-
before do
|
1089
|
-
stub_api_request(config, "auth").to_return(:status => 401)
|
1090
|
-
run
|
1091
|
-
end
|
1092
|
-
|
1093
|
-
it "outputs invalid" do
|
1094
|
-
expect(output).to include "Validation",
|
1095
|
-
"Validating Push API key: invalid"
|
1096
|
-
end
|
1097
|
-
|
1098
|
-
context "with color", :color => true do
|
1099
|
-
it "outputs invalid in color" do
|
1100
|
-
expect(output).to include "Validation",
|
1101
|
-
"Validating Push API key: #{colorize("invalid", :red)}"
|
1102
|
-
end
|
1103
|
-
end
|
1104
|
-
|
1105
|
-
it "transmits validation in report" do
|
1106
|
-
expect(received_report).to include(
|
1107
|
-
"validation" => {
|
1108
|
-
"push_api_key" => "invalid"
|
1109
|
-
}
|
1110
|
-
)
|
1111
|
-
end
|
1112
|
-
end
|
1113
|
-
|
1114
|
-
context "with invalid key" do
|
1115
|
-
before do
|
1116
|
-
stub_api_request(config, "auth").to_return(:status => 500)
|
1117
|
-
run
|
1118
|
-
end
|
1119
|
-
|
1120
|
-
it "outputs failure with status code" do
|
1121
|
-
expect(output).to include "Validation",
|
1122
|
-
"Validating Push API key: Failed to validate: status 500\n" +
|
1123
|
-
%("Could not confirm authorization: 500")
|
1124
|
-
end
|
1125
|
-
|
1126
|
-
context "with color", :color => true do
|
1127
|
-
it "outputs error in color" do
|
1128
|
-
expect(output).to include "Validation",
|
1129
|
-
"Validating Push API key: #{colorize(
|
1130
|
-
%(Failed to validate: status 500\n"Could not confirm authorization: 500"),
|
1131
|
-
:red
|
1132
|
-
)}"
|
1133
|
-
end
|
1134
|
-
end
|
1135
|
-
|
1136
|
-
it "transmits validation in report" do
|
1137
|
-
expect(received_report).to include(
|
1138
|
-
"validation" => {
|
1139
|
-
"push_api_key" => "Failed to validate: status 500\n" +
|
1140
|
-
%("Could not confirm authorization: 500")
|
1141
|
-
}
|
1142
|
-
)
|
1143
|
-
end
|
1144
|
-
end
|
1145
|
-
end
|
1146
|
-
|
1147
|
-
describe "paths" do
|
1148
|
-
describe "report" do
|
1149
|
-
it "adds paths to the report" do
|
1150
|
-
run
|
1151
|
-
expect(received_report["paths"].keys).to match_array(
|
1152
|
-
%w[
|
1153
|
-
package_install_path root_path working_dir log_dir_path
|
1154
|
-
ext/mkmf.log appsignal.log
|
1155
|
-
]
|
1156
|
-
)
|
1157
|
-
end
|
1158
|
-
|
1159
|
-
describe "working_dir" do
|
1160
|
-
before { run }
|
1161
|
-
|
1162
|
-
it "outputs current path" do
|
1163
|
-
expect(output).to include %(Current working directory\n Path: "#{root_path}")
|
1164
|
-
end
|
1165
|
-
|
1166
|
-
it "transmits path data in report" do
|
1167
|
-
expect(received_report["paths"]["working_dir"]).to match(
|
1168
|
-
"path" => root_path,
|
1169
|
-
"exists" => true,
|
1170
|
-
"type" => "directory",
|
1171
|
-
"mode" => kind_of(String),
|
1172
|
-
"writable" => boolean,
|
1173
|
-
"ownership" => {
|
1174
|
-
"uid" => kind_of(Integer),
|
1175
|
-
"user" => kind_of(String),
|
1176
|
-
"gid" => kind_of(Integer),
|
1177
|
-
"group" => kind_of(String)
|
1178
|
-
}
|
1179
|
-
)
|
1180
|
-
end
|
1181
|
-
end
|
1182
|
-
|
1183
|
-
describe "root_path" do
|
1184
|
-
before { run }
|
1185
|
-
|
1186
|
-
it "outputs root path" do
|
1187
|
-
expect(output).to include %(Root path\n Path: "#{root_path}")
|
1188
|
-
end
|
1189
|
-
|
1190
|
-
it "transmits path data in report" do
|
1191
|
-
expect(received_report["paths"]["root_path"]).to match(
|
1192
|
-
"path" => root_path,
|
1193
|
-
"exists" => true,
|
1194
|
-
"type" => "directory",
|
1195
|
-
"mode" => kind_of(String),
|
1196
|
-
"writable" => boolean,
|
1197
|
-
"ownership" => {
|
1198
|
-
"uid" => kind_of(Integer),
|
1199
|
-
"user" => kind_of(String),
|
1200
|
-
"gid" => kind_of(Integer),
|
1201
|
-
"group" => kind_of(String)
|
1202
|
-
}
|
1203
|
-
)
|
1204
|
-
end
|
1205
|
-
end
|
1206
|
-
|
1207
|
-
describe "package_install_path" do
|
1208
|
-
before { run }
|
1209
|
-
|
1210
|
-
it "outputs gem install path" do
|
1211
|
-
expect(output).to match %(AppSignal gem path\n Path: "#{gem_path}")
|
1212
|
-
end
|
1213
|
-
|
1214
|
-
it "transmits path data in report" do
|
1215
|
-
expect(received_report["paths"]["package_install_path"]).to match(
|
1216
|
-
"path" => gem_path,
|
1217
|
-
"exists" => true,
|
1218
|
-
"type" => "directory",
|
1219
|
-
"mode" => kind_of(String),
|
1220
|
-
"writable" => boolean,
|
1221
|
-
"ownership" => {
|
1222
|
-
"uid" => kind_of(Integer),
|
1223
|
-
"user" => kind_of(String),
|
1224
|
-
"gid" => kind_of(Integer),
|
1225
|
-
"group" => kind_of(String)
|
1226
|
-
}
|
1227
|
-
)
|
1228
|
-
end
|
1229
|
-
end
|
1230
|
-
|
1231
|
-
describe "log_dir_path" do
|
1232
|
-
let(:log_path) { File.dirname(Appsignal.config.log_file_path) }
|
1233
|
-
before { run }
|
1234
|
-
|
1235
|
-
it "outputs log directory path" do
|
1236
|
-
expect(output).to match %(Log directory\n Path: "#{log_path}")
|
1237
|
-
end
|
1238
|
-
|
1239
|
-
it "transmits path data in report" do
|
1240
|
-
expect(received_report["paths"]["log_dir_path"]).to match(
|
1241
|
-
"path" => log_path,
|
1242
|
-
"exists" => true,
|
1243
|
-
"type" => "directory",
|
1244
|
-
"mode" => kind_of(String),
|
1245
|
-
"writable" => boolean,
|
1246
|
-
"ownership" => {
|
1247
|
-
"uid" => kind_of(Integer),
|
1248
|
-
"user" => kind_of(String),
|
1249
|
-
"gid" => kind_of(Integer),
|
1250
|
-
"group" => kind_of(String)
|
1251
|
-
}
|
1252
|
-
)
|
1253
|
-
end
|
1254
|
-
end
|
1255
|
-
end
|
1256
|
-
|
1257
|
-
context "when a directory does not exist" do
|
1258
|
-
let(:root_path) { tmp_dir }
|
1259
|
-
let(:environment) { nil }
|
1260
|
-
let(:push_api_key) { nil }
|
1261
|
-
let(:app_name) { nil }
|
1262
|
-
let(:options) { {} }
|
1263
|
-
let(:execution_path) { File.join(tmp_dir, "not_existing_dir") }
|
1264
|
-
before do
|
1265
|
-
allow(Dir).to receive(:pwd).and_return(execution_path)
|
1266
|
-
FileUtils.rm_rf(execution_path)
|
1267
|
-
run_within_dir root_path
|
1268
|
-
end
|
1269
|
-
|
1270
|
-
it "outputs not existing path" do
|
1271
|
-
expect(output).to include %(Root path\n Path: "#{execution_path}"\n Exists?: false)
|
1272
|
-
end
|
1273
|
-
|
1274
|
-
it "transmits path data in report" do
|
1275
|
-
expect(received_report["paths"]["root_path"]).to eq(
|
1276
|
-
"path" => execution_path,
|
1277
|
-
"exists" => false
|
1278
|
-
)
|
1279
|
-
end
|
1280
|
-
end
|
1281
|
-
|
1282
|
-
context "when not writable" do
|
1283
|
-
let(:root_path) { File.join(tmp_dir, "not_writable_path") }
|
1284
|
-
let(:environment) { nil }
|
1285
|
-
let(:push_api_key) { nil }
|
1286
|
-
let(:app_name) { nil }
|
1287
|
-
let(:options) { {} }
|
1288
|
-
before do
|
1289
|
-
FileUtils.mkdir_p(root_path)
|
1290
|
-
FileUtils.chmod(0o555, root_path)
|
1291
|
-
run_within_dir root_path
|
1292
|
-
end
|
1293
|
-
|
1294
|
-
it "outputs not writable root path" do
|
1295
|
-
expect(output).to include %(Root path\n Path: "#{root_path}"\n Writable?: false)
|
1296
|
-
end
|
1297
|
-
|
1298
|
-
it "transmits path data in report" do
|
1299
|
-
expect(received_report["paths"]["root_path"]).to eq(
|
1300
|
-
"path" => root_path,
|
1301
|
-
"exists" => true,
|
1302
|
-
"type" => "directory",
|
1303
|
-
"mode" => "40555",
|
1304
|
-
"writable" => false,
|
1305
|
-
"ownership" => {
|
1306
|
-
"uid" => Process.uid,
|
1307
|
-
"user" => process_user,
|
1308
|
-
"gid" => Process.gid,
|
1309
|
-
"group" => process_group
|
1310
|
-
}
|
1311
|
-
)
|
1312
|
-
end
|
1313
|
-
end
|
1314
|
-
|
1315
|
-
context "when writable" do
|
1316
|
-
let(:root_path) { File.join(tmp_dir, "writable_path") }
|
1317
|
-
let(:environment) { nil }
|
1318
|
-
let(:push_api_key) { nil }
|
1319
|
-
let(:app_name) { nil }
|
1320
|
-
let(:options) { {} }
|
1321
|
-
before do
|
1322
|
-
FileUtils.mkdir_p(root_path)
|
1323
|
-
FileUtils.chmod(0o755, root_path)
|
1324
|
-
run_within_dir root_path
|
1325
|
-
end
|
1326
|
-
|
1327
|
-
it "outputs writable root path" do
|
1328
|
-
expect(output).to include %(Root path\n Path: "#{root_path}"\n Writable?: true)
|
1329
|
-
end
|
1330
|
-
|
1331
|
-
it "transmits path data in report" do
|
1332
|
-
expect(received_report["paths"]["root_path"]).to eq(
|
1333
|
-
"path" => root_path,
|
1334
|
-
"exists" => true,
|
1335
|
-
"type" => "directory",
|
1336
|
-
"mode" => "40755",
|
1337
|
-
"writable" => true,
|
1338
|
-
"ownership" => {
|
1339
|
-
"uid" => Process.uid,
|
1340
|
-
"user" => process_user,
|
1341
|
-
"gid" => Process.gid,
|
1342
|
-
"group" => process_group
|
1343
|
-
}
|
1344
|
-
)
|
1345
|
-
end
|
1346
|
-
end
|
1347
|
-
|
1348
|
-
describe "ownership" do
|
1349
|
-
let(:environment) { nil }
|
1350
|
-
let(:push_api_key) { nil }
|
1351
|
-
let(:app_name) { nil }
|
1352
|
-
let(:options) { {} }
|
1353
|
-
before do
|
1354
|
-
FileUtils.mkdir_p(root_path)
|
1355
|
-
end
|
1356
|
-
|
1357
|
-
context "when a directory is owned by the current user" do
|
1358
|
-
let(:root_path) { File.join(tmp_dir, "owned_path") }
|
1359
|
-
before { run_within_dir root_path }
|
1360
|
-
|
1361
|
-
it "outputs ownership" do
|
1362
|
-
expect(output).to include \
|
1363
|
-
%(Root path\n Path: "#{root_path}"\n Writable?: true\n ) \
|
1364
|
-
"Ownership?: true (file: #{process_user}:#{Process.uid}, " \
|
1365
|
-
"process: #{process_user}:#{Process.uid})"
|
1366
|
-
end
|
1367
|
-
|
1368
|
-
it "transmits path data in report" do
|
1369
|
-
mode = "40755"
|
1370
|
-
expect(received_report["paths"]["root_path"]).to eq(
|
1371
|
-
"path" => root_path,
|
1372
|
-
"exists" => true,
|
1373
|
-
"type" => "directory",
|
1374
|
-
"mode" => mode,
|
1375
|
-
"writable" => true,
|
1376
|
-
"ownership" => {
|
1377
|
-
"uid" => Process.uid,
|
1378
|
-
"user" => process_user,
|
1379
|
-
"gid" => Process.gid,
|
1380
|
-
"group" => process_group
|
1381
|
-
}
|
1382
|
-
)
|
1383
|
-
end
|
1384
|
-
end
|
1385
|
-
|
1386
|
-
context "when a directory is not owned by the current user" do
|
1387
|
-
let(:root_path) { File.join(tmp_dir, "not_owned_path") }
|
1388
|
-
before do
|
1389
|
-
stat = File.stat(root_path)
|
1390
|
-
allow(stat).to receive(:uid).and_return(0)
|
1391
|
-
allow(File).to receive(:stat).and_return(stat)
|
1392
|
-
run_within_dir root_path
|
1393
|
-
end
|
1394
|
-
|
1395
|
-
it "outputs no ownership" do
|
1396
|
-
expect(output).to include \
|
1397
|
-
%(Root path\n Path: "#{root_path}"\n Writable?: true\n ) \
|
1398
|
-
"Ownership?: false (file: root:0, process: #{process_user}:#{Process.uid})"
|
1399
|
-
end
|
1400
|
-
end
|
1401
|
-
end
|
1402
|
-
end
|
1403
|
-
|
1404
|
-
describe "files" do
|
1405
|
-
shared_examples "diagnose file" do |shared_example_options|
|
1406
|
-
let(:parent_directory) { File.join(tmp_dir, "diagnose_files") }
|
1407
|
-
let(:file_path) { File.join(parent_directory, filename) }
|
1408
|
-
let(:path_key) { filename }
|
1409
|
-
before { FileUtils.mkdir_p File.dirname(file_path) }
|
1410
|
-
after { FileUtils.rm_rf parent_directory }
|
1411
|
-
|
1412
|
-
context "when file exists" do
|
1413
|
-
let(:contents) do
|
1414
|
-
[].tap do |lines|
|
1415
|
-
(1..12).each do |i|
|
1416
|
-
lines << "log line #{i}"
|
1417
|
-
end
|
1418
|
-
end
|
1419
|
-
end
|
1420
|
-
before do
|
1421
|
-
File.open file_path, "a" do |f|
|
1422
|
-
contents.each do |line|
|
1423
|
-
f.puts line
|
1424
|
-
end
|
1425
|
-
end
|
1426
|
-
run
|
1427
|
-
end
|
1428
|
-
|
1429
|
-
it "outputs file location and content" do
|
1430
|
-
expect(output).to include(
|
1431
|
-
%(Path: "#{file_path}"),
|
1432
|
-
"Contents (last 10 lines):"
|
1433
|
-
)
|
1434
|
-
expect(output).to include(*contents.last(10).join("\n"))
|
1435
|
-
expect(output).to_not include(*contents.first(2).join("\n"))
|
1436
|
-
end
|
1437
|
-
|
1438
|
-
it "transmits file data in report" do
|
1439
|
-
expect(received_report["paths"][path_key]).to match(
|
1440
|
-
"path" => file_path,
|
1441
|
-
"exists" => true,
|
1442
|
-
"type" => "file",
|
1443
|
-
"mode" => kind_of(String),
|
1444
|
-
"writable" => boolean,
|
1445
|
-
"ownership" => {
|
1446
|
-
"uid" => kind_of(Integer),
|
1447
|
-
"user" => kind_of(String),
|
1448
|
-
"gid" => kind_of(Integer),
|
1449
|
-
"group" => kind_of(String)
|
1450
|
-
},
|
1451
|
-
"content" => contents
|
1452
|
-
)
|
1453
|
-
end
|
1454
|
-
end
|
1455
|
-
|
1456
|
-
context "when file does not exist" do
|
1457
|
-
before do
|
1458
|
-
if shared_example_options && shared_example_options[:stub_not_exists]
|
1459
|
-
allow(File).to receive(:exist?).and_call_original
|
1460
|
-
expect(File).to receive(:exist?).with(file_path).and_return(false)
|
1461
|
-
end
|
1462
|
-
run
|
1463
|
-
end
|
1464
|
-
|
1465
|
-
it "outputs file does not exists" do
|
1466
|
-
expect(output).to include %(Path: "#{file_path}"\n Exists?: false)
|
1467
|
-
end
|
1468
|
-
|
1469
|
-
it "transmits file data in report" do
|
1470
|
-
expect(received_report["paths"][path_key]).to eq(
|
1471
|
-
"path" => file_path,
|
1472
|
-
"exists" => false
|
1473
|
-
)
|
1474
|
-
end
|
1475
|
-
end
|
1476
|
-
|
1477
|
-
context "when reading the file returns a illegal seek error" do
|
1478
|
-
before do
|
1479
|
-
File.write(file_path, "Some content")
|
1480
|
-
allow(File).to receive(:binread).and_call_original
|
1481
|
-
expect(File).to receive(:binread).with(file_path, anything,
|
1482
|
-
anything).and_raise(Errno::ESPIPE)
|
1483
|
-
run
|
1484
|
-
end
|
1485
|
-
|
1486
|
-
it "outputs file does not exists" do
|
1487
|
-
expect(output).to include %(Read error: Errno::ESPIPE: Illegal seek)
|
1488
|
-
end
|
1489
|
-
|
1490
|
-
it "transmits file data in report" do
|
1491
|
-
expect(received_report["paths"][path_key]).to include(
|
1492
|
-
"read_error" => "Errno::ESPIPE: Illegal seek"
|
1493
|
-
)
|
1494
|
-
end
|
1495
|
-
end
|
1496
|
-
end
|
1497
|
-
|
1498
|
-
describe "ext/mkmf.log" do
|
1499
|
-
it_behaves_like "diagnose file" do
|
1500
|
-
let(:filename) { "mkmf.log" }
|
1501
|
-
let(:path_key) { "ext/mkmf.log" }
|
1502
|
-
before do
|
1503
|
-
expect_any_instance_of(Appsignal::CLI::Diagnose::Paths)
|
1504
|
-
.to receive(:makefile_install_log_path)
|
1505
|
-
.at_least(:once)
|
1506
|
-
.and_return(File.join(parent_directory, filename))
|
1507
|
-
end
|
1508
|
-
end
|
1509
|
-
|
1510
|
-
it "outputs header" do
|
1511
|
-
run
|
1512
|
-
expect(output).to include("Makefile install log")
|
1513
|
-
end
|
1514
|
-
end
|
1515
|
-
|
1516
|
-
describe "appsignal.log" do
|
1517
|
-
it_behaves_like "diagnose file", :stub_not_exists => true do
|
1518
|
-
let(:filename) { "appsignal.log" }
|
1519
|
-
before do
|
1520
|
-
ENV["APPSIGNAL_LOG"] = "stdout"
|
1521
|
-
expect_any_instance_of(Appsignal::Config).to receive(:log_file_path)
|
1522
|
-
.at_least(:once)
|
1523
|
-
.and_return(file_path)
|
1524
|
-
end
|
1525
|
-
end
|
1526
|
-
|
1527
|
-
it "outputs header" do
|
1528
|
-
run
|
1529
|
-
expect(output).to include("AppSignal log")
|
1530
|
-
end
|
1531
|
-
end
|
1532
|
-
end
|
1533
|
-
end
|
1534
|
-
|
1535
|
-
def expect_valid_agent_diagnostics_report(output, working_directory_stat)
|
1536
|
-
expect(output).to include \
|
1537
|
-
"Agent diagnostics",
|
1538
|
-
" Extension tests\n Configuration: valid",
|
1539
|
-
" Started: started",
|
1540
|
-
" Process user id: #{Process.uid}",
|
1541
|
-
" Process user group id: #{Process.gid}\n" \
|
1542
|
-
" Configuration: valid",
|
1543
|
-
" Logger: started",
|
1544
|
-
" Working directory user id: #{working_directory_stat.uid}",
|
1545
|
-
" Working directory user group id: #{working_directory_stat.gid}",
|
1546
|
-
" Working directory permissions: #{working_directory_stat.mode}",
|
1547
|
-
" Lock path: writable"
|
1548
|
-
end
|
1549
|
-
|
1550
|
-
def hash_with_string_keys(hash)
|
1551
|
-
hash.transform_keys(&:to_s)
|
1552
|
-
end
|
1553
|
-
end
|