mongo 2.0.5 → 2.0.6

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 (85) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo/auth/cr/conversation.rb +0 -1
  5. data/lib/mongo/client.rb +19 -5
  6. data/lib/mongo/cluster.rb +84 -16
  7. data/lib/mongo/cluster/topology.rb +3 -4
  8. data/lib/mongo/cluster/topology/replica_set.rb +75 -0
  9. data/lib/mongo/cluster/topology/sharded.rb +60 -0
  10. data/lib/mongo/cluster/topology/single.rb +51 -0
  11. data/lib/mongo/cluster/topology/unknown.rb +62 -0
  12. data/lib/mongo/error/invalid_bulk_operation.rb +2 -1
  13. data/lib/mongo/event.rb +9 -9
  14. data/lib/mongo/event/{server_added.rb → description_changed.rb} +6 -5
  15. data/lib/mongo/event/{server_removed.rb → standalone_discovered.rb} +15 -15
  16. data/lib/mongo/operation/aggregate.rb +6 -5
  17. data/lib/mongo/operation/command.rb +5 -6
  18. data/lib/mongo/operation/kill_cursors.rb +3 -2
  19. data/lib/mongo/operation/map_reduce.rb +6 -5
  20. data/lib/mongo/operation/read/collections_info.rb +5 -4
  21. data/lib/mongo/operation/read/get_more.rb +8 -7
  22. data/lib/mongo/operation/read/indexes.rb +4 -3
  23. data/lib/mongo/operation/read/list_collections.rb +5 -4
  24. data/lib/mongo/operation/read/list_indexes.rb +7 -6
  25. data/lib/mongo/operation/read/query.rb +8 -7
  26. data/lib/mongo/operation/read_preferrable.rb +6 -2
  27. data/lib/mongo/operation/write/bulk/bulk_delete.rb +13 -12
  28. data/lib/mongo/operation/write/bulk/bulk_insert.rb +10 -9
  29. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +2 -2
  30. data/lib/mongo/operation/write/bulk/bulk_update.rb +12 -11
  31. data/lib/mongo/operation/write/create_index.rb +8 -7
  32. data/lib/mongo/operation/write/create_user.rb +4 -3
  33. data/lib/mongo/operation/write/delete.rb +13 -12
  34. data/lib/mongo/operation/write/drop_index.rb +6 -5
  35. data/lib/mongo/operation/write/insert.rb +8 -7
  36. data/lib/mongo/operation/write/insert/result.rb +1 -1
  37. data/lib/mongo/operation/write/remove_user.rb +4 -3
  38. data/lib/mongo/operation/write/update.rb +10 -9
  39. data/lib/mongo/operation/write/update_user.rb +4 -3
  40. data/lib/mongo/server.rb +8 -15
  41. data/lib/mongo/server/context.rb +2 -2
  42. data/lib/mongo/server/description.rb +65 -3
  43. data/lib/mongo/server/description/features.rb +2 -1
  44. data/lib/mongo/server/description/inspector.rb +5 -5
  45. data/lib/mongo/server/description/inspector/{server_added.rb → description_changed.rb} +3 -5
  46. data/lib/mongo/server/description/inspector/{server_removed.rb → standalone_discovered.rb} +12 -15
  47. data/lib/mongo/version.rb +1 -1
  48. data/spec/mongo/auth/cr_spec.rb +1 -1
  49. data/spec/mongo/auth/ldap_spec.rb +1 -1
  50. data/spec/mongo/auth/scram_spec.rb +1 -1
  51. data/spec/mongo/auth/x509_spec.rb +1 -1
  52. data/spec/mongo/client_spec.rb +4 -0
  53. data/spec/mongo/cluster/topology/replica_set_spec.rb +254 -4
  54. data/spec/mongo/cluster/topology/sharded_spec.rb +70 -19
  55. data/spec/mongo/cluster/topology/single_spec.rb +25 -4
  56. data/spec/mongo/cluster/topology/unknown_spec.rb +167 -0
  57. data/spec/mongo/cluster/topology_spec.rb +6 -6
  58. data/spec/mongo/cluster_spec.rb +179 -1
  59. data/spec/mongo/operation/read_preferrable_spec.rb +81 -28
  60. data/spec/mongo/operation/write/bulk/bulk_delete_spec.rb +1 -0
  61. data/spec/mongo/server/connection_pool_spec.rb +10 -10
  62. data/spec/mongo/server/connection_spec.rb +1 -1
  63. data/spec/mongo/server/description/features_spec.rb +23 -3
  64. data/spec/mongo/server/description/inspector/description_changed_spec.rb +78 -0
  65. data/spec/mongo/server/description_spec.rb +238 -0
  66. data/spec/mongo/server/monitor_spec.rb +1 -1
  67. data/spec/mongo/server_discovery_and_monitoring_spec.rb +20 -4
  68. data/spec/mongo/server_selection_spec.rb +2 -2
  69. data/spec/mongo/server_spec.rb +12 -8
  70. data/spec/support/authorization.rb +8 -8
  71. data/spec/support/sdam/rs/discover_passives.yml +36 -0
  72. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
  73. data/spec/support/sdam/rs/primary_becomes_standalone.yml +1 -1
  74. data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
  75. data/spec/support/sdam/rs/primary_disconnect.yml +1 -1
  76. data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
  77. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
  78. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
  79. data/spec/support/sdam/sharded/single_mongos.yml +33 -0
  80. data/spec/support/shared/operation.rb +12 -4
  81. data/spec/support/shared/server_selector.rb +1 -1
  82. metadata +12 -10
  83. metadata.gz.sig +0 -0
  84. data/spec/mongo/server/description/inspector/server_added_spec.rb +0 -92
  85. data/spec/mongo/server/description/inspector/server_removed_spec.rb +0 -95
