mongo 2.11.0 → 2.11.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +24 -0
  5. data/lib/mongo/address.rb +53 -37
  6. data/lib/mongo/auth.rb +30 -10
  7. data/lib/mongo/auth/cr.rb +1 -0
  8. data/lib/mongo/auth/cr/conversation.rb +13 -13
  9. data/lib/mongo/auth/ldap.rb +2 -1
  10. data/lib/mongo/auth/ldap/conversation.rb +9 -12
  11. data/lib/mongo/auth/scram.rb +1 -0
  12. data/lib/mongo/auth/scram/conversation.rb +36 -27
  13. data/lib/mongo/auth/user.rb +7 -1
  14. data/lib/mongo/auth/x509.rb +2 -1
  15. data/lib/mongo/auth/x509/conversation.rb +9 -9
  16. data/lib/mongo/bulk_write/transformable.rb +3 -3
  17. data/lib/mongo/client.rb +17 -6
  18. data/lib/mongo/cluster.rb +67 -49
  19. data/lib/mongo/cluster/sdam_flow.rb +87 -3
  20. data/lib/mongo/collection/view/readable.rb +3 -1
  21. data/lib/mongo/collection/view/writable.rb +3 -3
  22. data/lib/mongo/cursor/builder/kill_cursors_command.rb +8 -1
  23. data/lib/mongo/cursor/builder/op_kill_cursors.rb +8 -1
  24. data/lib/mongo/database.rb +1 -1
  25. data/lib/mongo/grid/file.rb +5 -0
  26. data/lib/mongo/grid/file/chunk.rb +2 -0
  27. data/lib/mongo/grid/fs_bucket.rb +15 -13
  28. data/lib/mongo/grid/stream/write.rb +9 -3
  29. data/lib/mongo/protocol/serializers.rb +12 -2
  30. data/lib/mongo/retryable.rb +33 -8
  31. data/lib/mongo/server.rb +13 -6
  32. data/lib/mongo/server/connection.rb +15 -8
  33. data/lib/mongo/server/connection_base.rb +7 -4
  34. data/lib/mongo/server/description.rb +34 -21
  35. data/lib/mongo/server/monitor.rb +1 -1
  36. data/lib/mongo/server/monitor/connection.rb +2 -3
  37. data/lib/mongo/session.rb +10 -10
  38. data/lib/mongo/socket.rb +10 -1
  39. data/lib/mongo/uri.rb +1 -1
  40. data/lib/mongo/version.rb +1 -1
  41. data/mongo.gemspec +1 -1
  42. data/spec/README.md +13 -0
  43. data/spec/integration/auth_spec.rb +27 -8
  44. data/spec/integration/bson_symbol_spec.rb +34 -0
  45. data/spec/integration/client_construction_spec.rb +14 -0
  46. data/spec/integration/client_options_spec.rb +5 -5
  47. data/spec/integration/connection_spec.rb +57 -9
  48. data/spec/integration/crud_spec.rb +45 -0
  49. data/spec/integration/cursor_reaping_spec.rb +2 -1
  50. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  51. data/spec/integration/retryable_errors_spec.rb +204 -39
  52. data/spec/integration/retryable_writes_spec.rb +36 -36
  53. data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +98 -0
  54. data/spec/lite_spec_helper.rb +1 -0
  55. data/spec/mongo/address_spec.rb +19 -13
  56. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  57. data/spec/mongo/auth/scram/conversation_spec.rb +25 -14
  58. data/spec/mongo/auth/user/view_spec.rb +36 -1
  59. data/spec/mongo/auth/user_spec.rb +12 -0
  60. data/spec/mongo/auth/x509/conversation_spec.rb +1 -1
  61. data/spec/mongo/bulk_write_spec.rb +2 -2
  62. data/spec/mongo/client_construction_spec.rb +1 -21
  63. data/spec/mongo/cluster_spec.rb +57 -0
  64. data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
  65. data/spec/mongo/collection_spec.rb +26 -2
  66. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +56 -0
  67. data/spec/mongo/server/connection_spec.rb +76 -8
  68. data/spec/mongo/server/monitor/connection_spec.rb +14 -7
  69. data/spec/mongo/socket/ssl_spec.rb +132 -98
  70. data/spec/mongo/socket/tcp_spec.rb +1 -9
  71. data/spec/mongo/uri_spec.rb +1 -1
  72. data/spec/runners/sdam/verifier.rb +91 -0
  73. data/spec/spec_tests/data/sdam/rs/primary_address_change.yml +29 -0
  74. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me.yml +27 -23
  75. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +56 -79
  76. data/spec/spec_tests/data/sdam/sharded/primary_address_change.yml +21 -0
  77. data/spec/spec_tests/data/sdam/sharded/primary_mismatched_me.yml +22 -0
  78. data/spec/spec_tests/data/sdam/single/primary_address_change.yml +24 -0
  79. data/spec/spec_tests/data/sdam/single/primary_mismatched_me.yml +25 -0
  80. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +159 -0
  81. data/spec/spec_tests/data/sdam_monitoring/{replica_set_other_seed.yml → replica_set_with_primary_change.yml} +97 -101
  82. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary_removal.yml +22 -18
  83. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +90 -0
  84. data/spec/spec_tests/sdam_monitoring_spec.rb +9 -4
  85. data/spec/support/cluster_config.rb +36 -0
  86. data/spec/support/cluster_tools.rb +5 -3
  87. data/spec/support/command_monitoring.rb +1 -1
  88. data/spec/support/constraints.rb +18 -18
  89. data/spec/support/lite_constraints.rb +8 -0
  90. data/spec/support/sdam_monitoring.rb +0 -115
  91. data/spec/support/server_discovery_and_monitoring.rb +2 -0
  92. data/spec/support/spec_config.rb +1 -1
  93. data/spec/support/utils.rb +11 -1
  94. metadata +687 -659
  95. metadata.gz.sig +3 -2
