mongo 1.10.0.rc0 → 1.10.0.rc1

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/VERSION +1 -1
  5. data/lib/mongo/bulk_write_collection_view.rb +31 -3
  6. data/lib/mongo/collection.rb +69 -25
  7. data/lib/mongo/collection_writer.rb +3 -2
  8. data/lib/mongo/connection/node.rb +5 -0
  9. data/lib/mongo/cursor.rb +4 -1
  10. data/lib/mongo/db.rb +23 -41
  11. data/lib/mongo/functional.rb +2 -0
  12. data/lib/mongo/functional/authentication.rb +18 -3
  13. data/lib/mongo/functional/sasl_java.rb +48 -0
  14. data/lib/mongo/functional/uri_parser.rb +62 -50
  15. data/lib/mongo/mongo_client.rb +24 -9
  16. data/lib/mongo/mongo_replica_set_client.rb +16 -5
  17. data/lib/mongo/networking.rb +3 -3
  18. data/lib/mongo/utils/conversions.rb +2 -1
  19. data/test/functional/authentication_test.rb +6 -1
  20. data/test/functional/bulk_api_stress_test.rb +133 -0
  21. data/test/functional/bulk_write_collection_view_test.rb +573 -226
  22. data/test/functional/client_test.rb +3 -1
  23. data/test/functional/collection_test.rb +336 -17
  24. data/test/functional/conversions_test.rb +32 -0
  25. data/test/functional/cursor_test.rb +3 -3
  26. data/test/functional/db_api_test.rb +2 -2
  27. data/test/functional/db_test.rb +24 -0
  28. data/test/functional/uri_test.rb +49 -32
  29. data/test/helpers/test_unit.rb +8 -0
  30. data/test/replica_set/authentication_test.rb +5 -1
  31. data/test/replica_set/client_test.rb +5 -4
  32. data/test/replica_set/max_values_test.rb +6 -0
  33. data/test/shared/authentication/basic_auth_shared.rb +101 -30
  34. data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
  35. data/test/shared/authentication/gssapi_shared.rb +164 -0
  36. data/test/shared/ssl_shared.rb +49 -27
  37. data/test/unit/client_test.rb +4 -2
  38. data/test/unit/connection_test.rb +4 -2
  39. data/test/unit/cursor_test.rb +12 -0
  40. data/test/unit/db_test.rb +6 -0
  41. metadata +27 -20
  42. metadata.gz.sig +0 -0
@@ -17,3 +17,5 @@ require 'mongo/functional/logging'
17
17
  require 'mongo/functional/read_preference'
18
18
  require 'mongo/functional/write_concern'
19
19
  require 'mongo/functional/uri_parser'
20
+
21
+ require 'mongo/functional/sasl_java' if RUBY_PLATFORM =~ /java/
@@ -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
- "The #{auth[:mechanism]} authentication mechanism is not yet supported."
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 => lambda { |arg| Mongo::Authentication.validate_mechanism(arg) },
63
- :authsource => lambda { |arg| arg.length > 0 },
64
- :connect => lambda { |arg| [ 'direct', 'replicaset', 'true', 'false', true, false ].include?(arg) },
65
- :connecttimeoutms => lambda { |arg| arg =~ /^\d+$/ },
66
- :fsync => lambda { |arg| ['true', 'false'].include?(arg) },
67
- :journal => lambda { |arg| ['true', 'false'].include?(arg) },
68
- :pool_size => lambda { |arg| arg.to_i > 0 },
69
- :readpreference => lambda { |arg| READ_PREFERENCES.keys.include?(arg) },
70
- :replicaset => lambda { |arg| arg.length > 0 },
71
- :safe => lambda { |arg| ['true', 'false'].include?(arg) },
72
- :slaveok => lambda { |arg| ['true', 'false'].include?(arg) },
73
- :sockettimeoutms => lambda { |arg| arg =~ /^\d+$/ },
74
- :ssl => lambda { |arg| ['true', 'false'].include?(arg) },
75
- :w => lambda { |arg| arg =~ /^\w+$/ },
76
- :wtimeout => lambda { |arg| arg =~ /^\d+$/ },
77
- :wtimeoutms => lambda { |arg| arg =~ /^\d+$/ }
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 => "must be one of #{Mongo::Authentication::MECHANISMS.join(', ')}",
82
- :authsource => "must be a string containing the name of the database being used for authentication",
83
- :connect => "must be 'direct', 'replicaset', 'true', or 'false'",
84
- :connecttimeoutms => "must be an integer specifying milliseconds",
85
- :fsync => "must be 'true' or 'false'",
86
- :journal => "must be 'true' or 'false'",
87
- :pool_size => "must be an integer greater than zero",
88
- :readpreference => "must be on of #{READ_PREFERENCES.keys.map(&:inspect).join(",")}",
89
- :replicaset => "must be a string containing the name of the replica set to connect to",
90
- :safe => "must be 'true' or 'false'",
91
- :slaveok => "must be 'true' or 'false'",
92
- :settimeoutms => "must be an integer specifying milliseconds",
93
- :ssl => "must be 'true' or 'false'",
94
- :w => "must be an integer indicating number of nodes to replicate to or a string " +
95
- "specifying that replication is required to the majority or nodes with a " +
96
- "particilar getLastErrorMode.",
97
- :wtimeout => "must be an integer specifying milliseconds",
98
- :wtimeoutms => "must be an integer specifying milliseconds"
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 => lambda { |arg| arg.upcase },
103
- :authsource => lambda { |arg| arg },
104
- :connect => lambda { |arg| arg == 'false' ? false : arg }, # convert 'false' to FalseClass
105
- :connecttimeoutms => lambda { |arg| arg.to_f / 1000 }, # stored as seconds
106
- :fsync => lambda { |arg| arg == 'true' ? true : false },
107
- :journal => lambda { |arg| arg == 'true' ? true : false },
108
- :pool_size => lambda { |arg| arg.to_i },
109
- :readpreference => lambda { |arg| READ_PREFERENCES[arg] },
110
- :replicaset => lambda { |arg| arg },
111
- :safe => lambda { |arg| arg == 'true' ? true : false },
112
- :slaveok => lambda { |arg| arg == 'true' ? true : false },
113
- :sockettimeoutms => lambda { |arg| arg.to_f / 1000 }, # stored as seconds
114
- :ssl => lambda { |arg| arg == 'true' ? true : false },
115
- :w => lambda { |arg| Mongo::Support.is_i?(arg) ? arg.to_i : arg.to_sym },
116
- :wtimeout => lambda { |arg| arg.to_i },
117
- :wtimeoutms => lambda { |arg| arg.to_i }
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
@@ -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
- # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
91
- # should be acknowledged
92
- # @option opts [Boolean] :j (false) Set journal acknowledgement
93
- # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
94
- # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
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
- # If included with the :ssl_cert then only :ssl_cert is needed.
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
- # Fsync, then lock the mongod process against writes. Use this to get
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 [Boolean] :j (false) Set journal acknowledgement
52
- # @option opts [Integer] :wtimeout (nil) Set acknowledgement timeout
53
- # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
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
- # If included with the :ssl_cert then only :ssl_cert is needed.
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
@@ -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 && (jnote = docs[0]['jnote']) # assignment
108
- code = Mongo::ErrorCode::BAD_VALUE # as of server version 2.5.5
109
- raise OperationFailure.new(code.to_s + ': ' + jnote, code, docs[0])
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.to_s.downcase)
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