@@ -226,6 +226,7 @@ describe Mongo::Operation::Write::BulkDelete do
226
226
 
227
227
  it 'does not abort after first error' do
228
228
  failing_delete.execute(authorized_primary.context)
229
+ sleep(1)
229
230
  expect(authorized_collection.find.count).to eq(1)
230
231
  end
231
232
  end
@@ -9,10 +9,10 @@ describe Mongo::Server::ConnectionPool do
9
9
  describe '#checkin' do
10
10
 
11
11
  let(:server) do
12
- Mongo::Server.new(address, Mongo::Event::Listeners.new, ssl: SSL)
12
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, ssl: SSL)
13
13
  end
14
14
 
15
- let(:pool) do
15
+ let!(:pool) do
16
16
  described_class.get(server)
17
17
  end
18
18
 
@@ -39,10 +39,10 @@ describe Mongo::Server::ConnectionPool do
39
39
  describe '#checkout' do
40
40
 
41
41
  let(:server) do
42
- Mongo::Server.new(address, Mongo::Event::Listeners.new, ssl: SSL)
42
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, ssl: SSL)
43
43
  end
44
44
 
45
- let(:pool) do
45
+ let!(:pool) do
46
46
  described_class.get(server)
47
47
  end
48
48
 
@@ -87,10 +87,10 @@ describe Mongo::Server::ConnectionPool do
87
87
  describe '.get' do
88
88
 
89
89
  let(:server) do
90
- Mongo::Server.new(address, Mongo::Event::Listeners.new, ssl: SSL)
90
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, ssl: SSL)
91
91
  end
92
92
 
93
- let(:pool) do
93
+ let!(:pool) do
94
94
  described_class.get(server)
95
95
  end
96
96
 
@@ -102,10 +102,10 @@ describe Mongo::Server::ConnectionPool do
102
102
  describe '#inspect' do
103
103
 
104
104
  let(:server) do
105
- Mongo::Server.new(address, Mongo::Event::Listeners.new, ssl: SSL)
105
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, ssl: SSL)
106
106
  end
107
107
 
108
- let(:pool) do
108
+ let!(:pool) do
109
109
  described_class.get(server)
110
110
  end
111
111
 