@@ -29,12 +29,15 @@ module Mongo
29
29
  # @return [ Hash ] options The passed in options.
30
30
  attr_reader :options
31
31
 
32
+ # @return [ Server ] The server that this connection is for.
33
+ #
34
+ # @api private
35
+ attr_reader :server
36
+
32
37
  # @return [ Mongo::Address ] address The address to connect to.
33
- def address
34
- @server.address
35
- end
38
+ def_delegators :server, :address
36
39
 
37
- def_delegators :@server,
40
+ def_delegators :server,
38
41
  :features,
39
42
  :max_bson_object_size,
40
43
  :max_message_size,
@@ -33,6 +33,7 @@ module Mongo
33
33
  # Constant for reading arbiter info from config.
34
34
  #
35
35
  # @since 2.0.0
36
+ # @deprecated
36
37
  ARBITER = 'arbiterOnly'.freeze
37
38
 
38
39
  # Constant for reading arbiters info from config.
@@ -53,16 +54,19 @@ module Mongo
53
54
  # Constant for the key for the message value.
54
55
  #
55
56
  # @since 2.0.0
57
+ # @deprecated
56
58
  MESSAGE = 'msg'.freeze
57
59
 
58
60
  # Constant for the message that indicates a sharded cluster.
59
61
  #
60
62
  # @since 2.0.0
63
+ # @deprecated
61
64
  MONGOS_MESSAGE = 'isdbgrid'.freeze
62
65
 
63
66
  # Constant for determining ghost servers.
64
67
  #
65
68
  # @since 2.0.0
69
+ # @deprecated
66
70
  REPLICA_SET = 'isreplicaset'.freeze
67
71
 
68
72
  # Constant for reading max bson size info from config.
@@ -129,6 +133,7 @@ module Mongo
129
133
  # Constant for reading primary info from config.
130
134
  #
131
135
  # @since 2.0.0
136
+ # @deprecated
132
137
  PRIMARY = 'ismaster'.freeze
133
138
 
134
139
  # Constant for reading primary host field from config.
@@ -139,6 +144,7 @@ module Mongo
139
144
  # Constant for reading secondary info from config.
140
145
  #
141
146
  # @since 2.0.0
