mongo 2.0.5 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
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