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,848 +0,0 @@
|
|
1
|
-
require "appsignal/cli"
|
2
|
-
|
3
|
-
describe Appsignal::CLI::Install do
|
4
|
-
include CLIHelpers
|
5
|
-
|
6
|
-
let(:out_stream) { std_stream }
|
7
|
-
let(:output) { out_stream.read }
|
8
|
-
let(:push_api_key) { "my_key" }
|
9
|
-
let(:config) { Appsignal::Config.new(tmp_dir, "") }
|
10
|
-
let(:config_file_path) { File.join(tmp_dir, "config", "appsignal.yml") }
|
11
|
-
let(:config_file) { File.read(config_file_path) }
|
12
|
-
let(:options) { {} }
|
13
|
-
before do
|
14
|
-
stub_api_validation_request
|
15
|
-
# Stub calls to speed up tests
|
16
|
-
allow(described_class).to receive(:sleep)
|
17
|
-
allow(described_class).to receive(:press_any_key)
|
18
|
-
allow(Appsignal::Demo).to receive(:transmit).and_return(true)
|
19
|
-
end
|
20
|
-
after do
|
21
|
-
FileUtils.rm_rf(tmp_dir)
|
22
|
-
FileUtils.mkdir_p(tmp_dir)
|
23
|
-
end
|
24
|
-
around do |example|
|
25
|
-
original_stdin = $stdin
|
26
|
-
$stdin = StringIO.new
|
27
|
-
example.run
|
28
|
-
$stdin = original_stdin
|
29
|
-
end
|
30
|
-
|
31
|
-
define :include_complete_install do
|
32
|
-
match do |actual|
|
33
|
-
actual.include?("Please return to your browser and follow the instructions.")
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
define :include_env_push_api_key do |key|
|
38
|
-
match do |actual|
|
39
|
-
actual.include?("export APPSIGNAL_PUSH_API_KEY=#{key}")
|
40
|
-
end
|
41
|
-
end
|
42
|
-
define :include_env_app_name do |name|
|
43
|
-
match do |actual|
|
44
|
-
actual.include?("export APPSIGNAL_APP_NAME=#{name}")
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
define :configure_app_name do |name|
|
49
|
-
match do |file_contents|
|
50
|
-
file_contents =~ /^ name: "#{name}"/
|
51
|
-
end
|
52
|
-
end
|
53
|
-
define :configure_push_api_key do |key|
|
54
|
-
match do |file_contents|
|
55
|
-
file_contents =~ /^ push_api_key: "#{key}"/
|
56
|
-
end
|
57
|
-
end
|
58
|
-
define :configure_environment do |env|
|
59
|
-
match do |file_contents|
|
60
|
-
file_contents =~ /^#{env}:$/
|
61
|
-
end
|
62
|
-
end
|
63
|
-
define :include_file_config do
|
64
|
-
match do |log|
|
65
|
-
log.include?("Config file written to config/appsignal.yml")
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
define :include_demo_transmission do
|
70
|
-
match do |log|
|
71
|
-
log.include?("Sending example data to AppSignal") &&
|
72
|
-
log.include?("Example data sent!")
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def stub_api_validation_request
|
77
|
-
config[:push_api_key] = push_api_key
|
78
|
-
stub_api_request config, "auth"
|
79
|
-
end
|
80
|
-
|
81
|
-
alias_method :enter_app_name, :add_cli_input
|
82
|
-
|
83
|
-
def choose_config_file
|
84
|
-
add_cli_input "1"
|
85
|
-
end
|
86
|
-
|
87
|
-
def choose_environment_config
|
88
|
-
add_cli_input "2"
|
89
|
-
end
|
90
|
-
|
91
|
-
def run
|
92
|
-
Dir.chdir tmp_dir do
|
93
|
-
prepare_cli_input
|
94
|
-
capture_stdout(out_stream) do
|
95
|
-
run_cli(["install", push_api_key], options)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
shared_examples "push_api_key validation" do
|
101
|
-
context "without key" do
|
102
|
-
let(:push_api_key) { nil }
|
103
|
-
|
104
|
-
it "does not install" do
|
105
|
-
run
|
106
|
-
|
107
|
-
expect(output).to include "Problem encountered:",
|
108
|
-
"No Push API key entered"
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context "with key" do
|
113
|
-
let(:push_api_key) { "my_key" }
|
114
|
-
|
115
|
-
context "when the key is valid" do
|
116
|
-
before { stub_api_validation_request.to_return(:status => 200) }
|
117
|
-
|
118
|
-
it "continues with the installer" do
|
119
|
-
enter_app_name "Test App"
|
120
|
-
choose_environment_config
|
121
|
-
run
|
122
|
-
|
123
|
-
expect(output).to include("Validating Push API key...", "Push API key valid")
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
context "when the key is invalid" do
|
128
|
-
before { stub_api_validation_request.to_return(:status => 402) }
|
129
|
-
|
130
|
-
it "prints an error" do
|
131
|
-
run
|
132
|
-
expect(output).to include "Push API key 'my_key' is not valid"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
context "when there is an error validating" do
|
137
|
-
before do
|
138
|
-
expect(Appsignal::AuthCheck).to receive(:new).and_raise(StandardError)
|
139
|
-
end
|
140
|
-
|
141
|
-
it "prints an error" do
|
142
|
-
run
|
143
|
-
expect(output).to include "There was an error validating your Push API key"
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
shared_examples "requires an application name" do
|
150
|
-
before do
|
151
|
-
enter_app_name ""
|
152
|
-
enter_app_name "Test app"
|
153
|
-
choose_environment_config
|
154
|
-
run
|
155
|
-
end
|
156
|
-
|
157
|
-
it "requires an application name" do
|
158
|
-
expect(output.scan("Enter application name:").length).to eq(2)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
shared_examples "capistrano install" do
|
163
|
-
let(:capfile) { File.join(tmp_dir, "Capfile") }
|
164
|
-
before do
|
165
|
-
enter_app_name "foo"
|
166
|
-
add_cli_input "n"
|
167
|
-
choose_environment_config
|
168
|
-
end
|
169
|
-
|
170
|
-
context "without Capfile" do
|
171
|
-
it "does nothing" do
|
172
|
-
run
|
173
|
-
|
174
|
-
expect(output).to_not include "Adding AppSignal integration to Capfile"
|
175
|
-
expect(File.exist?(capfile)).to be_falsy
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
context "with Capfile" do
|
180
|
-
context "when already installed" do
|
181
|
-
before { File.write(capfile, "require 'appsignal/capistrano'") }
|
182
|
-
|
183
|
-
it "does not add another require to Capfile" do
|
184
|
-
run
|
185
|
-
|
186
|
-
expect(output).to_not include "Adding AppSignal integration to Capfile"
|
187
|
-
expect(File.read(capfile).scan("appsignal").count).to eq(1)
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
context "when not installed" do
|
192
|
-
before { FileUtils.touch(capfile) }
|
193
|
-
|
194
|
-
it "adds a require to Capfile" do
|
195
|
-
run
|
196
|
-
|
197
|
-
expect(output).to include "Adding AppSignal integration to Capfile"
|
198
|
-
expect(File.read(capfile)).to include "require 'appsignal/capistrano'"
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
shared_examples "windows installation" do
|
205
|
-
before do
|
206
|
-
allow(Gem).to receive(:win_platform?).and_return(true)
|
207
|
-
expect(Appsignal::Demo).to_not receive(:transmit)
|
208
|
-
run
|
209
|
-
end
|
210
|
-
|
211
|
-
it "prints a warning for windows" do
|
212
|
-
expect(output).to include("The AppSignal agent currently does not work on Microsoft Windows")
|
213
|
-
expect(output).to include("staging/production environment")
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
shared_examples "demo data" do
|
218
|
-
context "with demo data sent" do
|
219
|
-
before do
|
220
|
-
expect(Appsignal::Demo).to receive(:transmit).and_return(true)
|
221
|
-
run
|
222
|
-
end
|
223
|
-
|
224
|
-
it "prints sending demo data" do
|
225
|
-
expect(output).to include "Sending example data to AppSignal", "Example data sent!"
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
context "without demo data being sent" do
|
230
|
-
before do
|
231
|
-
expect(Appsignal::Demo).to receive(:transmit).and_return(false)
|
232
|
-
run
|
233
|
-
end
|
234
|
-
|
235
|
-
it "prints that it couldn't send the demo data" do
|
236
|
-
expect(output).to include "Sending example data to AppSignal",
|
237
|
-
"Couldn't start the AppSignal agent and send example data",
|
238
|
-
"`appsignal diagnose`"
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
if rails_present?
|
244
|
-
context "with rails" do
|
245
|
-
let(:installation_instructions) do
|
246
|
-
[
|
247
|
-
"Installing for Ruby on Rails",
|
248
|
-
"Your app's name is: 'MyApp'"
|
249
|
-
]
|
250
|
-
end
|
251
|
-
let(:app_name) { "MyApp" }
|
252
|
-
let(:config_dir) { File.join(tmp_dir, "config") }
|
253
|
-
let(:environments_dir) { File.join(config_dir, "environments") }
|
254
|
-
before do
|
255
|
-
# Fake Rails directory
|
256
|
-
FileUtils.mkdir_p(config_dir)
|
257
|
-
FileUtils.mkdir_p(environments_dir)
|
258
|
-
FileUtils.touch(File.join(config_dir, "application.rb"))
|
259
|
-
FileUtils.touch(File.join(environments_dir, "development.rb"))
|
260
|
-
FileUtils.touch(File.join(environments_dir, "staging.rb"))
|
261
|
-
FileUtils.touch(File.join(environments_dir, "production.rb"))
|
262
|
-
end
|
263
|
-
|
264
|
-
describe "environments" do
|
265
|
-
before do
|
266
|
-
File.delete(File.join(environments_dir, "development.rb"))
|
267
|
-
File.delete(File.join(environments_dir, "staging.rb"))
|
268
|
-
add_cli_input "n"
|
269
|
-
choose_config_file
|
270
|
-
end
|
271
|
-
|
272
|
-
it "only configures the available environments" do
|
273
|
-
run
|
274
|
-
|
275
|
-
expect(output).to include_file_config
|
276
|
-
expect(config_file).to configure_app_name(app_name)
|
277
|
-
expect(config_file).to configure_push_api_key(push_api_key)
|
278
|
-
expect(config_file).to_not configure_environment("development")
|
279
|
-
expect(config_file).to_not configure_environment("staging")
|
280
|
-
expect(config_file).to configure_environment("production")
|
281
|
-
|
282
|
-
expect(output).to include(*installation_instructions)
|
283
|
-
expect(output).to include_complete_install
|
284
|
-
expect(output).to include_demo_transmission
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
context "without custom name" do
|
289
|
-
before { add_cli_input "n" }
|
290
|
-
|
291
|
-
it_behaves_like "push_api_key validation"
|
292
|
-
|
293
|
-
context "with configuration using environment variables" do
|
294
|
-
before { choose_environment_config }
|
295
|
-
|
296
|
-
it_behaves_like "windows installation"
|
297
|
-
it_behaves_like "capistrano install"
|
298
|
-
it_behaves_like "demo data"
|
299
|
-
|
300
|
-
it "prints environment variables" do
|
301
|
-
run
|
302
|
-
|
303
|
-
expect(output).to include_env_push_api_key(push_api_key)
|
304
|
-
expect(output).to_not include_env_app_name
|
305
|
-
end
|
306
|
-
|
307
|
-
it "completes the installation" do
|
308
|
-
run
|
309
|
-
|
310
|
-
expect(output).to include(*installation_instructions)
|
311
|
-
expect(output).to include_complete_install
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
context "with configuration using a configuration file" do
|
316
|
-
before { choose_config_file }
|
317
|
-
|
318
|
-
it_behaves_like "windows installation"
|
319
|
-
it_behaves_like "capistrano install"
|
320
|
-
it_behaves_like "demo data"
|
321
|
-
|
322
|
-
it "writes configuration to file" do
|
323
|
-
run
|
324
|
-
|
325
|
-
expect(output).to include_file_config
|
326
|
-
expect(config_file).to configure_app_name(app_name)
|
327
|
-
expect(config_file).to configure_push_api_key(push_api_key)
|
328
|
-
expect(config_file).to configure_environment("development")
|
329
|
-
expect(config_file).to configure_environment("staging")
|
330
|
-
expect(config_file).to configure_environment("production")
|
331
|
-
end
|
332
|
-
|
333
|
-
it "completes the installation" do
|
334
|
-
run
|
335
|
-
|
336
|
-
expect(output).to include(*installation_instructions)
|
337
|
-
expect(output).to include_complete_install
|
338
|
-
end
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
context "with custom name" do
|
343
|
-
let(:app_name) { "Custom name" }
|
344
|
-
before { add_cli_input "y" }
|
345
|
-
|
346
|
-
it_behaves_like "push_api_key validation"
|
347
|
-
|
348
|
-
it "requires the custom name" do
|
349
|
-
enter_app_name ""
|
350
|
-
enter_app_name app_name
|
351
|
-
choose_environment_config
|
352
|
-
run
|
353
|
-
|
354
|
-
expect(output.scan("Choose app's display name:").length).to eq(2)
|
355
|
-
end
|
356
|
-
|
357
|
-
context "with configuration using environment variables" do
|
358
|
-
before do
|
359
|
-
enter_app_name app_name
|
360
|
-
choose_environment_config
|
361
|
-
end
|
362
|
-
|
363
|
-
it_behaves_like "windows installation"
|
364
|
-
it_behaves_like "capistrano install"
|
365
|
-
it_behaves_like "demo data"
|
366
|
-
|
367
|
-
it "prints environment variables" do
|
368
|
-
run
|
369
|
-
|
370
|
-
expect(output).to include_env_push_api_key(push_api_key)
|
371
|
-
expect(output).to include_env_app_name(app_name)
|
372
|
-
end
|
373
|
-
|
374
|
-
it "completes the installation" do
|
375
|
-
run
|
376
|
-
|
377
|
-
expect(output).to include(*installation_instructions)
|
378
|
-
expect(output).to include_complete_install
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
|
-
context "with configuration using a configuration file" do
|
383
|
-
before do
|
384
|
-
enter_app_name app_name
|
385
|
-
choose_config_file
|
386
|
-
end
|
387
|
-
|
388
|
-
it_behaves_like "windows installation"
|
389
|
-
it_behaves_like "capistrano install"
|
390
|
-
it_behaves_like "demo data"
|
391
|
-
|
392
|
-
it "writes configuration to file" do
|
393
|
-
run
|
394
|
-
|
395
|
-
expect(output).to include_file_config
|
396
|
-
expect(config_file).to configure_app_name(app_name)
|
397
|
-
expect(config_file).to configure_push_api_key(push_api_key)
|
398
|
-
expect(config_file).to configure_environment("development")
|
399
|
-
expect(config_file).to configure_environment("staging")
|
400
|
-
expect(config_file).to configure_environment("production")
|
401
|
-
end
|
402
|
-
|
403
|
-
it "completes the installation" do
|
404
|
-
run
|
405
|
-
|
406
|
-
expect(output).to include(*installation_instructions)
|
407
|
-
expect(output).to include_complete_install
|
408
|
-
end
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
context "when there is no Rails application.rb file" do
|
413
|
-
before do
|
414
|
-
# Do not detect it as another framework for testing
|
415
|
-
allow(described_class).to receive(:framework_available?).and_call_original
|
416
|
-
allow(described_class).to receive(:framework_available?).with("sinatra").and_return(false)
|
417
|
-
|
418
|
-
File.delete(File.join(config_dir, "application.rb"))
|
419
|
-
expect(File.exist?(File.join(config_dir, "application.rb"))).to eql(false)
|
420
|
-
end
|
421
|
-
|
422
|
-
it "falls back on the unknown framework installation" do
|
423
|
-
enter_app_name app_name
|
424
|
-
choose_environment_config
|
425
|
-
run
|
426
|
-
|
427
|
-
expect(output)
|
428
|
-
.to include("\e[31mWarning: We could not detect which framework you are using\e[0m")
|
429
|
-
expect(output).to_not include("Installing for Ruby on Rails")
|
430
|
-
expect(output).to include_env_push_api_key(push_api_key)
|
431
|
-
expect(output).to include_complete_install
|
432
|
-
end
|
433
|
-
end
|
434
|
-
|
435
|
-
context "when failed to load the Rails application.rb file" do
|
436
|
-
before do
|
437
|
-
File.write(File.join(config_dir, "application.rb"), "I am invalid code")
|
438
|
-
end
|
439
|
-
|
440
|
-
it "prompts the user to fill in an app name" do
|
441
|
-
enter_app_name app_name
|
442
|
-
choose_config_file
|
443
|
-
run
|
444
|
-
|
445
|
-
expect(output).to include("Installing for Ruby on Rails")
|
446
|
-
expect(output).to include("Unable to automatically detect your Rails app's name.")
|
447
|
-
expect(output).to include("Choose your app's display name for AppSignal.com:")
|
448
|
-
expect(output).to include_file_config
|
449
|
-
expect(output).to include_complete_install
|
450
|
-
|
451
|
-
expect(config_file).to configure_app_name(app_name)
|
452
|
-
expect(config_file).to configure_push_api_key(push_api_key)
|
453
|
-
expect(config_file).to configure_environment("development")
|
454
|
-
expect(config_file).to configure_environment("staging")
|
455
|
-
expect(config_file).to configure_environment("production")
|
456
|
-
end
|
457
|
-
end
|
458
|
-
end
|
459
|
-
end
|
460
|
-
|
461
|
-
if sinatra_present? && !padrino_present? && !rails_present?
|
462
|
-
context "with sinatra" do
|
463
|
-
it_behaves_like "push_api_key validation"
|
464
|
-
it_behaves_like "requires an application name"
|
465
|
-
|
466
|
-
describe "sinatra specific tests" do
|
467
|
-
let(:installation_instructions) do
|
468
|
-
[
|
469
|
-
"Installing for Sinatra",
|
470
|
-
"Sinatra apps requires some manual setup.",
|
471
|
-
%(require "appsignal"),
|
472
|
-
"Appsignal.load(:sinatra)",
|
473
|
-
"Appsignal.start",
|
474
|
-
"https://docs.appsignal.com/ruby/integrations/sinatra.html"
|
475
|
-
]
|
476
|
-
end
|
477
|
-
let(:app_name) { "Test app" }
|
478
|
-
before { enter_app_name app_name }
|
479
|
-
|
480
|
-
describe "configuration with environment variables" do
|
481
|
-
before { choose_environment_config }
|
482
|
-
|
483
|
-
it_behaves_like "windows installation"
|
484
|
-
it_behaves_like "capistrano install"
|
485
|
-
it_behaves_like "demo data"
|
486
|
-
|
487
|
-
it "prints environment variables" do
|
488
|
-
run
|
489
|
-
|
490
|
-
expect(output).to include_env_push_api_key(push_api_key)
|
491
|
-
expect(output).to include_env_app_name(app_name)
|
492
|
-
end
|
493
|
-
|
494
|
-
it "completes the installation" do
|
495
|
-
run
|
496
|
-
|
497
|
-
expect(output).to include(*installation_instructions)
|
498
|
-
expect(output).to include_complete_install
|
499
|
-
end
|
500
|
-
end
|
501
|
-
|
502
|
-
describe "configure with a configuration file" do
|
503
|
-
before { choose_config_file }
|
504
|
-
|
505
|
-
it_behaves_like "windows installation"
|
506
|
-
it_behaves_like "capistrano install"
|
507
|
-
it_behaves_like "demo data"
|
508
|
-
|
509
|
-
it "writes configuration to file" do
|
510
|
-
run
|
511
|
-
|
512
|
-
expect(output).to include_file_config
|
513
|
-
expect(config_file).to configure_app_name(app_name)
|
514
|
-
expect(config_file).to configure_push_api_key(push_api_key)
|
515
|
-
expect(config_file).to configure_environment("development")
|
516
|
-
expect(config_file).to configure_environment("staging")
|
517
|
-
expect(config_file).to configure_environment("production")
|
518
|
-
end
|
519
|
-
|
520
|
-
it "completes the installation" do
|
521
|
-
run
|
522
|
-
|
523
|
-
expect(output).to include(*installation_instructions)
|
524
|
-
expect(output).to include_complete_install
|
525
|
-
end
|
526
|
-
end
|
527
|
-
end
|
528
|
-
end
|
529
|
-
end
|
530
|
-
|
531
|
-
if padrino_present?
|
532
|
-
context "with padrino" do
|
533
|
-
it_behaves_like "push_api_key validation"
|
534
|
-
it_behaves_like "requires an application name"
|
535
|
-
|
536
|
-
describe "padrino specific tests" do
|
537
|
-
let(:installation_instructions) do
|
538
|
-
[
|
539
|
-
"Installing for Padrino",
|
540
|
-
"Padrino apps requires some manual setup.",
|
541
|
-
%(require "appsignal"),
|
542
|
-
"Appsignal.load(:padrino)",
|
543
|
-
"Appsignal.start",
|
544
|
-
"https://docs.appsignal.com/ruby/integrations/padrino.html"
|
545
|
-
]
|
546
|
-
end
|
547
|
-
let(:app_name) { "Test app" }
|
548
|
-
before { enter_app_name app_name }
|
549
|
-
|
550
|
-
describe "configuration with environment variables" do
|
551
|
-
before { choose_environment_config }
|
552
|
-
|
553
|
-
it_behaves_like "windows installation"
|
554
|
-
it_behaves_like "capistrano install"
|
555
|
-
it_behaves_like "demo data"
|
556
|
-
|
557
|
-
it "prints environment variables" do
|
558
|
-
run
|
559
|
-
|
560
|
-
expect(output).to include_env_push_api_key(push_api_key)
|
561
|
-
expect(output).to include_env_app_name(app_name)
|
562
|
-
end
|
563
|
-
|
564
|
-
it "completes the installation" do
|
565
|
-
run
|
566
|
-
|
567
|
-
expect(output).to include(*installation_instructions)
|
568
|
-
expect(output).to include_complete_install
|
569
|
-
end
|
570
|
-
end
|
571
|
-
|
572
|
-
describe "configure with a configuration file" do
|
573
|
-
before { choose_config_file }
|
574
|
-
|
575
|
-
it_behaves_like "windows installation"
|
576
|
-
it_behaves_like "capistrano install"
|
577
|
-
it_behaves_like "demo data"
|
578
|
-
|
579
|
-
it "writes configuration to file" do
|
580
|
-
run
|
581
|
-
|
582
|
-
expect(output).to include_file_config
|
583
|
-
expect(config_file).to configure_app_name(app_name)
|
584
|
-
expect(config_file).to configure_push_api_key(push_api_key)
|
585
|
-
expect(config_file).to configure_environment("development")
|
586
|
-
expect(config_file).to configure_environment("staging")
|
587
|
-
expect(config_file).to configure_environment("production")
|
588
|
-
end
|
589
|
-
|
590
|
-
it "completes the installation" do
|
591
|
-
run
|
592
|
-
|
593
|
-
expect(output).to include(*installation_instructions)
|
594
|
-
expect(output).to include_complete_install
|
595
|
-
end
|
596
|
-
end
|
597
|
-
end
|
598
|
-
end
|
599
|
-
end
|
600
|
-
|
601
|
-
if grape_present?
|
602
|
-
context "with grape" do
|
603
|
-
it_behaves_like "push_api_key validation"
|
604
|
-
it_behaves_like "requires an application name"
|
605
|
-
|
606
|
-
describe "grape specific tests" do
|
607
|
-
let(:installation_instructions) do
|
608
|
-
[
|
609
|
-
"Installing for Grape",
|
610
|
-
"Grape apps require some manual setup.",
|
611
|
-
"https://docs.appsignal.com/ruby/integrations/grape.html"
|
612
|
-
]
|
613
|
-
end
|
614
|
-
let(:app_name) { "Test app" }
|
615
|
-
before { enter_app_name app_name }
|
616
|
-
|
617
|
-
describe "configuration with environment variables" do
|
618
|
-
before { choose_environment_config }
|
619
|
-
|
620
|
-
it_behaves_like "windows installation"
|
621
|
-
it_behaves_like "capistrano install"
|
622
|
-
it_behaves_like "demo data"
|
623
|
-
|
624
|
-
it "prints environment variables" do
|
625
|
-
run
|
626
|
-
|
627
|
-
expect(output).to include_env_push_api_key(push_api_key)
|
628
|
-
expect(output).to include_env_app_name(app_name)
|
629
|
-
end
|
630
|
-
|
631
|
-
it "completes the installation" do
|
632
|
-
run
|
633
|
-
|
634
|
-
puts output
|
635
|
-
expect(output).to include(*installation_instructions)
|
636
|
-
expect(output).to include_complete_install
|
637
|
-
end
|
638
|
-
end
|
639
|
-
|
640
|
-
describe "configure with a configuration file" do
|
641
|
-
before { choose_config_file }
|
642
|
-
|
643
|
-
it_behaves_like "windows installation"
|
644
|
-
it_behaves_like "capistrano install"
|
645
|
-
it_behaves_like "demo data"
|
646
|
-
|
647
|
-
it "writes configuration to file" do
|
648
|
-
run
|
649
|
-
|
650
|
-
expect(output).to include_file_config
|
651
|
-
expect(config_file).to configure_app_name(app_name)
|
652
|
-
expect(config_file).to configure_push_api_key(push_api_key)
|
653
|
-
expect(config_file).to configure_environment("development")
|
654
|
-
expect(config_file).to configure_environment("staging")
|
655
|
-
expect(config_file).to configure_environment("production")
|
656
|
-
end
|
657
|
-
|
658
|
-
it "completes the installation" do
|
659
|
-
run
|
660
|
-
|
661
|
-
expect(output).to include(*installation_instructions)
|
662
|
-
expect(output).to include_complete_install
|
663
|
-
end
|
664
|
-
end
|
665
|
-
end
|
666
|
-
end
|
667
|
-
end
|
668
|
-
|
669
|
-
if hanami2_present?
|
670
|
-
context "with hanami" do
|
671
|
-
it_behaves_like "push_api_key validation"
|
672
|
-
it_behaves_like "requires an application name"
|
673
|
-
|
674
|
-
describe "hanami specific tests" do
|
675
|
-
let(:installation_instructions) do
|
676
|
-
[
|
677
|
-
"Installing for Hanami",
|
678
|
-
"Hanami apps requires some manual setup.",
|
679
|
-
%(require "appsignal"),
|
680
|
-
"Appsignal.load(:hanami)",
|
681
|
-
"Appsignal.start",
|
682
|
-
"https://docs.appsignal.com/ruby/integrations/hanami.html"
|
683
|
-
]
|
684
|
-
end
|
685
|
-
let(:app_name) { "Test app" }
|
686
|
-
before { enter_app_name app_name }
|
687
|
-
|
688
|
-
describe "configuration with environment variables" do
|
689
|
-
before { choose_environment_config }
|
690
|
-
|
691
|
-
it_behaves_like "windows installation"
|
692
|
-
it_behaves_like "capistrano install"
|
693
|
-
it_behaves_like "demo data"
|
694
|
-
|
695
|
-
it "prints environment variables" do
|
696
|
-
run
|
697
|
-
|
698
|
-
expect(output).to include_env_push_api_key(push_api_key)
|
699
|
-
expect(output).to include_env_app_name(app_name)
|
700
|
-
end
|
701
|
-
|
702
|
-
it "completes the installation" do
|
703
|
-
run
|
704
|
-
|
705
|
-
expect(output).to include(*installation_instructions)
|
706
|
-
expect(output).to include_complete_install
|
707
|
-
end
|
708
|
-
end
|
709
|
-
|
710
|
-
describe "configure with a configuration file" do
|
711
|
-
before { choose_config_file }
|
712
|
-
|
713
|
-
it_behaves_like "windows installation"
|
714
|
-
it_behaves_like "capistrano install"
|
715
|
-
it_behaves_like "demo data"
|
716
|
-
|
717
|
-
it "writes configuration to file" do
|
718
|
-
run
|
719
|
-
expect(output).to include_file_config
|
720
|
-
expect(config_file).to configure_app_name(app_name)
|
721
|
-
expect(config_file).to configure_push_api_key(push_api_key)
|
722
|
-
expect(config_file).to configure_environment("development")
|
723
|
-
expect(config_file).to configure_environment("staging")
|
724
|
-
expect(config_file).to configure_environment("production")
|
725
|
-
end
|
726
|
-
|
727
|
-
it "completes the installation" do
|
728
|
-
run
|
729
|
-
|
730
|
-
expect(output).to include(*installation_instructions)
|
731
|
-
expect(output).to include_complete_install
|
732
|
-
end
|
733
|
-
end
|
734
|
-
end
|
735
|
-
end
|
736
|
-
end
|
737
|
-
|
738
|
-
if !rails_present? && !sinatra_present? && !padrino_present? && !grape_present? &&
|
739
|
-
!hanami2_present?
|
740
|
-
context "with unknown framework" do
|
741
|
-
let(:push_api_key) { "my_key" }
|
742
|
-
let(:app_name) { "Test app" }
|
743
|
-
|
744
|
-
it_behaves_like "push_api_key validation"
|
745
|
-
it_behaves_like "requires an application name"
|
746
|
-
|
747
|
-
describe "unknown framework specific tests" do
|
748
|
-
let(:installation_instructions) do
|
749
|
-
[
|
750
|
-
"Installing",
|
751
|
-
"\e[31mWarning: We could not detect which framework you are using\e[0m",
|
752
|
-
"Some manual installation is most likely required.",
|
753
|
-
"https://docs.appsignal.com/ruby/integrations.html"
|
754
|
-
]
|
755
|
-
end
|
756
|
-
before { enter_app_name app_name }
|
757
|
-
|
758
|
-
describe "configuration with environment variables" do
|
759
|
-
before { choose_environment_config }
|
760
|
-
|
761
|
-
it_behaves_like "windows installation"
|
762
|
-
it_behaves_like "capistrano install"
|
763
|
-
it_behaves_like "demo data"
|
764
|
-
|
765
|
-
it "prints environment variables" do
|
766
|
-
run
|
767
|
-
|
768
|
-
expect(output).to include_env_push_api_key(push_api_key)
|
769
|
-
expect(output).to include_env_app_name(app_name)
|
770
|
-
end
|
771
|
-
|
772
|
-
it "completes the installation" do
|
773
|
-
run
|
774
|
-
|
775
|
-
expect(output).to include(*installation_instructions)
|
776
|
-
expect(output).to include_complete_install
|
777
|
-
end
|
778
|
-
end
|
779
|
-
|
780
|
-
describe "configure with a configuration file" do
|
781
|
-
before { choose_config_file }
|
782
|
-
|
783
|
-
it_behaves_like "windows installation"
|
784
|
-
it_behaves_like "capistrano install"
|
785
|
-
it_behaves_like "demo data"
|
786
|
-
|
787
|
-
it "writes configuration to file" do
|
788
|
-
run
|
789
|
-
expect(output).to include_file_config
|
790
|
-
expect(config_file).to configure_app_name(app_name)
|
791
|
-
expect(config_file).to configure_push_api_key(push_api_key)
|
792
|
-
expect(config_file).to configure_environment("development")
|
793
|
-
expect(config_file).to configure_environment("staging")
|
794
|
-
expect(config_file).to configure_environment("production")
|
795
|
-
end
|
796
|
-
|
797
|
-
it "completes the installation" do
|
798
|
-
run
|
799
|
-
|
800
|
-
expect(output).to include(*installation_instructions)
|
801
|
-
expect(output).to include_complete_install
|
802
|
-
end
|
803
|
-
end
|
804
|
-
end
|
805
|
-
|
806
|
-
describe "color flag" do
|
807
|
-
before do
|
808
|
-
enter_app_name "Test app"
|
809
|
-
choose_environment_config
|
810
|
-
end
|
811
|
-
|
812
|
-
context "without color options" do
|
813
|
-
let(:options) { {} }
|
814
|
-
|
815
|
-
it "prints the instructions in color" do
|
816
|
-
run
|
817
|
-
expect(output).to have_colorized_text(
|
818
|
-
:green,
|
819
|
-
"## Starting AppSignal Installer ##"
|
820
|
-
)
|
821
|
-
end
|
822
|
-
end
|
823
|
-
|
824
|
-
context "with --color option" do
|
825
|
-
let(:options) { { "color" => nil } }
|
826
|
-
|
827
|
-
it "prints the instructions in color" do
|
828
|
-
run
|
829
|
-
expect(output).to have_colorized_text(
|
830
|
-
:green,
|
831
|
-
"## Starting AppSignal Installer ##"
|
832
|
-
)
|
833
|
-
end
|
834
|
-
end
|
835
|
-
|
836
|
-
context "with --no-color option" do
|
837
|
-
let(:options) { { "no-color" => nil } }
|
838
|
-
|
839
|
-
it "prints the instructions without special colors" do
|
840
|
-
run
|
841
|
-
expect(output).to include("## Starting AppSignal Installer ##")
|
842
|
-
expect(output).to_not have_color_markers
|
843
|
-
end
|
844
|
-
end
|
845
|
-
end
|
846
|
-
end
|
847
|
-
end
|
848
|
-
end
|