147
+ # @deprecated
142
148
  SECONDARY = 'secondary'.freeze
143
149
 
144
150
  # Constant for reading replica set name info from config.
@@ -227,7 +233,7 @@ module Mongo
227
233
  # @return [ Float ] The moving average time the ismaster call took to complete.
228
234
  attr_reader :average_round_trip_time
229
235
 
230
- # Will return true if the server is an arbiter.
236
+ # Returns whether this server is an arbiter, per the SDAM spec.
231
237
  #
232
238
  # @example Is the server an arbiter?
233
239
  # description.arbiter?
@@ -236,7 +242,9 @@ module Mongo
236
242
  #
237
243
  # @since 2.0.0
238
244
  def arbiter?
239
- ok? && !!config[ARBITER] && !replica_set_name.nil?
245
+ ok? &&
246
+ config['arbiterOnly'] == true &&
247
+ !!config['setName']
240
248
  end
241
249
 
242
250
  # Get a list of all arbiters in the replica set.
@@ -251,7 +259,7 @@ module Mongo
251
259
  @arbiters ||= (config[ARBITERS] || []).map { |s| s.downcase }
252
260
  end
253
261
 
254
- # Is the server a ghost in a replica set?
262
+ # Whether this server is a ghost, per the SDAM spec.
255
263
  #
256
264
  # @example Is the server a ghost?
257
265
  # description.ghost?
@@ -260,7 +268,8 @@ module Mongo
260
268
  #
261
269
  # @since 2.0.0
262
270
  def ghost?
263
- ok? && !!config[REPLICA_SET]
271
+ ok? &&
272
+ config['isreplicaset'] == true
264
273
  end
265
274
 
266
275
  # Will return true if the server is hidden.
@@ -431,7 +440,7 @@ module Mongo
431
440
  config[LOGICAL_SESSION_TIMEOUT_MINUTES] if config[LOGICAL_SESSION_TIMEOUT_MINUTES]
432
441
  end
433
442
 
434
- # Is the server a mongos?
443
+ # Returns whether this server is a mongos, per the SDAM spec.
435
444
  #
436
445
  # @example Is the server a mongos?
437
446
  # description.mongos?
@@ -440,10 +449,10 @@ module Mongo
440
449
  #
441
450
  # @since 2.0.0
442
451
  def mongos?
443
- ok? && config[MESSAGE] == MONGOS_MESSAGE
452
+ ok? && config['msg'] == 'isdbgrid'
444
453
  end
445
454
 
446
- # Is the description of type other.
455
+ # Returns whether the server is an other, per the SDAM spec.
447
456
  #
448
457
  # @example Is the description of type other.
449
458
  # description.other?
@@ -455,11 +464,11 @@ module Mongo
455
464
  # The SDAM spec is slightly confusing on what "other" means,
456
465
  # but it's referred to it as "RSOther" which means a non-RS member
457
466
  # cannot be "other".
458
- if unknown? || replica_set_name.nil?
459
- return false
460
- end
461
- (!primary? && !secondary? && !passive? && !arbiter?) ||
462
- (hidden? && !replica_set_name.nil?)
467
+ ok? &&
468
+ !!config['setName'] && (
469
+ config['hidden'] == true ||
470
+ !primary? && !secondary? && !arbiter?
471
+ )
463
472
  end
464
473
 
465
474
  # Will return true if the server is passive.
@@ -498,7 +507,7 @@ module Mongo
498
507
  config[PRIMARY_HOST] && config[PRIMARY_HOST].downcase
499
508
  end
500
509
 
501
- # Will return true if the server is a primary.
510
+ # Returns whether this server is a primary, per the SDAM spec.
502
511
  #
503
512
  # @example Is the server a primary?
504
513
  # description.primary?
@@ -508,9 +517,8 @@ module Mongo
508
517
  # @since 2.0.0
509
518
  def primary?
510
519
  ok? &&
511
- !!config[PRIMARY] &&
512
- (primary_host.nil? || primary_host == address.to_s) &&
513
- !replica_set_name.nil?
520
+ config['ismaster'] == true &&
521
+ !!config['setName']
514
522
  end