@@ -121,10 +121,10 @@ describe Mongo::Server::ConnectionPool do
121
121
  describe '#with_connection' do
122
122
 
123
123
  let(:server) do
124
- Mongo::Server.new(address, Mongo::Event::Listeners.new, ssl: SSL)
124
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, ssl: SSL)
125
125
  end
126
126
 
127
- let(:pool) do
127
+ let!(:pool) do
128
128
  described_class.get(server)
129
129
  end
130
130
 
@@ -7,7 +7,7 @@ describe Mongo::Server::Connection do
7
7
  end
8
8
 
9
9
  let(:server) do
10
- Mongo::Server.new(address, Mongo::Event::Listeners.new, ssl: SSL)
10
+ Mongo::Server.new(address, double('cluster'), Mongo::Event::Listeners.new, ssl: SSL)
11
11
  end
12
12
 
13
13
  describe '#connect!' do
@@ -15,16 +15,36 @@ describe Mongo::Server::Description::Features do
15
15
  end
16
16
  end
17
17
 
18
- context 'when the server wire version range is higher' do
18
+ context 'when the server wire version range min is higher' do
19
19
 
20
20
  it 'raises an exception' do
21
21
  expect {
22
- described_class.new(0..4)
22
+ described_class.new(described_class::DRIVER_WIRE_VERSIONS.max+1..described_class::DRIVER_WIRE_VERSIONS.max+2)
23
23
  }.to raise_error(Mongo::Error::UnsupportedFeatures)
24
24
  end
25
25
  end
26
26
 
27
- context 'when the server wire version range is lower' do
27
+ context 'when the server wire version range max is higher' do
28
+
29
+ let(:features) do
30
+ described_class.new(0..4)
31
+ end
32
+
33
+ it 'sets the server wire version range' do
34
+ expect(features.server_wire_versions).to eq(0..4)
35
+ end
36
+ end
37
+
38
+ context 'when the server wire version range max is lower' do
39
+
40
+ it 'raises an exception' do
41
+ expect {
42
+ described_class.new(described_class::DRIVER_WIRE_VERSIONS.min-2..described_class::DRIVER_WIRE_VERSIONS.min-1)
43
+ }.to raise_error(Mongo::Error::UnsupportedFeatures)
44
+ end
45
+ end
46
+
47
+ context 'when the server wire version range max is lower' do
28
48
 
29
49
  let(:features) do
30
50
  described_class.new(0..2)
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Server::Description::Inspector::DescriptionChanged do
4
+
5
+ let(:listeners) do
6
+ Mongo::Event::Listeners.new
7
+ end
8
+
9
+ let(:inspection) do
10
+ described_class.new(listeners)
11
+ end
12
+
13
+ let(:address) do
14
+ Mongo::Address.new('127.0.0.1:27017')
15
+ end
16
+
17
+ describe '.run' do
18
+
19
+ let(:config) do
20
+ {
21
+ 'ismaster' => true,
22
+ 'secondary' => false,
23
+ 'hosts' => [ '127.0.0.1:27018', '127.0.0.1:27019' ],
24
+ 'setName' => 'test'
25
+ }
26
+ end
27
+
28
+ let(:description) do
29
+ Mongo::Server::Description.new(address, config, listeners)
30
+ end
31
+
32
+ let(:updated) do
33
+ Mongo::Server::Description.new(address, new_config, listeners)
34
+ end
35
+
36
+ let(:listener) do
37
+ double('listener')
38
+ end
39
+
40
+ before do
41
+ listeners.add_listener(Mongo::Event::DESCRIPTION_CHANGED, listener)
42
+ end
43
+
44
+ context 'when there is no change' do
45
+
46
+ let(:new_config) do
47
+ {
48
+ 'ismaster' => true,
49
+ 'secondary' => false,
50
+ 'hosts' => [ '127.0.0.1:27018', '127.0.0.1:27019' ],
51
+ 'setName' => 'test'
52
+ }
53
+ end
54
+
55
+ it 'does not fire a description changed event' do
56
+ expect(listener).to_not receive(:handle)
57
+ inspection.run(description, updated)
58
+ end
59
+ end
60
+
61
+ context 'when there is a change' do
62
+
63
+ let(:new_config) do
64
+ {
65
+ 'ismaster' => true,
66
+ 'secondary' => false,
67
+ 'hosts' => [ '127.0.0.1:27018', '127.0.0.1:27020' ],
68
+ 'setName' => 'test'
69
+ }
70
+ end
71
+
72
+ it 'fires a description changed event' do
73
+ expect(listener).to receive(:handle)
74
+ inspection.run(description, updated)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -22,6 +22,7 @@ describe Mongo::Server::Description do
22
22
  'maxWriteBatchSize' => 1000,
