appsignal 2.5.0.alpha.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +33 -0
- data/.rspec +4 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +124 -0
- data/.travis.yml +72 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +639 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +264 -0
- data/Rakefile +214 -0
- data/appsignal.gemspec +42 -0
- data/benchmark.rake +77 -0
- data/bin/appsignal +13 -0
- data/ext/Rakefile +27 -0
- data/ext/agent.yml +64 -0
- data/ext/appsignal_extension.c +692 -0
- data/ext/base.rb +79 -0
- data/ext/extconf.rb +35 -0
- data/gemfiles/capistrano2.gemfile +7 -0
- data/gemfiles/capistrano3.gemfile +7 -0
- data/gemfiles/grape.gemfile +7 -0
- data/gemfiles/no_dependencies.gemfile +5 -0
- data/gemfiles/padrino.gemfile +7 -0
- data/gemfiles/que.gemfile +5 -0
- data/gemfiles/rails-3.2.gemfile +6 -0
- data/gemfiles/rails-4.0.gemfile +6 -0
- data/gemfiles/rails-4.1.gemfile +6 -0
- data/gemfiles/rails-4.2.gemfile +10 -0
- data/gemfiles/rails-5.0.gemfile +5 -0
- data/gemfiles/rails-5.1.gemfile +5 -0
- data/gemfiles/resque.gemfile +12 -0
- data/gemfiles/sequel-435.gemfile +11 -0
- data/gemfiles/sequel.gemfile +11 -0
- data/gemfiles/sinatra.gemfile +6 -0
- data/gemfiles/webmachine.gemfile +5 -0
- data/lib/appsignal.rb +804 -0
- data/lib/appsignal/auth_check.rb +65 -0
- data/lib/appsignal/capistrano.rb +10 -0
- data/lib/appsignal/cli.rb +108 -0
- data/lib/appsignal/cli/demo.rb +63 -0
- data/lib/appsignal/cli/diagnose.rb +500 -0
- data/lib/appsignal/cli/helpers.rb +72 -0
- data/lib/appsignal/cli/install.rb +277 -0
- data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
- data/lib/appsignal/config.rb +287 -0
- data/lib/appsignal/demo.rb +107 -0
- data/lib/appsignal/event_formatter.rb +74 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
- data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
- data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
- data/lib/appsignal/extension.rb +63 -0
- data/lib/appsignal/extension/jruby.rb +460 -0
- data/lib/appsignal/garbage_collection_profiler.rb +48 -0
- data/lib/appsignal/hooks.rb +105 -0
- data/lib/appsignal/hooks/action_cable.rb +113 -0
- data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
- data/lib/appsignal/hooks/celluloid.rb +30 -0
- data/lib/appsignal/hooks/data_mapper.rb +18 -0
- data/lib/appsignal/hooks/delayed_job.rb +19 -0
- data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
- data/lib/appsignal/hooks/net_http.rb +29 -0
- data/lib/appsignal/hooks/passenger.rb +22 -0
- data/lib/appsignal/hooks/puma.rb +35 -0
- data/lib/appsignal/hooks/que.rb +21 -0
- data/lib/appsignal/hooks/rake.rb +39 -0
- data/lib/appsignal/hooks/redis.rb +30 -0
- data/lib/appsignal/hooks/sequel.rb +60 -0
- data/lib/appsignal/hooks/shoryuken.rb +43 -0
- data/lib/appsignal/hooks/sidekiq.rb +144 -0
- data/lib/appsignal/hooks/unicorn.rb +40 -0
- data/lib/appsignal/hooks/webmachine.rb +23 -0
- data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
- data/lib/appsignal/integrations/data_mapper.rb +33 -0
- data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
- data/lib/appsignal/integrations/grape.rb +53 -0
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
- data/lib/appsignal/integrations/object.rb +35 -0
- data/lib/appsignal/integrations/padrino.rb +84 -0
- data/lib/appsignal/integrations/que.rb +43 -0
- data/lib/appsignal/integrations/railtie.rb +41 -0
- data/lib/appsignal/integrations/rake.rb +2 -0
- data/lib/appsignal/integrations/resque.rb +20 -0
- data/lib/appsignal/integrations/resque_active_job.rb +30 -0
- data/lib/appsignal/integrations/sinatra.rb +17 -0
- data/lib/appsignal/integrations/webmachine.rb +38 -0
- data/lib/appsignal/js_exception_transaction.rb +54 -0
- data/lib/appsignal/marker.rb +63 -0
- data/lib/appsignal/minutely.rb +42 -0
- data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
- data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
- data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
- data/lib/appsignal/rack/streaming_listener.rb +73 -0
- data/lib/appsignal/system.rb +81 -0
- data/lib/appsignal/transaction.rb +498 -0
- data/lib/appsignal/transmitter.rb +107 -0
- data/lib/appsignal/utils.rb +127 -0
- data/lib/appsignal/utils/params_sanitizer.rb +59 -0
- data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
- data/lib/appsignal/version.rb +3 -0
- data/lib/sequel/extensions/appsignal_integration.rb +3 -0
- data/resources/appsignal.yml.erb +39 -0
- data/resources/cacert.pem +3866 -0
- data/spec/.rubocop.yml +7 -0
- data/spec/lib/appsignal/auth_check_spec.rb +80 -0
- data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
- data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
- data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
- data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
- data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
- data/spec/lib/appsignal/cli/install_spec.rb +632 -0
- data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
- data/spec/lib/appsignal/cli_spec.rb +56 -0
- data/spec/lib/appsignal/config_spec.rb +637 -0
- data/spec/lib/appsignal/demo_spec.rb +87 -0
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
- data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
- data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
- data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
- data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
- data/spec/lib/appsignal/extension_spec.rb +137 -0
- data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
- data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
- data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
- data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
- data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
- data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
- data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
- data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
- data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
- data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
- data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
- data/spec/lib/appsignal/hooks_spec.rb +195 -0
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
- data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
- data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
- data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
- data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
- data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
- data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
- data/spec/lib/appsignal/marker_spec.rb +51 -0
- data/spec/lib/appsignal/minutely_spec.rb +50 -0
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
- data/spec/lib/appsignal/system_spec.rb +131 -0
- data/spec/lib/appsignal/transaction_spec.rb +1146 -0
- data/spec/lib/appsignal/transmitter_spec.rb +152 -0
- data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
- data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
- data/spec/lib/appsignal/utils_spec.rb +150 -0
- data/spec/lib/appsignal_spec.rb +1049 -0
- data/spec/spec_helper.rb +116 -0
- data/spec/support/fixtures/containers/cgroups/docker +14 -0
- data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
- data/spec/support/fixtures/containers/cgroups/lxc +10 -0
- data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
- data/spec/support/fixtures/containers/cgroups/none +1 -0
- data/spec/support/fixtures/generated_config.yml +24 -0
- data/spec/support/fixtures/uploaded_file.txt +0 -0
- data/spec/support/helpers/api_request_helper.rb +19 -0
- data/spec/support/helpers/cli_helpers.rb +26 -0
- data/spec/support/helpers/config_helpers.rb +21 -0
- data/spec/support/helpers/dependency_helper.rb +73 -0
- data/spec/support/helpers/directory_helper.rb +27 -0
- data/spec/support/helpers/env_helpers.rb +33 -0
- data/spec/support/helpers/example_exception.rb +13 -0
- data/spec/support/helpers/example_standard_error.rb +13 -0
- data/spec/support/helpers/log_helpers.rb +22 -0
- data/spec/support/helpers/std_streams_helper.rb +66 -0
- data/spec/support/helpers/system_helpers.rb +8 -0
- data/spec/support/helpers/time_helpers.rb +11 -0
- data/spec/support/helpers/transaction_helpers.rb +37 -0
- data/spec/support/matchers/contains_log.rb +7 -0
- data/spec/support/mocks/fake_gc_profiler.rb +19 -0
- data/spec/support/mocks/mock_extension.rb +6 -0
- data/spec/support/project_fixture/config/application.rb +0 -0
- data/spec/support/project_fixture/config/appsignal.yml +32 -0
- data/spec/support/project_fixture/config/environments/development.rb +0 -0
- data/spec/support/project_fixture/config/environments/production.rb +0 -0
- data/spec/support/project_fixture/config/environments/test.rb +0 -0
- data/spec/support/project_fixture/log/.gitkeep +0 -0
- data/spec/support/rails/my_app.rb +6 -0
- data/spec/support/shared_examples/instrument.rb +43 -0
- data/spec/support/stubs/delayed_job.rb +0 -0
- metadata +483 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
describe Appsignal::Transmitter do
|
|
2
|
+
let(:config) { project_fixture_config }
|
|
3
|
+
let(:base_uri) { "action" }
|
|
4
|
+
let(:log) { StringIO.new }
|
|
5
|
+
let(:instance) { Appsignal::Transmitter.new(base_uri, config) }
|
|
6
|
+
before do
|
|
7
|
+
config.config_hash[:hostname] = "app1.local"
|
|
8
|
+
config.logger = Logger.new(log)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "#uri" do
|
|
12
|
+
let(:uri) { instance.uri }
|
|
13
|
+
|
|
14
|
+
it "returns a URI object with configuration data" do
|
|
15
|
+
expect(uri.to_s).to start_with(config[:endpoint])
|
|
16
|
+
expect(uri.path).to eq("/1/action")
|
|
17
|
+
expect(CGI.parse(uri.query)).to eq(
|
|
18
|
+
"api_key" => ["abc"],
|
|
19
|
+
"hostname" => ["app1.local"],
|
|
20
|
+
"name" => ["TestApp"],
|
|
21
|
+
"environment" => ["production"],
|
|
22
|
+
"gem_version" => [Appsignal::VERSION]
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "when base_uri argument is a full URI" do
|
|
27
|
+
let(:base_uri) { "http://foo.bar/path" }
|
|
28
|
+
|
|
29
|
+
it "uses the full URI" do
|
|
30
|
+
expect(uri.to_s).to start_with("#{base_uri}?")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "when base_uri argument is only a path" do
|
|
35
|
+
it "uses the config[:endpoint] base" do
|
|
36
|
+
expect(uri.to_s).to start_with("#{config[:endpoint]}/1/#{base_uri}?")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "#transmit" do
|
|
42
|
+
before do
|
|
43
|
+
stub_request(:post, "https://push.appsignal.com/1/action").with(
|
|
44
|
+
:query => {
|
|
45
|
+
:api_key => "abc",
|
|
46
|
+
:environment => "production",
|
|
47
|
+
:gem_version => Appsignal::VERSION,
|
|
48
|
+
:hostname => config[:hostname],
|
|
49
|
+
:name => "TestApp"
|
|
50
|
+
},
|
|
51
|
+
:body => "{\"the\":\"payload\"}",
|
|
52
|
+
:headers => {
|
|
53
|
+
"Content-Type" => "application/json; charset=UTF-8"
|
|
54
|
+
}
|
|
55
|
+
).to_return(:status => 200)
|
|
56
|
+
end
|
|
57
|
+
let(:response) { instance.transmit(:the => :payload) }
|
|
58
|
+
|
|
59
|
+
it "returns Net::HTTP response" do
|
|
60
|
+
expect(response).to be_kind_of(Net::HTTPResponse)
|
|
61
|
+
expect(response.code).to eq "200"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "with ca_file_path config option set" do
|
|
65
|
+
context "when file does not exist" do
|
|
66
|
+
before do
|
|
67
|
+
config.config_hash[:ca_file_path] = File.join(resources_dir, "cacert.pem")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "ignores the config and logs a warning" do
|
|
71
|
+
expect(response).to be_kind_of(Net::HTTPResponse)
|
|
72
|
+
expect(response.code).to eq "200"
|
|
73
|
+
expect(log.string).to_not include "Ignoring non-existing or unreadable " \
|
|
74
|
+
"`ca_file_path`: #{config[:ca_file_path]}"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context "when not existing file" do
|
|
79
|
+
before do
|
|
80
|
+
config.config_hash[:ca_file_path] = File.join(tmp_dir, "ca_file_that_does_not_exist")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "ignores the config and logs a warning" do
|
|
84
|
+
expect(response).to be_kind_of(Net::HTTPResponse)
|
|
85
|
+
expect(response.code).to eq "200"
|
|
86
|
+
expect(log.string).to include "Ignoring non-existing or unreadable " \
|
|
87
|
+
"`ca_file_path`: #{config[:ca_file_path]}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context "when not readable file" do
|
|
92
|
+
let(:file) { File.join(tmp_dir, "ca_file") }
|
|
93
|
+
before do
|
|
94
|
+
config.config_hash[:ca_file_path] = file
|
|
95
|
+
File.open(file, "w") { |f| f.chmod 0o000 }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "ignores the config and logs a warning" do
|
|
99
|
+
expect(response).to be_kind_of(Net::HTTPResponse)
|
|
100
|
+
expect(response.code).to eq "200"
|
|
101
|
+
expect(log.string).to include "Ignoring non-existing or unreadable " \
|
|
102
|
+
"`ca_file_path`: #{config[:ca_file_path]}"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
after { File.delete file }
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe "#http_post" do
|
|
111
|
+
subject { instance.send(:http_post, "the" => "payload") }
|
|
112
|
+
|
|
113
|
+
it "sets the path" do
|
|
114
|
+
expect(subject.path).to eq instance.uri.request_uri
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "sets the correct headers" do
|
|
118
|
+
expect(subject["Content-Type"]).to eq "application/json; charset=UTF-8"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
describe "#http_client" do
|
|
123
|
+
subject { instance.send(:http_client) }
|
|
124
|
+
|
|
125
|
+
context "with a http uri" do
|
|
126
|
+
let(:config) { project_fixture_config("test") }
|
|
127
|
+
|
|
128
|
+
it { expect(subject).to be_instance_of(Net::HTTP) }
|
|
129
|
+
it { expect(subject.proxy?).to be_falsy }
|
|
130
|
+
it { expect(subject.use_ssl?).to be_falsy }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
context "with a https uri" do
|
|
134
|
+
let(:config) { project_fixture_config("production") }
|
|
135
|
+
|
|
136
|
+
it { expect(subject).to be_instance_of(Net::HTTP) }
|
|
137
|
+
it { expect(subject.proxy?).to be_falsy }
|
|
138
|
+
it { expect(subject.use_ssl?).to be_truthy }
|
|
139
|
+
it { expect(subject.verify_mode).to eq OpenSSL::SSL::VERIFY_PEER }
|
|
140
|
+
it { expect(subject.ca_file).to eq config[:ca_file_path] }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
context "with a proxy" do
|
|
144
|
+
let(:config) { project_fixture_config("production", :http_proxy => "http://localhost:8080") }
|
|
145
|
+
|
|
146
|
+
it { expect(subject).to be_instance_of(Net::HTTP) }
|
|
147
|
+
it { expect(subject.proxy?).to be_truthy }
|
|
148
|
+
it { expect(subject.proxy_address).to eq "localhost" }
|
|
149
|
+
it { expect(subject.proxy_port).to eq 8080 }
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
describe Appsignal::Utils::ParamsSanitizer do
|
|
2
|
+
let(:file) { uploaded_file }
|
|
3
|
+
let(:params) do
|
|
4
|
+
{
|
|
5
|
+
:text => "string",
|
|
6
|
+
"string" => "string key value",
|
|
7
|
+
:file => file,
|
|
8
|
+
:float => 0.0,
|
|
9
|
+
:bool_true => true,
|
|
10
|
+
:bool_false => false,
|
|
11
|
+
:nil => nil,
|
|
12
|
+
:int => 1, # Fixnum
|
|
13
|
+
:int64 => 1 << 64, # Bignum
|
|
14
|
+
:hash => {
|
|
15
|
+
:nested_text => "string",
|
|
16
|
+
:nested_array => [
|
|
17
|
+
"something",
|
|
18
|
+
"else",
|
|
19
|
+
file,
|
|
20
|
+
{
|
|
21
|
+
:key => "value",
|
|
22
|
+
:file => file
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe ".sanitize" do
|
|
30
|
+
let(:sanitized_params) { described_class.sanitize(params) }
|
|
31
|
+
subject { sanitized_params }
|
|
32
|
+
|
|
33
|
+
it { is_expected.to be_instance_of Hash }
|
|
34
|
+
it { expect(subject[:text]).to eq("string") }
|
|
35
|
+
it { expect(subject["string"]).to eq("string key value") }
|
|
36
|
+
it do
|
|
37
|
+
expect(subject[:file]).to be_instance_of String
|
|
38
|
+
expect(subject[:file]).to include "::UploadedFile"
|
|
39
|
+
end
|
|
40
|
+
it { expect(subject[:float]).to eq(0.0) }
|
|
41
|
+
it { expect(subject[:bool_true]).to be(true) }
|
|
42
|
+
it { expect(subject[:bool_false]).to be(false) }
|
|
43
|
+
it { expect(subject[:nil]).to be_nil }
|
|
44
|
+
it { expect(subject[:int]).to eq(1) }
|
|
45
|
+
it { expect(subject[:int64]).to eq(1 << 64) }
|
|
46
|
+
|
|
47
|
+
it "does not change the original params" do
|
|
48
|
+
subject
|
|
49
|
+
expect(params[:file]).to eq(file)
|
|
50
|
+
expect(params[:hash][:nested_array][2]).to eq(file)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe ":hash" do
|
|
54
|
+
subject { sanitized_params[:hash] }
|
|
55
|
+
|
|
56
|
+
it { is_expected.to be_instance_of Hash }
|
|
57
|
+
it { expect(subject[:nested_text]).to eq("string") }
|
|
58
|
+
|
|
59
|
+
describe ":nested_array" do
|
|
60
|
+
subject { sanitized_params[:hash][:nested_array] }
|
|
61
|
+
|
|
62
|
+
it { is_expected.to be_instance_of Array }
|
|
63
|
+
it { expect(subject[0]).to eq("something") }
|
|
64
|
+
it { expect(subject[1]).to eq("else") }
|
|
65
|
+
it do
|
|
66
|
+
expect(subject[2]).to be_instance_of String
|
|
67
|
+
expect(subject[2]).to include "::UploadedFile"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe ":nested_hash" do
|
|
71
|
+
subject { sanitized_params[:hash][:nested_array][3] }
|
|
72
|
+
|
|
73
|
+
it { is_expected.to be_instance_of Hash }
|
|
74
|
+
it { expect(subject[:key]).to eq("value") }
|
|
75
|
+
it do
|
|
76
|
+
expect(subject[:file]).to be_instance_of String
|
|
77
|
+
expect(subject[:file]).to include "::UploadedFile"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "with :filter_parameters option" do
|
|
84
|
+
let(:sanitized_params) do
|
|
85
|
+
described_class.sanitize(params, :filter_parameters => %w[text hash])
|
|
86
|
+
end
|
|
87
|
+
subject { sanitized_params }
|
|
88
|
+
|
|
89
|
+
it { expect(subject[:text]).to eq(described_class::FILTERED) }
|
|
90
|
+
it { expect(subject[:hash]).to eq(described_class::FILTERED) }
|
|
91
|
+
it do
|
|
92
|
+
expect(subject[:file]).to be_instance_of String
|
|
93
|
+
expect(subject[:file]).to include "::UploadedFile"
|
|
94
|
+
end
|
|
95
|
+
it { expect(subject[:float]).to eq(0.0) }
|
|
96
|
+
it { expect(subject[:bool_true]).to be(true) }
|
|
97
|
+
it { expect(subject[:bool_false]).to be(false) }
|
|
98
|
+
it { expect(subject[:nil]).to be_nil }
|
|
99
|
+
it { expect(subject[:int]).to eq(1) }
|
|
100
|
+
|
|
101
|
+
context "with strings as key filter values" do
|
|
102
|
+
let(:sanitized_params) do
|
|
103
|
+
described_class.sanitize(params, :filter_parameters => %w[string])
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "sanitizes values" do
|
|
107
|
+
expect(subject["string"]).to eq("[FILTERED]")
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe ":hash" do
|
|
112
|
+
let(:sanitized_params) do
|
|
113
|
+
described_class.sanitize(params, :filter_parameters => %w[nested_text])
|
|
114
|
+
end
|
|
115
|
+
subject { sanitized_params[:hash] }
|
|
116
|
+
|
|
117
|
+
it "sanitizes values in nested hashes" do
|
|
118
|
+
expect(subject[:nested_text]).to eq("[FILTERED]")
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe ":nested_array" do
|
|
122
|
+
describe ":nested_hash" do
|
|
123
|
+
let(:sanitized_params) do
|
|
124
|
+
described_class.sanitize(params, :filter_parameters => %w[key])
|
|
125
|
+
end
|
|
126
|
+
subject { sanitized_params[:hash][:nested_array][3] }
|
|
127
|
+
|
|
128
|
+
it "sanitizes values in deeply nested hashes and arrays" do
|
|
129
|
+
expect(subject[:key]).to eq("[FILTERED]")
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
describe Appsignal::Utils::QueryParamsSanitizer do
|
|
2
|
+
describe ".sanitize" do
|
|
3
|
+
context "when only_top_level = true" do
|
|
4
|
+
subject { described_class.sanitize(value, true) }
|
|
5
|
+
|
|
6
|
+
context "when value is a hash" do
|
|
7
|
+
let(:value) { { "foo" => "bar" } }
|
|
8
|
+
|
|
9
|
+
it "should only return the first level of the object" do
|
|
10
|
+
expect(subject).to eq("foo" => "?")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should not modify source value" do
|
|
14
|
+
subject
|
|
15
|
+
expect(value).to eq("foo" => "bar")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "when value is a nested hash" do
|
|
20
|
+
let(:value) { { "foo" => { "bar" => "baz" } } }
|
|
21
|
+
|
|
22
|
+
it "should only return the first level of the object" do
|
|
23
|
+
expect(subject).to eq("foo" => "?")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should not modify source value" do
|
|
27
|
+
subject
|
|
28
|
+
expect(value).to eq("foo" => { "bar" => "baz" })
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "when value is an array of hashes" do
|
|
33
|
+
let(:value) { ["foo" => "bar"] }
|
|
34
|
+
|
|
35
|
+
it "should sanitize all hash values with a questionmark" do
|
|
36
|
+
expect(subject).to eq("foo" => "?")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should not modify source value" do
|
|
40
|
+
subject
|
|
41
|
+
expect(value).to eq(["foo" => "bar"])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "when value is an array" do
|
|
46
|
+
let(:value) { %w[foo bar] }
|
|
47
|
+
|
|
48
|
+
it "should only return the first level of the object" do
|
|
49
|
+
expect(subject).to eq("?")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should not modify source value" do
|
|
53
|
+
subject
|
|
54
|
+
expect(value).to eq(%w[foo bar])
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "when value is a mixed array" do
|
|
59
|
+
let(:value) { [nil, "foo", "bar"] }
|
|
60
|
+
|
|
61
|
+
it "should sanitize all hash values with a single questionmark" do
|
|
62
|
+
expect(subject).to eq("?")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context "when value is a string" do
|
|
67
|
+
let(:value) { "foo" }
|
|
68
|
+
|
|
69
|
+
it "should sanitize all hash values with a questionmark" do
|
|
70
|
+
expect(subject).to eq("?")
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "when only_top_level = false" do
|
|
76
|
+
subject { described_class.sanitize(value, false) }
|
|
77
|
+
|
|
78
|
+
context "when value is a hash" do
|
|
79
|
+
let(:value) { { "foo" => "bar" } }
|
|
80
|
+
|
|
81
|
+
it "should sanitize all hash values with a questionmark" do
|
|
82
|
+
expect(subject).to eq("foo" => "?")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should not modify source value" do
|
|
86
|
+
subject
|
|
87
|
+
expect(value).to eq("foo" => "bar")
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context "when value is a nested hash" do
|
|
92
|
+
let(:value) { { "foo" => { "bar" => "baz" } } }
|
|
93
|
+
|
|
94
|
+
it "should replaces values" do
|
|
95
|
+
expect(subject).to eq("foo" => { "bar" => "?" })
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should not modify source value" do
|
|
99
|
+
subject
|
|
100
|
+
expect(value).to eq("foo" => { "bar" => "baz" })
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
context "when value is an array of hashes" do
|
|
105
|
+
let(:value) { ["foo" => "bar"] }
|
|
106
|
+
|
|
107
|
+
it "should sanitize all hash values with a questionmark" do
|
|
108
|
+
expect(subject).to eq(["foo" => "?"])
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should not modify source value" do
|
|
112
|
+
subject
|
|
113
|
+
expect(value).to eq(["foo" => "bar"])
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context "when value is an array" do
|
|
118
|
+
let(:value) { %w[foo bar] }
|
|
119
|
+
|
|
120
|
+
it "should sanitize all hash values with a single questionmark" do
|
|
121
|
+
expect(subject).to eq(["?"])
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
context "when value is a mixed array" do
|
|
126
|
+
let(:value) { [nil, "foo", "bar"] }
|
|
127
|
+
|
|
128
|
+
it "should sanitize all hash values with a single questionmark" do
|
|
129
|
+
expect(subject).to eq(["?"])
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
context "when value is a string" do
|
|
134
|
+
let(:value) { "bar" }
|
|
135
|
+
|
|
136
|
+
it "should sanitize all hash values with a questionmark" do
|
|
137
|
+
expect(subject).to eq("?")
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
describe "key_sanitizer option" do
|
|
144
|
+
context "without key_sanitizer" do
|
|
145
|
+
subject { described_class.sanitize(value) }
|
|
146
|
+
|
|
147
|
+
context "when dots are in the key" do
|
|
148
|
+
let(:value) { { "foo.bar" => "bar" } }
|
|
149
|
+
|
|
150
|
+
it "should not sanitize the key" do
|
|
151
|
+
expect(subject).to eql("foo.bar" => "?")
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
context "when key is a symbol" do
|
|
156
|
+
let(:value) { { :ismaster => "bar" } }
|
|
157
|
+
|
|
158
|
+
it "should sanitize the key" do
|
|
159
|
+
expect(subject).to eql(:ismaster => "?")
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
context "with mongodb key_sanitizer" do
|
|
165
|
+
subject { described_class.sanitize(value, false, :mongodb) }
|
|
166
|
+
|
|
167
|
+
context "when no dots are in the key" do
|
|
168
|
+
let(:value) { { "foo" => "bar" } }
|
|
169
|
+
|
|
170
|
+
it "should not sanitize the key" do
|
|
171
|
+
expect(subject).to eql("foo" => "?")
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
context "when dots are in the key" do
|
|
176
|
+
let(:value) { { "foo.bar" => "bar" } }
|
|
177
|
+
|
|
178
|
+
it "should sanitize the key" do
|
|
179
|
+
expect(subject).to eql("foo.?" => "?")
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
context "when key is a symbol" do
|
|
184
|
+
let(:value) { { :ismaster => "bar" } }
|
|
185
|
+
|
|
186
|
+
it "should sanitize the key" do
|
|
187
|
+
expect(subject).to eql("ismaster" => "?")
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|