515
523
 
516
524
  # Get the name of the replica set the server belongs to, returns nil if
@@ -538,7 +546,7 @@ module Mongo
538
546
  hosts + arbiters + passives
539
547
  end
540
548
 
541
- # Will return true if the server is a secondary.
549
+ # Returns whether this server is a secondary, per the SDAM spec.
542
550
  #
543
551
  # @example Is the server a secondary?
544
552
  # description.secondary?
@@ -547,7 +555,9 @@ module Mongo
547
555
  #
548
556
  # @since 2.0.0
549
557
  def secondary?
550
- ok? && !!config[SECONDARY] && !replica_set_name.nil?
558
+ ok? &&
559
+ config['secondary'] == true &&
560
+ !!config['setName']
551
561
  end
552
562
 
553
563
  # Returns the server type as a symbol.
@@ -569,7 +579,7 @@ module Mongo
569
579
  :unknown
570
580
  end
571
581
 
572
- # Is this server a standalone server?
582
+ # Returns whether this server is a standalone, per the SDAM spec.
573
583
  #
574
584
  # @example Is the server standalone?
575
585
  # description.standalone?
@@ -578,10 +588,13 @@ module Mongo
578
588
  #
579
589
  # @since 2.0.0
580
590
  def standalone?
581
- replica_set_name.nil? && !mongos? && !ghost? && !unknown?
591
+ ok? &&
592
+ config['msg'] != 'isdbgrid' &&
593
+ config['setName'].nil? &&
594
+ config['isreplicaset'] != true
582
595
  end
583
596
 
584
- # Is the server description currently unknown?
597
+ # Returns whether this server is an unknown, per the SDAM spec.
585
598
  #
586
599
  # @example Is the server description unknown?
587
600
  # description.unknown?
@@ -204,7 +204,7 @@ module Mongo
204
204
  connection.ismaster
205
205
  end
206
206
  if exc
207
- log_debug("Error running ismaster on #{server.address}: #{exc.class}: #{exc.message}")
207
+ log_debug("Error running ismaster on #{server.address}: #{exc.class}: #{exc}:\n#{exc.backtrace[0..5].join("\n")}")
208
208
  if monitoring.monitoring?