23
23
  'maxWireVersion' => 2,
24
24
  'minWireVersion' => 0,
25
+ 'localTime' => Time.now,
25
26
  'ok' => 1
26
27
  }
27
28
  end
@@ -78,6 +79,27 @@ describe Mongo::Server::Description do
78
79
  expect(description.arbiters).to be_empty
79
80
  end
80
81
  end
82
+
83
+ context 'when the addresses are not lowercase' do
84
+
85
+ let(:config) do
86
+ replica.merge(
87
+ {
88
+ 'arbiters' => [
89
+ 'SERVER:27017'
90
+ ],
91
+ }
92
+ )
93
+ end
94
+
95
+ let(:description) do
96
+ described_class.new(address, config)
97
+ end
98
+
99
+ it 'normalizes the addresses to lowercase' do
100
+ expect(description.arbiters).to eq(['server:27017'])
101
+ end
102
+ end
81
103
  end
82
104
 
83
105
  describe '#ghost?' do
@@ -143,6 +165,27 @@ describe Mongo::Server::Description do
143
165
  it 'returns all the hosts in the replica set' do
144
166
  expect(description.hosts).to eq([ '127.0.0.1:27018', '127.0.0.1:27019' ])
145
167
  end
168
+
169
+ context 'when the addresses are not lowercase' do
170
+
171
+ let(:config) do
172
+ replica.merge(
173
+ {
174
+ 'hosts' => [
175
+ 'SERVER:27017'
176
+ ],
177
+ }
178
+ )
179
+ end
180
+
181
+ let(:description) do
182
+ described_class.new(address, config)
183
+ end
184
+
185
+ it 'normalizes the addresses to lowercase' do
186
+ expect(description.hosts).to eq(['server:27017'])
187
+ end
188
+ end
146
189
  end
147
190
 
148
191
  describe '#max_bson_object_size' do
@@ -334,6 +377,31 @@ describe Mongo::Server::Description do
334
377
  expect(description.passives).to be_empty
335
378
  end
336
379
  end
380
+
381
+ context 'when the addresses are not lowercase' do
382
+
383
+ let(:config) do
384
+ replica.merge(
385
+ {
386
+ 'passives' => [
387
+ 'SERVER:27017'
388
+ ],
389
+ }
390
+ )
391
+ end
392
+
393
+ let(:description) do
394
+ described_class.new(address, config)
395
+ end
396
+
397
+ it 'normalizes the addresses to lowercase' do
398
+ expect(description.passives).to eq(['server:27017'])
399
+ end
400
+
401
+ it 'normalizes the addresses to lowercase' do
402
+
403
+ end
404
+ end
337
405
  end
338
406
 
339
407
  describe '#primary?' do
@@ -507,4 +575,174 @@ describe Mongo::Server::Description do
507
575
  end
508
576
  end
509
577
  end
