mongo 1.10.0.rc0 → 1.10.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/VERSION +1 -1
- data/lib/mongo/bulk_write_collection_view.rb +31 -3
- data/lib/mongo/collection.rb +69 -25
- data/lib/mongo/collection_writer.rb +3 -2
- data/lib/mongo/connection/node.rb +5 -0
- data/lib/mongo/cursor.rb +4 -1
- data/lib/mongo/db.rb +23 -41
- data/lib/mongo/functional.rb +2 -0
- data/lib/mongo/functional/authentication.rb +18 -3
- data/lib/mongo/functional/sasl_java.rb +48 -0
- data/lib/mongo/functional/uri_parser.rb +62 -50
- data/lib/mongo/mongo_client.rb +24 -9
- data/lib/mongo/mongo_replica_set_client.rb +16 -5
- data/lib/mongo/networking.rb +3 -3
- data/lib/mongo/utils/conversions.rb +2 -1
- data/test/functional/authentication_test.rb +6 -1
- data/test/functional/bulk_api_stress_test.rb +133 -0
- data/test/functional/bulk_write_collection_view_test.rb +573 -226
- data/test/functional/client_test.rb +3 -1
- data/test/functional/collection_test.rb +336 -17
- data/test/functional/conversions_test.rb +32 -0
- data/test/functional/cursor_test.rb +3 -3
- data/test/functional/db_api_test.rb +2 -2
- data/test/functional/db_test.rb +24 -0
- data/test/functional/uri_test.rb +49 -32
- data/test/helpers/test_unit.rb +8 -0
- data/test/replica_set/authentication_test.rb +5 -1
- data/test/replica_set/client_test.rb +5 -4
- data/test/replica_set/max_values_test.rb +6 -0
- data/test/shared/authentication/basic_auth_shared.rb +101 -30
- data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
- data/test/shared/authentication/gssapi_shared.rb +164 -0
- data/test/shared/ssl_shared.rb +49 -27
- data/test/unit/client_test.rb +4 -2
- data/test/unit/connection_test.rb +4 -2
- data/test/unit/cursor_test.rb +12 -0
- data/test/unit/db_test.rb +6 -0
- metadata +27 -20
- metadata.gz.sig +0 -0
data/lib/mongo/functional.rb
CHANGED
@@ -19,6 +19,7 @@ module Mongo
|
|
19
19
|
|
20
20
|
DEFAULT_MECHANISM = 'MONGODB-CR'
|
21
21
|
MECHANISMS = ['GSSAPI', 'MONGODB-CR', 'MONGODB-X509', 'PLAIN']
|
22
|
+
EXTRA = { 'GSSAPI' => [:gssapi_service_name, :canonicalize_host_name] }
|
22
23
|
|
23
24
|
# authentication module methods
|
24
25
|
class << self
|
@@ -59,6 +60,15 @@ module Mongo
|
|
59
60
|
"When using the authentication mechanism #{auth[:mechanism]} " +
|
60
61
|
"both username and password are required."
|
61
62
|
end
|
63
|
+
# if extra opts exist, validate them
|
64
|
+
allowed_keys = EXTRA[auth[:mechanism]]
|
65
|
+
if auth[:extra] && !auth[:extra].empty?
|
66
|
+
invalid_opts = []
|
67
|
+
auth[:extra].keys.each { |k| invalid_opts << k unless allowed_keys.include?(k) }
|
68
|
+
raise MongoArgumentError,
|
69
|
+
"Invalid extra option(s): #{invalid_opts} found. Please check the extra options" +
|
70
|
+
" passed and try again." unless invalid_opts.empty?
|
71
|
+
end
|
62
72
|
auth
|
63
73
|
end
|
64
74
|
|
@@ -95,19 +105,22 @@ module Mongo
|
|
95
105
|
# (if different than the current database).
|
96
106
|
# @param mechanism [String] (nil) The authentication mechanism being used
|
97
107
|
# (default: 'MONGODB-CR').
|
108
|
+
# @param extra [Hash] (nil) A optional hash of extra options to be stored with
|
109
|
+
# the credential set.
|
98
110
|
#
|
99
111
|
# @raise [MongoArgumentError] Raised if the database has already been used
|
100
112
|
# for authentication. A log out is required before additional auths can
|
101
113
|
# be issued against a given database.
|
102
114
|
# @raise [AuthenticationError] Raised if authentication fails.
|
103
115
|
# @return [Hash] a hash representing the authentication just added.
|
104
|
-
def add_auth(db_name, username, password=nil, source=nil, mechanism=nil)
|
116
|
+
def add_auth(db_name, username, password=nil, source=nil, mechanism=nil, extra=nil)
|
105
117
|
auth = Authentication.validate_credentials({
|
106
118
|
:db_name => db_name,
|
107
119
|
:username => username,
|
108
120
|
:password => password,
|
109
121
|
:source => source,
|
110
|
-
:mechanism => mechanism
|
122
|
+
:mechanism => mechanism,
|
123
|
+
:extra => extra
|
111
124
|
})
|
112
125
|
|
113
126
|
if @auths.any? {|a| a[:source] == auth[:source]}
|
@@ -276,7 +289,9 @@ module Mongo
|
|
276
289
|
# @private
|
277
290
|
def issue_gssapi(auth, opts={})
|
278
291
|
raise NotImplementedError,
|
279
|
-
|
292
|
+
"The #{auth[:mechanism]} authentication mechanism is only supported " +
|
293
|
+
"for JRuby." unless RUBY_PLATFORM =~ /java/
|
294
|
+
Mongo::Sasl::GSSAPI.authenticate(auth[:username], self, opts[:socket], auth[:extra] || {})
|
280
295
|
end
|
281
296
|
|
282
297
|
# Helper to fetch a nonce value from a given database instance.
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'jruby'
|
16
|
+
|
17
|
+
include Java
|
18
|
+
|
19
|
+
jar_dir = File.join(File.dirname(__FILE__), '../../../ext/jsasl')
|
20
|
+
require File.join(jar_dir, 'target/jsasl.jar')
|
21
|
+
|
22
|
+
module Mongo
|
23
|
+
module Sasl
|
24
|
+
|
25
|
+
module GSSAPI
|
26
|
+
|
27
|
+
def self.authenticate(username, client, socket, opts={})
|
28
|
+
db = client.db('$external')
|
29
|
+
hostname = socket.pool.host
|
30
|
+
servicename = opts[:gssapi_service_name] || 'mongodb'
|
31
|
+
canonicalize = opts[:canonicalize_host_name] ? opts[:canonicalize_host_name] : false
|
32
|
+
|
33
|
+
authenticator = org.mongodb.sasl.GSSAPIAuthenticator.new(JRuby.runtime, username, hostname, servicename, canonicalize)
|
34
|
+
token = BSON::Binary.new(authenticator.initialize_challenge)
|
35
|
+
cmd = BSON::OrderedHash['saslStart', 1, 'mechanism', 'GSSAPI', 'payload', token, 'autoAuthorize', 1]
|
36
|
+
response = db.command(cmd, :check_response => false, :socket => socket)
|
37
|
+
|
38
|
+
until response['done'] do
|
39
|
+
token = BSON::Binary.new(authenticator.evaluate_challenge(response['payload'].to_s))
|
40
|
+
cmd = BSON::OrderedHash['saslContinue', 1, 'conversationId', response['conversationId'], 'payload', token]
|
41
|
+
response = db.command(cmd, :check_response => false, :socket => socket)
|
42
|
+
end
|
43
|
+
response
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -42,9 +42,11 @@ module Mongo
|
|
42
42
|
OPT_ATTRS = [
|
43
43
|
:authmechanism,
|
44
44
|
:authsource,
|
45
|
+
:canonicalizehostname,
|
45
46
|
:connect,
|
46
47
|
:connecttimeoutms,
|
47
48
|
:fsync,
|
49
|
+
:gssapiservicename,
|
48
50
|
:journal,
|
49
51
|
:pool_size,
|
50
52
|
:readpreference,
|
@@ -59,71 +61,79 @@ module Mongo
|
|
59
61
|
]
|
60
62
|
|
61
63
|
OPT_VALID = {
|
62
|
-
:authmechanism
|
63
|
-
:authsource
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
75
|
-
:
|
76
|
-
:
|
77
|
-
:
|
64
|
+
:authmechanism => lambda { |arg| Mongo::Authentication.validate_mechanism(arg) },
|
65
|
+
:authsource => lambda { |arg| arg.length > 0 },
|
66
|
+
:canonicalizehostname => lambda { |arg| ['true', 'false'].include?(arg) },
|
67
|
+
:connect => lambda { |arg| [ 'direct', 'replicaset', 'true', 'false', true, false ].include?(arg) },
|
68
|
+
:connecttimeoutms => lambda { |arg| arg =~ /^\d+$/ },
|
69
|
+
:fsync => lambda { |arg| ['true', 'false'].include?(arg) },
|
70
|
+
:gssapiservicename => lambda { |arg| arg.length > 0 },
|
71
|
+
:journal => lambda { |arg| ['true', 'false'].include?(arg) },
|
72
|
+
:pool_size => lambda { |arg| arg.to_i > 0 },
|
73
|
+
:readpreference => lambda { |arg| READ_PREFERENCES.keys.include?(arg) },
|
74
|
+
:replicaset => lambda { |arg| arg.length > 0 },
|
75
|
+
:safe => lambda { |arg| ['true', 'false'].include?(arg) },
|
76
|
+
:slaveok => lambda { |arg| ['true', 'false'].include?(arg) },
|
77
|
+
:sockettimeoutms => lambda { |arg| arg =~ /^\d+$/ },
|
78
|
+
:ssl => lambda { |arg| ['true', 'false'].include?(arg) },
|
79
|
+
:w => lambda { |arg| arg =~ /^\w+$/ },
|
80
|
+
:wtimeout => lambda { |arg| arg =~ /^\d+$/ },
|
81
|
+
:wtimeoutms => lambda { |arg| arg =~ /^\d+$/ }
|
78
82
|
}
|
79
83
|
|
80
84
|
OPT_ERR = {
|
81
|
-
:authmechanism
|
82
|
-
:authsource
|
83
|
-
:
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
87
|
-
:
|
88
|
-
:
|
89
|
-
:
|
90
|
-
:
|
91
|
-
:
|
92
|
-
:
|
93
|
-
:
|
94
|
-
:
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
85
|
+
:authmechanism => "must be one of #{Mongo::Authentication::MECHANISMS.join(', ')}",
|
86
|
+
:authsource => "must be a string containing the name of the database being used for authentication",
|
87
|
+
:canonicalizehostname => "must be 'true' or 'false'",
|
88
|
+
:connect => "must be 'direct', 'replicaset', 'true', or 'false'",
|
89
|
+
:connecttimeoutms => "must be an integer specifying milliseconds",
|
90
|
+
:fsync => "must be 'true' or 'false'",
|
91
|
+
:gssapiservicename => "must be a string containing the name of the GSSAPI service",
|
92
|
+
:journal => "must be 'true' or 'false'",
|
93
|
+
:pool_size => "must be an integer greater than zero",
|
94
|
+
:readpreference => "must be on of #{READ_PREFERENCES.keys.map(&:inspect).join(",")}",
|
95
|
+
:replicaset => "must be a string containing the name of the replica set to connect to",
|
96
|
+
:safe => "must be 'true' or 'false'",
|
97
|
+
:slaveok => "must be 'true' or 'false'",
|
98
|
+
:settimeoutms => "must be an integer specifying milliseconds",
|
99
|
+
:ssl => "must be 'true' or 'false'",
|
100
|
+
:w => "must be an integer indicating number of nodes to replicate to or a string " +
|
101
|
+
"specifying that replication is required to the majority or nodes with a " +
|
102
|
+
"particilar getLastErrorMode.",
|
103
|
+
:wtimeout => "must be an integer specifying milliseconds",
|
104
|
+
:wtimeoutms => "must be an integer specifying milliseconds"
|
99
105
|
}
|
100
106
|
|
101
107
|
OPT_CONV = {
|
102
|
-
:authmechanism
|
103
|
-
:authsource
|
104
|
-
:
|
105
|
-
:
|
106
|
-
:
|
107
|
-
:
|
108
|
-
:
|
109
|
-
:
|
110
|
-
:
|
111
|
-
:
|
112
|
-
:
|
113
|
-
:
|
114
|
-
:
|
115
|
-
:
|
116
|
-
:
|
117
|
-
:
|
108
|
+
:authmechanism => lambda { |arg| arg.upcase },
|
109
|
+
:authsource => lambda { |arg| arg },
|
110
|
+
:canonicalizehostname => lambda { |arg| arg == 'true' ? true : false },
|
111
|
+
:connect => lambda { |arg| arg == 'false' ? false : arg }, # convert 'false' to FalseClass
|
112
|
+
:connecttimeoutms => lambda { |arg| arg.to_f / 1000 }, # stored as seconds
|
113
|
+
:fsync => lambda { |arg| arg == 'true' ? true : false },
|
114
|
+
:gssapiservicename => lambda { |arg| arg },
|
115
|
+
:journal => lambda { |arg| arg == 'true' ? true : false },
|
116
|
+
:pool_size => lambda { |arg| arg.to_i },
|
117
|
+
:readpreference => lambda { |arg| READ_PREFERENCES[arg] },
|
118
|
+
:replicaset => lambda { |arg| arg },
|
119
|
+
:safe => lambda { |arg| arg == 'true' ? true : false },
|
120
|
+
:slaveok => lambda { |arg| arg == 'true' ? true : false },
|
121
|
+
:sockettimeoutms => lambda { |arg| arg.to_f / 1000 }, # stored as seconds
|
122
|
+
:ssl => lambda { |arg| arg == 'true' ? true : false },
|
123
|
+
:w => lambda { |arg| Mongo::Support.is_i?(arg) ? arg.to_i : arg.to_sym },
|
124
|
+
:wtimeout => lambda { |arg| arg.to_i },
|
125
|
+
:wtimeoutms => lambda { |arg| arg.to_i }
|
118
126
|
}
|
119
127
|
|
120
128
|
attr_reader :auths,
|
121
129
|
:authmechanism,
|
122
130
|
:authsource,
|
131
|
+
:canonicalizehostname,
|
123
132
|
:connect,
|
124
133
|
:connecttimeoutms,
|
125
134
|
:db_name,
|
126
135
|
:fsync,
|
136
|
+
:gssapiservicename,
|
127
137
|
:journal,
|
128
138
|
:nodes,
|
129
139
|
:pool_size,
|
@@ -318,6 +328,8 @@ module Mongo
|
|
318
328
|
:source => @authsource,
|
319
329
|
:mechanism => @authmechanism
|
320
330
|
})
|
331
|
+
auth[:extra] = @canonicalizehostname ? { :canonicalize_host_name => @canonicalizehostname } : {}
|
332
|
+
auth[:extra].merge!(:gssapi_service_name => @gssapiservicename) if @gssapiservicename
|
321
333
|
@auths << auth
|
322
334
|
end
|
323
335
|
end
|
data/lib/mongo/mongo_client.rb
CHANGED
@@ -33,6 +33,8 @@ module Mongo
|
|
33
33
|
APPEND_HEADROOM = COMMAND_HEADROOM / 2
|
34
34
|
SERIALIZE_HEADROOM = APPEND_HEADROOM / 2
|
35
35
|
|
36
|
+
DEFAULT_MAX_WRITE_BATCH_SIZE = 1000
|
37
|
+
|
36
38
|
Mutex = ::Mutex
|
37
39
|
ConditionVariable = ::ConditionVariable
|
38
40
|
|
@@ -66,7 +68,8 @@ module Mongo
|
|
66
68
|
:acceptable_latency,
|
67
69
|
:read,
|
68
70
|
:max_wire_version,
|
69
|
-
:min_wire_version
|
71
|
+
:min_wire_version,
|
72
|
+
:max_write_batch_size
|
70
73
|
|
71
74
|
# Create a connection to single MongoDB instance.
|
72
75
|
#
|
@@ -87,11 +90,17 @@ module Mongo
|
|
87
90
|
# @param [Integer] port specify a port number here if only one host is being specified.
|
88
91
|
# @param [Hash] opts hash of optional settings and configuration values.
|
89
92
|
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
93
|
+
# @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
|
94
|
+
# should be acknowledged.
|
95
|
+
# @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
|
96
|
+
# @option opts [Boolean] :j (false) If true, block until write operations have been committed
|
97
|
+
# to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
|
98
|
+
# ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
|
99
|
+
# fail with an exception if this option is used when the server is running without journaling.
|
100
|
+
# @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
|
101
|
+
# the server has synced all data files to disk. If the server is running with journaling, this acts the same as
|
102
|
+
# the 'j' option, blocking until write operations have been committed to the journal.
|
103
|
+
# Cannot be used in combination with 'j'.
|
95
104
|
#
|
96
105
|
# Notes about Write-Concern Options:
|
97
106
|
# Write concern options are propagated to objects instantiated from this MongoClient.
|
@@ -101,7 +110,8 @@ module Mongo
|
|
101
110
|
# @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
|
102
111
|
# @option opts [String] :ssl_cert (nil) The certificate file used to identify the local connection against MongoDB.
|
103
112
|
# @option opts [String] :ssl_key (nil) The private keyfile used to identify the local connection against MongoDB.
|
104
|
-
#
|
113
|
+
# Note that even if the key is stored in the same file as the certificate, both need to be explicitly specified.
|
114
|
+
# Additionally, note that the driver does not currently support providing a passphrase for the private key.
|
105
115
|
# @option opts [Boolean] :ssl_verify (nil) Specifies whether or not peer certification validation should occur.
|
106
116
|
# @option opts [String] :ssl_ca_cert (nil) The ca_certs file contains a set of concatenated "certification authority"
|
107
117
|
# certificates, which are used to validate certificates passed from the other end of the connection.
|
@@ -161,6 +171,7 @@ module Mongo
|
|
161
171
|
@max_message_size = nil
|
162
172
|
@max_wire_version = nil
|
163
173
|
@min_wire_version = nil
|
174
|
+
@max_write_batch_size = nil
|
164
175
|
|
165
176
|
check_opts(opts)
|
166
177
|
setup(opts.dup)
|
@@ -231,8 +242,7 @@ module Mongo
|
|
231
242
|
[@host, @port]
|
232
243
|
end
|
233
244
|
|
234
|
-
#
|
235
|
-
# the datafiles in a state safe for snapshotting, backing up, etc.
|
245
|
+
# Flush all pending writes to datafiles.
|
236
246
|
#
|
237
247
|
# @return [BSON::OrderedHash] the command response
|
238
248
|
def lock!
|
@@ -403,6 +413,7 @@ module Mongo
|
|
403
413
|
@max_message_size = config['maxMessageSizeBytes']
|
404
414
|
@max_wire_version = config['maxWireVersion']
|
405
415
|
@min_wire_version = config['minWireVersion']
|
416
|
+
@max_write_batch_size = config['maxWriteBatchSize']
|
406
417
|
check_wire_version_in_range
|
407
418
|
set_primary(host_port)
|
408
419
|
end
|
@@ -482,6 +493,10 @@ module Mongo
|
|
482
493
|
@min_wire_version || 0
|
483
494
|
end
|
484
495
|
|
496
|
+
def max_write_batch_size
|
497
|
+
@max_write_batch_size || DEFAULT_MAX_WRITE_BATCH_SIZE
|
498
|
+
end
|
499
|
+
|
485
500
|
def wire_version_feature?(feature)
|
486
501
|
min_wire_version <= feature && feature <= max_wire_version
|
487
502
|
end
|
@@ -47,10 +47,16 @@ module Mongo
|
|
47
47
|
# @param [Array<String>, Array<Array(String, Integer)>] seeds
|
48
48
|
#
|
49
49
|
# @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
|
50
|
-
# should be acknowledged
|
51
|
-
# @option opts [
|
52
|
-
# @option opts [
|
53
|
-
#
|
50
|
+
# should be acknowledged.
|
51
|
+
# @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
|
52
|
+
# @option opts [Boolean] :j (false) If true, block until write operations have been committed
|
53
|
+
# to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
|
54
|
+
# ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
|
55
|
+
# fail with an exception if this option is used when the server is running without journaling.
|
56
|
+
# @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
|
57
|
+
# the server has synced all data files to disk. If the server is running with journaling, this acts the same as
|
58
|
+
# the 'j' option, blocking until write operations have been committed to the journal.
|
59
|
+
# Cannot be used in combination with 'j'.
|
54
60
|
#
|
55
61
|
# Notes about write concern options:
|
56
62
|
# Write concern options are propagated to objects instantiated from this MongoReplicaSetClient.
|
@@ -85,7 +91,8 @@ module Mongo
|
|
85
91
|
# @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
|
86
92
|
# @option opts [String] :ssl_cert (nil) The certificate file used to identify the local connection against MongoDB.
|
87
93
|
# @option opts [String] :ssl_key (nil) The private keyfile used to identify the local connection against MongoDB.
|
88
|
-
#
|
94
|
+
# Note that even if the key is stored in the same file as the certificate, both need to be explicitly specified.
|
95
|
+
# Additionally, note that the driver does not currently support providing a passphrase for the private key.
|
89
96
|
# @option opts [Boolean] :ssl_verify (nil) Specifies whether or not peer certification validation should occur.
|
90
97
|
# @option opts [String] :ssl_ca_cert (nil) The ca_certs file contains a set of concatenated "certification authority"
|
91
98
|
# certificates, which are used to validate certificates passed from the other end of the connection.
|
@@ -463,6 +470,10 @@ module Mongo
|
|
463
470
|
local_manager && local_manager.primary_pool && local_manager.primary_pool.node.wire_version_feature?(feature)
|
464
471
|
end
|
465
472
|
|
473
|
+
def max_write_batch_size
|
474
|
+
local_manager && local_manager.primary_pool && local_manager.primary_pool.node.max_write_batch_size
|
475
|
+
end
|
476
|
+
|
466
477
|
private
|
467
478
|
|
468
479
|
# Parse option hash
|
data/lib/mongo/networking.rb
CHANGED
@@ -104,9 +104,9 @@ module Mongo
|
|
104
104
|
error = "wtimeout" if error == "timeout"
|
105
105
|
raise OperationFailure.new(code.to_s + ': ' + error, code, docs[0])
|
106
106
|
end
|
107
|
-
elsif num_received == 1 && (
|
108
|
-
code = Mongo::ErrorCode::BAD_VALUE # as of server version 2.5.5
|
109
|
-
raise OperationFailure.new(code.to_s + ': ' +
|
107
|
+
elsif num_received == 1 && (note = docs[0]['jnote'] || docs[0]['wnote']) # assignment
|
108
|
+
code = docs[0]['code'] || Mongo::ErrorCode::BAD_VALUE # as of server version 2.5.5
|
109
|
+
raise OperationFailure.new(code.to_s + ': ' + note, code, docs[0])
|
110
110
|
end
|
111
111
|
|
112
112
|
docs[0]
|
@@ -37,7 +37,7 @@ module Mongo #:nodoc:
|
|
37
37
|
)
|
38
38
|
else
|
39
39
|
order_by = value.inject({}) do |memo, (key, direction)|
|
40
|
-
memo[key.to_s] = sort_value(direction
|
40
|
+
memo[key.to_s] = sort_value(direction)
|
41
41
|
memo
|
42
42
|
end
|
43
43
|
end
|
@@ -97,6 +97,7 @@ module Mongo #:nodoc:
|
|
97
97
|
#
|
98
98
|
# If the value is invalid then an error will be raised.
|
99
99
|
def sort_value(value)
|
100
|
+
return value if value.is_a?(Hash)
|
100
101
|
val = value.to_s.downcase
|
101
102
|
return 1 if ASCENDING_CONVERSION.include?(val)
|
102
103
|
return -1 if DESCENDING_CONVERSION.include?(val)
|
@@ -15,16 +15,21 @@
|
|
15
15
|
require 'test_helper'
|
16
16
|
require 'shared/authentication/basic_auth_shared'
|
17
17
|
require 'shared/authentication/sasl_plain_shared'
|
18
|
+
require 'shared/authentication/bulk_api_auth_shared'
|
19
|
+
require 'shared/authentication/gssapi_shared'
|
20
|
+
|
18
21
|
|
19
22
|
class AuthenticationTest < Test::Unit::TestCase
|
20
23
|
include Mongo
|
21
24
|
include BasicAuthTests
|
22
25
|
include SASLPlainTests
|
26
|
+
include BulkAPIAuthTests
|
27
|
+
include GSSAPITests
|
23
28
|
|
24
29
|
def setup
|
25
30
|
@client = MongoClient.new(TEST_HOST, TEST_PORT)
|
31
|
+
@version = @client.server_version
|
26
32
|
@db = @client[TEST_DB]
|
27
33
|
@host_info = host_port
|
28
|
-
init_auth
|
29
34
|
end
|
30
35
|
end
|