209
209
  monitoring.failed(
210
210
  Monitoring::SERVER_HEARTBEAT,
@@ -162,8 +162,7 @@ module Mongo
162
162
  # @since 2.0.0
163
163
  def connect!
164
164
  unless @socket
165
- socket = address.socket(socket_timeout, ssl_options,
166
- connect_timeout: address.connect_timeout)
165
+ socket = address.socket(socket_timeout, ssl_options, address.options)
167
166
  handshake!(socket)
168
167
  @socket = socket
169
168
  end
@@ -232,7 +231,7 @@ module Mongo
232
231
  log_warn("Asked to handshake with #{address} but there was no app metadata provided")
233
232
  end
234
233
  rescue => e
235
- log_warn("Failed to handshake with #{address}: #{e.class}: #{e}")
234
+ log_warn("Failed to handshake with #{address}: #{e.class}: #{e}:\n#{e.backtrace[0..5].join("\n")}")
236
235
  raise
237
236
  end
238
237
 
@@ -881,21 +881,21 @@ module Mongo
881
881
  end
882
882
  end
883
883
 
884
- # Validate the session.
884
+ # Validate the session for use by the specified client.
885
885
  #
886
- # @example
887
- # session.validate!(cluster)
886
+ # The session must not be ended and must have been created by a client
887
+ # with the same cluster as the client that the session is to be used with.
888
888
  #
889
- # @param [ Cluster ] cluster The cluster the session is attempted to be used with.
889
+ # @param [ Client ] client The client the session is to be used with.
890
890
  #
891
- # @return [ nil ] nil if the session is valid.
891
+ # @return [ Session ] self, if the session is valid.
892
892
  #
893
- # @raise [ Mongo::Error::InvalidSession ] Raise error if the session is not valid.
893
+ # @raise [ Mongo::Error::InvalidSession ] Exception raised if the session is not valid.
894
894
  #
895
895
  # @since 2.5.0
896
896
  # @api private
897
- def validate!(cluster)
898
- check_matching_cluster!(cluster)
897
+ def validate!(client)
898
+ check_matching_cluster!(client)
899
899
  check_if_ended!
900
900
  self
901
901
  end
@@ -1041,8 +1041,8 @@ module Mongo
1041
1041
  raise Mongo::Error::InvalidSession.new(SESSION_ENDED_ERROR_MSG) if ended?
1042
1042
  end
1043
1043
 
1044
- def check_matching_cluster!(cluster)
1045
- if @client.cluster != cluster
1044
+ def check_matching_cluster!(client)
1045
+ if @client.cluster != client.cluster
1046
1046
  raise Mongo::Error::InvalidSession.new(MISMATCHED_CLUSTER_ERROR_MSG)
1047
1047
  end
1048
1048
  end
@@ -63,7 +63,16 @@ module Mongo
63
63
  def alive?
64
64
  sock_arr = [ @socket ]
65
65
  if Kernel::select(sock_arr, nil, sock_arr, 0)
66
- eof?
66
+ # The eof? call is supposed to return immediately since select
67
+ # indicated the socket is readable. However, if @socket is an SSL
68
+ # socket, eof? can block anyway - see RUBY-2140.
69
+ begin
70
+ Timeout.timeout(0.1) do
71
+ eof?
72
+ end
73
+ rescue ::Timeout::Error
74
+ true
75
+ end
67
76
  else
68
77
  true
69
78
  end
@@ -454,7 +454,7 @@ module Mongo
454
454
  end
455
455
 
456
456
  def decode(value)
457
- ::URI.decode(value)
457
+ ::URI::DEFAULT_PARSER.unescape(value)
458
458
  end
459
459
 
460
460
  def encode(value)
@@ -17,5 +17,5 @@ module Mongo
17
17
  # The current version of the driver.
18
18
  #
19
19
  # @since 2.0.0
20
- VERSION = '2.11.0'.freeze
20
+ VERSION = '2.11.5'.freeze
21
21
  end
@@ -40,5 +40,5 @@ Gem::Specification.new do |s|
40
40
 
41
41
  s.required_ruby_version = ">= 2.3"
42
42
 
43
- s.add_dependency 'bson', '>=4.6.0', '<5.0.0'
43
+ s.add_dependency 'bson', '>=4.4.2', '<5.0.0'
44
44
  end
@@ -74,6 +74,19 @@ configuration is needed:
74
74
 
75
75
  rake
76
76
 
77
+ ### Replica Set With Arbiter
78
+
79
+ Some tests require an arbiter to be present in the replica set. Such a
80
+ deployment can be obtained by providing `--arbiter` argument to mlaunch:
81
+
82
+ mlaunch init --replicaset --arbiter --name ruby-driver-rs \
83
+ --dir /tmp/mdb-rs --setParameter enableTestCommands=1
84
+
85
+ To indicate to the test suite that the deployment contains an arbiter, set
86
+ HAVE_ARBITER environment variable as follows:
87
+
88
+ HAVE_ARBITER=1 rake
89
+
77
90
  ### Sharded Cluster
78
91
 
79
92
  A sharded cluster can be configured with mlaunch:
@@ -41,7 +41,7 @@ describe 'Auth' do
41
41
  it 'indicates scram-sha-1 was used' do
42
42
  expect do
43
43
  connection.connect!
44
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-1\)/)
44
+ end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*used mechanism: SCRAM-SHA-1/)
45
45
  end
46
46
  end
47
47
 
@@ -53,7 +53,7 @@ describe 'Auth' do
53
53
  it 'indicates scram-sha-1 was used' do
54
54
  expect do
55
55
  connection.connect!
56
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-1\)/)
56
+ end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*used mechanism: SCRAM-SHA-1/)
57
57
  end
58
58
  end
59
59
  end
@@ -73,7 +73,7 @@ describe 'Auth' do
73
73
  it 'indicates scram-sha-1 was used' do
74
74
  expect do
