Skip to content

Commit 3ab9296

Browse files
committed
add (and skip) missing specs
1 parent 14e0743 commit 3ab9296

18 files changed

+838
-309
lines changed

Diff for: lib/mongo/client.rb

+111-92
Original file line numberDiff line numberDiff line change
@@ -1364,74 +1364,25 @@ def cluster_modifying?(new_options)
13641364
# but does not check for interactions between combinations of options.
13651365
def validate_new_options!(opts)
13661366
return Options::Redacted.new unless opts
1367-
if opts[:read_concern]
1368-
# Raise an error for non user-settable options
1369-
if opts[:read_concern][:after_cluster_time]
1370-
raise Mongo::Error::InvalidReadConcern.new(
1371-
'The after_cluster_time read_concern option cannot be specified by the user'
1372-
)
1373-
end
1374-
1375-
given_keys = opts[:read_concern].keys.map(&:to_s)
1376-
allowed_keys = ['level']
1377-
invalid_keys = given_keys - allowed_keys
1378-
# Warn that options are invalid but keep it and forward to the server
1379-
unless invalid_keys.empty?
1380-
log_warn("Read concern has invalid keys: #{invalid_keys.join(',')}.")
1381-
end
1382-
end
1383-
1384-
if server_api = opts[:server_api]
1385-
unless server_api.is_a?(Hash)
1386-
raise ArgumentError, ":server_api value must be a hash: #{server_api}"
1387-
end
1388-
1389-
extra_keys = server_api.keys - %w(version strict deprecation_errors)
1390-
unless extra_keys.empty?
1391-
raise ArgumentError, "Unknown keys under :server_api: #{extra_keys.map(&:inspect).join(', ')}"
1392-
end
13931367

1394-
if version = server_api[:version]
1395-
unless VALID_SERVER_API_VERSIONS.include?(version)
1396-
raise ArgumentError, "Unknown server API version: #{version}"
1397-
end
1398-
end
1368+
validate_read_concern!(opts[:read_concern])
1369+
validate_server_api!(opts[:server_api])
1370+
validate_max_min_pool_size!(opts)
1371+
validate_max_connecting!(opts)
1372+
validate_read!(opts)
1373+
validate_compressors!(opts)
1374+
validate_srv_max_hosts!(opts)
1375+
1376+
invalid_options = opts.keys.map(&:to_sym) - VALID_OPTIONS
1377+
if invalid_options.any?
1378+
log_warn("Unsupported client options: #{invalid_options.join(', ')}. These will be ignored.")
1379+
opts = opts.select { |key,| VALID_OPTIONS.include?(key.to_sym) }
13991380
end
14001381

14011382
Lint.validate_underscore_read_preference(opts[:read])
14021383
Lint.validate_read_concern_option(opts[:read_concern])
1403-
opts.each.inject(Options::Redacted.new) do |_options, (k, v)|
1404-
key = k.to_sym
1405-
if VALID_OPTIONS.include?(key)
1406-
validate_max_min_pool_size!(key, opts)
1407-
validate_max_connecting!(key, opts)
1408-
validate_read!(key, opts)
1409-
if key == :compressors
1410-
compressors = valid_compressors(v)
1411-
1412-
if compressors.include?('snappy')
1413-
validate_snappy_compression!
1414-
end
1415-
1416-
if compressors.include?('zstd')
1417-
validate_zstd_compression!
1418-
end
14191384

1420-
_options[key] = compressors unless compressors.empty?
1421-
elsif key == :srv_max_hosts
1422-
if v && (!v.is_a?(Integer) || v < 0)
1423-
log_warn("#{v} is not a valid integer for srv_max_hosts")
1424-
else
1425-
_options[key] = v
1426-
end
1427-
else
1428-
_options[key] = v
1429-
end
1430-
else
1431-
log_warn("Unsupported client option '#{k}'. It will be ignored.")
1432-
end
1433-
_options
1434-
end
1385+
Options::Redacted.new(opts)
14351386
end
14361387

14371388
# Validates all options after they are set on the client.
@@ -1569,6 +1520,48 @@ def validate_options!(addresses = nil, is_srv: nil)
15691520
end
15701521
end
15711522