578
+
579
+ describe '#is_server?' do
580
+
581
+ let(:listeners) do
582
+ Mongo::Event::Listeners.new
583
+ end
584
+
585
+ let(:server) do
586
+ Mongo::Server.new(address, double('cluster'), listeners)
587
+ end
588
+
589
+ let(:description) do
590
+ described_class.new(address, {})
591
+ end
592
+
593
+ context 'when the server address matches the description address' do
594
+
595
+ it 'returns true' do
596
+ expect(description.is_server?(server)).to be(true)
597
+ end
598
+ end
599
+
600
+ context 'when the server address does not match the description address' do
601
+
602
+ let(:other_address) do
603
+ Mongo::Address.new('127.0.0.1:27020')
604
+ end
605
+
606
+ let(:server) do
607
+ Mongo::Server.new(other_address, double('cluster'), listeners)
608
+ end
609
+
610
+ it 'returns false' do
611
+ expect(description.is_server?(server)).to be(false)
612
+ end
613
+ end
614
+ end
615
+
616
+ describe '#lists_server?' do
617
+
618
+ let(:description) do
619
+ described_class.new(address, replica)
620
+ end
621
+
622
+ let(:server_address) do
623
+ Mongo::Address.new('127.0.0.1:27018')
624
+ end
625
+
626
+ let(:listeners) do
627
+ Mongo::Event::Listeners.new
628
+ end
629
+
630
+ let(:server) do
631
+ Mongo::Server.new(server_address, double('cluster'), listeners)
632
+ end
633
+
634
+ context 'when the server is included in the description hosts list' do
635
+
636
+ it 'returns true' do
637
+ expect(description.lists_server?(server)).to be(true)
638
+ end
639
+ end
640
+
641
+ context 'when the server is not included in the description hosts list' do
642
+
643
+ let(:server_address) do
644
+ Mongo::Address.new('127.0.0.1:27017')
645
+ end
646
+
647
+ it 'returns false' do
648
+ expect(description.lists_server?(server)).to be(false)
649
+ end
650
+ end
651
+ end
652
+
653
+ describe '#replica_set_member?' do
654
+
655
+ context 'when the description is from a mongos' do
656
+
657
+ let(:config) do
658
+ { 'msg' => 'isdbgrid', 'ismaster' => true }
659
+ end
660
+
661
+ let(:description) do
662
+ described_class.new(address, config)
663
+ end
664
+
665
+ it 'returns false' do
666
+ expect(description.replica_set_member?).to be(false)
667
+ end
668
+ end
669
+
670
+ context 'when the description is from a standalone' do
671
+
672
+ let(:description) do
673
+ described_class.new(address, { 'ismaster' => true, 'ok' => 1 })
674
+ end
675
+
676
+ it 'returns false' do
677
+ expect(description.replica_set_member?).to be(false)
678
+ end
679
+ end
680
+
681
+ context 'when the description is from a replica set member' do
682
+
683
+ let(:description) do
684
+ described_class.new(address, replica)
685
+ end
686
+
687
+ it 'returns true' do
688
+ expect(description.replica_set_member?).to be(true)
689
+ end
690
+ end
691
+ end
692
+
693
+ describe '#==' do
694
+
695
+ let(:description) do
696
+ described_class.new(address, replica)
697
+ end
698
+
699
+ let(:other) do
700
+ described_class.new(address, replica.merge('localTime' => 1))
701
+ end
702
+
703
+ it 'excludes certain fields' do
704
+ expect(description == other).to be(true)
705
+ end
706
+
707
+ context 'when the classes do not match' do
708
+
709
+ let(:description) do
710
+ described_class.new(address, replica)
711
+ end
712
+
713
+ it 'returns false' do
714
+ expect(description == Array.new).to be(false)
715
+ end
716
+ end
717
+
718
+ context 'when the configs match' do
719
+
720
+ let(:description) do
721
+ described_class.new(address, replica)
722
+ end
723
+
724
+ let(:other) do
725
+ described_class.new(address, replica)
726
+ end
727
+
728
+ it 'returns true' do
729
+ expect(description == other).to be(true)
730
+ end
731
+ end
732
+
733
+ context 'when the configs do not match' do
734
+
735
+ let(:description) do
736
+ described_class.new(address, replica)
737
+ end
738
+
739
+ let(:other) do
740
+ described_class.new(address, { 'ismaster' => true, 'ok' => 1 })
741
+ end
742
+
743
+ it 'returns false' do
744
+ expect(description == other).to be(false)
745
+ end
746
+ end
747
+ end
510
748
  end