75
75
  connection.connect!
76
- end.to raise_error(Mongo::Auth::Unauthorized, /User existing_user \(mechanism: scram\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-1\)/)
76
+ end.to raise_error(Mongo::Auth::Unauthorized, /User existing_user \(mechanism: scram\) is not authorized to access admin.*used mechanism: SCRAM-SHA-1/)
77
77
  end
78
78
  end
79
79
 
@@ -85,7 +85,7 @@ describe 'Auth' do
85
85
  it 'indicates scram-sha-256 was used' do
86
86
  expect do
87
87
  connection.connect!
88
- end.to raise_error(Mongo::Auth::Unauthorized, /User existing_user \(mechanism: scram256\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-256\)/)
88
+ end.to raise_error(Mongo::Auth::Unauthorized, /User existing_user \(mechanism: scram256\) is not authorized to access admin.*used mechanism: SCRAM-SHA-256/)
89
89
  end
90
90
  end
91
91
  end
@@ -101,7 +101,7 @@ describe 'Auth' do
101
101
  it 'indicates scram-sha-1 was requested and used' do
102
102
  expect do
103
103
  connection.connect!
104
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-1\)/)
104
+ end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*used mechanism: SCRAM-SHA-1/)
105
105
  end
106
106
  end
107
107
 
@@ -114,7 +114,7 @@ describe 'Auth' do
114
114
  it 'indicates scram-sha-256 was requested and used' do
115
115
  expect do
116
116
  connection.connect!
117
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram256\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-256\)/)
117
+ end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram256\) is not authorized to access admin.*used mechanism: SCRAM-SHA-256/)
118
118
  end
119
119
  end
120
120
  end
@@ -123,10 +123,29 @@ describe 'Auth' do
123
123
  let(:options) { SpecConfig.instance.ssl_options.merge(
124
124
  user: 'nonexistent_user', password: 'foo') }
125
125
 
126
- it 'reports auth source used' do
126
+ it 'reports which server authentication was attempted against' do
127
127
  expect do
128
128
  connection.connect!
129
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user.*is not authorized to access admin \(auth source: admin\)/)
129
+ end.to raise_error(Mongo::Auth::Unauthorized, /used server: #{connection.address.to_s}/)
130
+ end
131
+
132
+ context 'with default auth source' do
133
+ it 'reports auth source used' do
134
+ expect do
135
+ connection.connect!
136
+ end.to raise_error(Mongo::Auth::Unauthorized, /auth source: admin/)
137
+ end
138
+ end
139
+
140
+ context 'with custom auth source' do
141
+ let(:options) { SpecConfig.instance.ssl_options.merge(
142
+ user: 'nonexistent_user', password: 'foo', auth_source: 'authdb') }
143
+
144
+ it 'reports auth source used' do
145
+ expect do
146
+ connection.connect!
147
+ end.to raise_error(Mongo::Auth::Unauthorized, /auth source: authdb/)
148
+ end
130
149
  end
131
150
  end
132
151
 
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Symbol encoding to BSON' do
4
+ let(:value) { :foo }
5
+
6
+ let(:hash) do
7
+ {'foo' => value}
8
+ end
9
+
10
+ let(:serialized) do
11
+ hash.to_bson.to_s
12
+ end
13
+
14
+ let(:expected) do
15
+ "\x12\x00\x00\x00\x0Efoo\x00\x04\x00\x00\x00foo\x00\x00".force_encoding('binary')
16
+ end
17
+
18
+ it 'encodes symbol to BSON symbol' do
19
+ serialized.should == expected
20
+ end
21
+
22
+ it 'round-trips symbol values' do
23
+ buffer = BSON::ByteBuffer.new(serialized)
24
+ Hash.from_bson(buffer).should == hash
25
+ end
26
+
27
+ it 'round-trips symbol values using the same byte buffer' do
28
+ if BSON::Environment.jruby?
29
+ pending 'https://jira.mongodb.org/browse/RUBY-2128'
30
+ end
31
+
32
+ Hash.from_bson(hash.to_bson).should == hash
33
+ end
34
+ end