1523+
ALLOWED_READ_CONCERN_KEYS = %w[ level ].freeze
1524+
1525+
def validate_read_concern!(read_concern)
1526+
return unless read_concern
1527+
1528+
# Raise an error for non user-settable options
1529+
if read_concern[:after_cluster_time]
1530+
raise Mongo::Error::InvalidReadConcern.new(
1531+
'The after_cluster_time read_concern option cannot be specified by the user'
1532+
)
1533+
end
1534+
1535+
given_keys = read_concern.keys.map(&:to_s)
1536+
invalid_keys = given_keys - ALLOWED_READ_CONCERN_KEYS
1537+
1538+
# Warn that options are invalid but keep it and forward to the server
1539+
unless invalid_keys.empty?
1540+
log_warn("Read concern has invalid keys: #{invalid_keys.join(',')}.")
1541+
end
1542+
end
1543+
1544+
ALLOWED_SERVER_API_KEYS = %w[ version strict deprecation_errors ].freeze
1545+
1546+
def validate_server_api!(server_api)
1547+
return unless server_api
1548+
1549+
unless server_api.is_a?(Hash)
1550+
raise ArgumentError, ":server_api value must be a hash: #{server_api}"
1551+
end
1552+
1553+
extra_keys = server_api.keys - ALLOWED_SERVER_API_KEYS
1554+
unless extra_keys.empty?
1555+
raise ArgumentError, "Unknown keys under :server_api: #{extra_keys.map(&:inspect).join(', ')}"
1556+
end
1557+
1558+
if version = server_api[:version]
1559+
unless VALID_SERVER_API_VERSIONS.include?(version)
1560+
raise ArgumentError, "Unknown server API version: #{version}"
1561+
end
1562+
end
1563+
end
1564+
15721565
# Validates all authentication-related options after they are set on the client
15731566
# This method is intended to catch combinations of options which are not allowed
15741567
def validate_authentication_options!
@@ -1639,6 +1632,22 @@ def valid_compressors(compressors)
16391632
end
16401633
end
16411634

1635+
def validate_compressors!(opts)
1636+
return unless opts[:compressors]
1637+
1638+
compressors = valid_compressors(opts[:compressors])
1639+
1640+
if compressors.include?('snappy')
1641+
validate_snappy_compression!
1642+
end
1643+
1644+
if compressors.include?('zstd')
1645+
validate_zstd_compression!
1646+
end
1647+
1648+
opts[:compressors] = compressors unless compressors.empty?
1649+
end
1650+
16421651
def validate_snappy_compression!
16431652
return if defined?(Snappy)
16441653
require 'snappy'
@@ -1657,14 +1666,25 @@ def validate_zstd_compression!
16571666
"\"bundle install\" to install the gem. (#{e.class}: #{e})"
16581667
end
16591668

1660-
def validate_max_min_pool_size!(option, opts)
1661-
if option == :min_pool_size && opts[:min_pool_size]
1662-
max = opts[:max_pool_size] || Server::ConnectionPool::DEFAULT_MAX_SIZE
1663-
if max != 0 && opts[:min_pool_size] > max
1664-
raise Error::InvalidMinPoolSize.new(opts[:min_pool_size], max)
1665-
end
1669+
def validate_max_min_pool_size!(opts)
1670+
return unless opts[:min_pool_size]
1671+
1672+
max = opts[:max_pool_size] || Server::ConnectionPool::DEFAULT_MAX_SIZE
1673+
if max != 0 && opts[:min_pool_size] > max
1674+
raise Error::InvalidMinPoolSize.new(opts[:min_pool_size], max)
1675+
end
1676+
end
1677+
1678+
def validate_srv_max_hosts!(opts)
1679+
return unless opts.key?(:srv_max_hosts)
1680+
1681+
srv_max_hosts = opts[:srv_max_hosts]
1682+
return unless srv_max_hosts
1683+
1684+
if !srv_max_hosts.is_a?(Integer) || srv_max_hosts < 0
1685+
log_warn("#{srv_max_hosts} is not a valid integer for srv_max_hosts")
1686+
opts.delete(:srv_max_hosts)
16661687
end
1667-
true
16681688
end
16691689

16701690
# Validates whether the max_connecting option is valid.
@@ -1673,35 +1693,34 @@ def validate_max_min_pool_size!(option, opts)
16731693
# @param [ Hash ] opts The client options.
16741694
#
16751695
# @return [ true ] If the option is valid.
1676-
# @raise [ Error::InvalidMaxConnecting ] If the option is invalid.
1677-
def validate_max_connecting!(option, opts)
1678-
if option == :max_connecting && opts.key?(:max_connecting)
1679-
max_connecting = opts[:max_connecting] || Server::ConnectionPool::DEFAULT_MAX_CONNECTING
1680-
if max_connecting <= 0
1681-
raise Error::InvalidMaxConnecting.new(opts[:max_connecting])
1682-
end
1696+
def validate_max_connecting!(opts)
1697+
return unless opts.key?(:max_connecting)
1698+
1699+
max_connecting = opts[:max_connecting] || Server::ConnectionPool::DEFAULT_MAX_CONNECTING
1700+
if max_connecting <= 0
1701+
opts[:max_connecting] = Server::ConnectionPool::DEFAULT_MAX_CONNECTING
1702+
log_warn("Invalid max_connecting: #{max_connecting}. Please ensure that it is greater than zero.")
16831703
end
1684-
true
16851704
end
16861705

1687-
def validate_read!(option, opts)
1688-
if option == :read && opts.has_key?(:read)
1689-
read = opts[:read]
1690-
# We could check if read is a Hash, but this would fail
1691-
# for custom classes implementing key access ([]).
1692-
# Instead reject common cases of strings and symbols.
1693-
if read.is_a?(String) || read.is_a?(Symbol)
1694-
raise Error::InvalidReadOption.new(read, "the read preference must be specified as a hash: { mode: #{read.inspect} }")
1695-
end
1706+
def validate_read!(opts)
1707+
return unless opts.has_key?(:read)
16961708

1697-
if mode = read[:mode]
1698-
mode = mode.to_sym
1699-
unless Mongo::ServerSelector::PREFERENCES.include?(mode)
1700-
raise Error::InvalidReadOption.new(read, "mode #{mode} is not one of recognized modes")
1701-
end
1709+
read = opts[:read]
1710+
1711+
# We could check if read is a Hash, but this would fail
1712+
# for custom classes implementing key access ([]).
1713+
# Instead reject common cases of strings and symbols.
1714+
if read.is_a?(String) || read.is_a?(Symbol)
1715+
raise Error::InvalidReadOption.new(read, "the read preference must be specified as a hash: { mode: #{read.inspect} }")
1716+
end
1717+
1718+
if mode = read[:mode]
1719+
mode = mode.to_sym
1720+
unless Mongo::ServerSelector::PREFERENCES.include?(mode)
1721+
raise Error::InvalidReadOption.new(read, "mode #{mode} is not one of recognized modes")
17021722
end
17031723
end
1704-
true
17051724
end
17061725

17071726
def assert_not_closed

Diff for: lib/mongo/uri.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -505,17 +505,17 @@ def validate_uri_options!
505505
end
506506

507507
unless uri_options[:ssl_verify_hostname].nil?
508-
raise_invalid_error_no_fmt!("tlsInsecure' and 'tlsAllowInvalidHostnames' cannot both be specified")
508+
raise_invalid_error_no_fmt!("'tlsInsecure' and 'tlsAllowInvalidHostnames' cannot both be specified")
509509
end
510510

511511
unless uri_options[:ssl_verify_ocsp_endpoint].nil?
512-
raise_invalid_error_no_fmt!("tlsInsecure' and 'tlsDisableOCSPEndpointCheck' cannot both be specified")
512+
raise_invalid_error_no_fmt!("'tlsInsecure' and 'tlsDisableOCSPEndpointCheck' cannot both be specified")
513513
end
514514
end
515515

516516
unless uri_options[:ssl_verify_certificate].nil?
517517
unless uri_options[:ssl_verify_ocsp_endpoint].nil?
518-
raise_invalid_error_no_fmt!("tlsAllowInvalidCertificates' and 'tlsDisableOCSPEndpointCheck' cannot both be specified")
518+
raise_invalid_error_no_fmt!("'tlsAllowInvalidCertificates' and 'tlsDisableOCSPEndpointCheck' cannot both be specified")
519519
end
520520
end
521521

Diff for: lib/mongo/uri/options_mapper.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def initialize(**opts)
6262
def add_uri_option(key, value, uri_options)
6363
strategy = URI_OPTION_MAP[key.downcase]
6464
if strategy.nil?
65-
log_warn("Unsupported URI option '#{key}' on URI '#{@string}'. It will be ignored.")
65+
warn_unsupported_option(key, @string)
6666
return
6767
end
6868

@@ -91,7 +91,7 @@ def smc_to_ruby(opts)
9191
opts.each do |key, value|
9292
strategy = URI_OPTION_MAP[key.downcase]
9393
if strategy.nil?
94-
log_warn("Unsupported URI option '#{key}' on URI '#{@string}'. It will be ignored.")
94+
warn_unsupported_option(key, @string)
9595
return
9696
end
9797

@@ -206,6 +206,10 @@ def ruby_to_string(opts)
206206

207207
private
208208

209+
def warn_unsupported_option(key, uri)
210+
log_warn("Unsupported URI option '#{key}' on URI '#{uri}'. It will be ignored.")
211+
end
212+
209213
# Applies URI value transformation by either using the default cast
210214
# or a transformation appropriate for the given type.
211215
#

Diff for: spec/spec_tests/data/uri_options/auth-options.yml

+3-27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
tests:
22
-
33
description: "Valid auth options are parsed correctly (GSSAPI)"
4-
uri: "mongodb://foo:[email protected]/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true&authSource=$external"
4+
uri: "mongodb://foo:[email protected]/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:forward,SERVICE_HOST:example.com&authSource=$external"
55
valid: true
66
warning: false
77
hosts: ~
@@ -10,32 +10,8 @@ tests:
1010
authMechanism: "GSSAPI"
1111
authMechanismProperties:
1212
SERVICE_NAME: "other"
13-
CANONICALIZE_HOST_NAME: true
14-
authSource: "$external"
15-
-
16-
description: "Mixed case in auth mechanism properties is preserved"
17-
uri: "mongodb://foo:[email protected]/?authMechanism=GSSAPI&authMechanismProperties=PropertyName:PropertyValue&authSource=$external"
18-
valid: true
19-
warning: false
20-
hosts: ~
21-
auth: ~
22-
options:
23-
authMechanism: "GSSAPI"
24-
authMechanismProperties:
25-
PropertyName: PropertyValue
26-
service_name: mongodb
27-
authSource: "$external"
28-
-
29-
description: "Auth mechanism properties are all invalid"
30-
uri: "mongodb://foo:[email protected]/?authMechanism=GSSAPI&authMechanismProperties=PropertyName&authSource=$external"
31-
valid: true
32-
warning: true
33-
hosts: ~
34-
auth: ~
35-
options:
36-
authMechanism: "GSSAPI"
37-
authMechanismProperties:
38-
service_name: mongodb
13+
SERVICE_HOST: "example.com"
14+
CANONICALIZE_HOST_NAME: "forward"
3915
authSource: "$external"
4016
-
4117
description: "Valid auth options are parsed correctly (SCRAM-SHA-1)"

Diff for: spec/spec_tests/data/uri_options/compression-options.yml

+1-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tests:
77
hosts: ~
88
auth: ~
99
options:
10-
compressors:
10+
compressors:
1111
- "zlib"
1212
zlibCompressionLevel: 9
1313
-
@@ -28,7 +28,6 @@ tests:
2828
warning: true
2929
hosts: ~
3030
auth: ~
31-
# https://jira.mongodb.org/browse/DRIVERS-1368
3231
options: ~
3332
-
3433
description: "Too low zlibCompressionLevel causes a warning"
@@ -37,7 +36,6 @@ tests:
3736
warning: true
3837
hosts: ~
3938
auth: ~
40-
# https://jira.mongodb.org/browse/DRIVERS-1368
4139
options: ~
4240
-
4341
description: "Too high zlibCompressionLevel causes a warning"
@@ -46,6 +44,5 @@ tests:
4644
warning: true
4745
hosts: ~
4846
auth: ~
49-
# https://jira.mongodb.org/browse/DRIVERS-1368
5047
options: ~
5148

0 commit comments

Comments
 (0)