mongo 2.11.1 → 2.11.2

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 (50) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -1
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +24 -0
  5. data/lib/mongo/auth.rb +30 -10
  6. data/lib/mongo/auth/cr.rb +1 -0
  7. data/lib/mongo/auth/cr/conversation.rb +13 -13
  8. data/lib/mongo/auth/ldap.rb +2 -1
  9. data/lib/mongo/auth/ldap/conversation.rb +9 -12
  10. data/lib/mongo/auth/scram.rb +1 -0
  11. data/lib/mongo/auth/scram/conversation.rb +36 -27
  12. data/lib/mongo/auth/x509.rb +2 -1
  13. data/lib/mongo/auth/x509/conversation.rb +9 -9
  14. data/lib/mongo/client.rb +17 -6
  15. data/lib/mongo/cluster.rb +65 -49
  16. data/lib/mongo/cluster/sdam_flow.rb +87 -3
  17. data/lib/mongo/database.rb +1 -1
  18. data/lib/mongo/server.rb +13 -6
  19. data/lib/mongo/server/connection.rb +12 -4
  20. data/lib/mongo/server/connection_base.rb +7 -4
  21. data/lib/mongo/server/description.rb +34 -21
  22. data/lib/mongo/session.rb +10 -10
  23. data/lib/mongo/version.rb +1 -1
  24. data/spec/README.md +13 -0
  25. data/spec/integration/auth_spec.rb +27 -8
  26. data/spec/integration/client_construction_spec.rb +14 -0
  27. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  28. data/spec/mongo/auth/scram/conversation_spec.rb +23 -14
  29. data/spec/mongo/auth/x509/conversation_spec.rb +1 -1
  30. data/spec/mongo/client_construction_spec.rb +1 -21
  31. data/spec/mongo/cluster_spec.rb +38 -0
  32. data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
  33. data/spec/mongo/server/connection_spec.rb +67 -0
  34. data/spec/runners/sdam/verifier.rb +6 -3
  35. data/spec/spec_tests/data/sdam/rs/primary_address_change.yml +29 -0
  36. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me.yml +27 -23
  37. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +56 -79
  38. data/spec/spec_tests/data/sdam/sharded/primary_address_change.yml +21 -0
  39. data/spec/spec_tests/data/sdam/sharded/primary_mismatched_me.yml +22 -0
  40. data/spec/spec_tests/data/sdam/single/primary_address_change.yml +24 -0
  41. data/spec/spec_tests/data/sdam/single/primary_mismatched_me.yml +25 -0
  42. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +159 -0
  43. data/spec/spec_tests/data/sdam_monitoring/{replica_set_other_seed.yml → replica_set_with_primary_change.yml} +97 -101
  44. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary_removal.yml +22 -18
  45. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +90 -0
  46. data/spec/support/cluster_config.rb +36 -0
  47. data/spec/support/constraints.rb +18 -18
  48. data/spec/support/server_discovery_and_monitoring.rb +2 -0
  49. metadata +18 -4
  50. metadata.gz.sig +0 -0
@@ -16,7 +16,7 @@ describe Mongo::Auth::X509::Conversation do
16
16
  describe '#start' do
17
17
 
18
18
  let(:query) do
19
- conversation.start
19
+ conversation.start(nil)
20
20
  end
21
21
 
22
22
  let(:selector) do
@@ -94,27 +94,7 @@ describe Mongo::Client do
94
94
  # cluster during SDAM
95
95
  context 'me mismatch on the only initial seed' do
96
96
  let(:address) do
97
- address = SpecConfig.instance.addresses.first
98
- port = address.sub(/^.*:/, '').to_i
99
- address = address.sub(/:.*/, '')
100
- case address
101
- when '127.0.0.1'
102
- 'localhost'
103
- when /^(\d+\.){3}\d+$/
104
- skip 'This test requires a hostname or 127.0.0.1 as address'
105
- else
106
- # We don't know if mongod is listening on ipv4 or ipv6,
107
- # in principle.
108
- # Our tests use ipv4, so hardcode that for now.
109
- # To support both we need to try both addresses
110
- # which will make this test more complicated.
111
- resolved_address = Addrinfo.getaddrinfo(address, port, Socket::PF_INET).first.ip_address
112
- if resolved_address.include?(':')
113
- "[#{resolved_address}]"
114
- else
115
- resolved_address
116
- end + ":#{port}"
117
- end
97
+ ClusterConfig.instance.alternate_address.to_s
118
98
  end
119
99
 
120
100
  let(:logger) do
@@ -575,6 +575,44 @@ describe Mongo::Cluster do
575
575
  end
576
576
 
577
577
  describe '#sessions_supported?' do
578
+ context 'when client has not contacted any servers' do
579
+
580
+ let(:cluster) do
581
+ described_class.new(SpecConfig.instance.addresses, monitoring,
582
+ SpecConfig.instance.test_options.merge(
583
+ monitoring_io: false, server_selection_timeout: 0.183))
584
+ end
585
+
586
+ it 'is false' do
587
+ expect(cluster.send(:sessions_supported?)).to be false
588
+ end
589
+ end
590
+
591
+ context 'when client has contacted servers and then disconnected' do
592
+ min_server_fcv '3.6'
593
+ require_wired_tiger
594
+ require_topology :sharded, :replica_set
595
+
596
+ let(:cluster) do
597
+ described_class.new(SpecConfig.instance.addresses, monitoring,
598
+ SpecConfig.instance.test_options.merge(
599
+ server_selection_timeout: 0.183)
600
+ ).tap do |cluster|
601
+ register_cluster(cluster)
602
+ end
603
+ end
604
+
605
+ before do
606
+ cluster.next_primary
607
+ cluster.servers_list.map(&:disconnect!)
608
+ cluster.servers_list.map(&:unknown!)
609
+ end
610
+
611
+ it 'is true' do
612
+ expect(cluster.send(:sessions_supported?)).to be true
613
+ end
614
+ end
615
+
578
616
  context 'in server < 3.6' do
579
617
  max_server_version '3.4'
580
618
 
@@ -575,7 +575,7 @@ describe Mongo::Collection::View::MapReduce do
575
575
  expect(map_reduce.send(:secondary_ok?)).to be false
576
576
  end
577
577
 
578
- context 'when the server is not a valid for writing' do
578
+ context 'when the server is not valid for writing' do
579
579
  clean_slate
580
580
 
581
581
  before do
@@ -419,6 +419,73 @@ describe Mongo::Server::Connection, retry: 3 do
419
419
  end
420
420
  end
421
421
 
422
+ context 'connecting to arbiter' do
423
+ require_topology :replica_set
424
+
425
+ before(:all) do
426
+ unless ENV['HAVE_ARBITER']
427
+ skip 'Test requires an arbiter in the deployment'
428
+ end
429
+ end
430
+
431
+ let(:arbiter_server) do
432
+ authorized_client.cluster.servers_list.each do |server|
433
+ server.scan!
434
+ end
435
+ server = authorized_client.cluster.servers_list.detect do |server|
436
+ server.arbiter?
437
+ end.tap do |server|
438
+ raise 'No arbiter in the deployment' unless server
439
+ end
440
+ end
441
+
442
+ shared_examples_for 'does not authenticate' do
443
+ let(:client) do
444
+ new_local_client([address],
445
+ SpecConfig.instance.test_options.merge(
446
+ :user => 'bogus',
447
+ :password => 'bogus',
448
+ :database => 'bogus'
449
+ ).merge(connect: :direct),
450
+ )
451
+ end
452
+
453
+ let(:connection) do
454
+ described_class.new(
455
+ server,
456
+ )
457
+ end
458
+
459
+ let(:ping) do
460
+ client.database.command(ping: 1)
461
+ end
462
+
463
+ it 'does not authenticate' do
464
+ ClientRegistry.instance.close_all_clients
465
+
466
+ expect_any_instance_of(Mongo::Server::Connection).not_to receive(:authenticate!)
467
+
468
+ expect(ping.documents.first['ok']).to eq(1) rescue nil
469
+ end
470
+ end
471
+
472
+ context 'without me mismatch' do
473
+ let(:address) do
474
+ arbiter_server.address.to_s
475
+ end
476
+
477
+ it_behaves_like 'does not authenticate'
478
+ end
479
+
480
+ context 'with me mismatch' do
481
+ let(:address) do
482
+ "#{ClusterConfig.instance.alternate_address.host}:#{arbiter_server.address.port}"
483
+ end
484
+
485
+ it_behaves_like 'does not authenticate'
486
+ end
487
+ end
488
+
422
489
  end
423
490
 
424
491
  describe '#disconnect!' do
@@ -37,10 +37,13 @@ module Sdam
37
37
  verify_description_matches(server, desc)
38
38
  end
39
39
 
40
+ # Verify actual topology has no servers not also present in the
41
+ # expected topology description.
42
+ expected_addresses = expected['servers'].map do |server|
43
+ server['address']
44
+ end
40
45
  actual.server_descriptions.keys.each do |address_str|
41
- expect(
42
- expected['servers'].any? { |server| server['address'] == address_str }
43
- ).to be true
46
+ expect(expected_addresses).to include(address_str)
44
47
  end
45
48
  end
46
49
 
@@ -0,0 +1,29 @@
1
+ description: Primary whose address differs from client address but no me mismatch
2
+ uri: mongodb://localhost:27017/?replicaSet=rs
3
+ phases:
4
+ -
5
+ responses:
6
+ -
7
+ - localhost:27017
8
+ - hosts:
9
+ - a:27017
10
+ - b:27017
11
+ ismaster: true
12
+ ok: 1
13
+ setName: rs
14
+ minWireVersion: 0
15
+ maxWireVersion: 6
16
+ outcome:
17
+ # Both of the hosts in the primary description are added to the topology.
18
+ # Existing server (localhost:27017) is removed from topology because
19
+ # its address is not in the list of hosts returned by the primary.
20
+ servers:
21
+ a:27017:
22
+ setName:
23
+ type: Unknown
24
+ b:27017:
25
+ setName:
26
+ type: Unknown
27
+ setName: rs
28
+ topologyType: ReplicaSetNoPrimary
29
+ logicalSessionTimeoutMinutes:
@@ -1,26 +1,30 @@
1
1
  description: Primary mismatched me
2
+ uri: mongodb://localhost:27017/?replicaSet=rs
2
3
  phases:
3
- - outcome:
4
- servers:
5
- 'a:27017':
6
- setName: null
7
- type: Unknown
8
- 'b:27017':
9
- setName: null
10
- type: Unknown
4
+ -
5
+ responses:
6
+ -
7
+ - localhost:27017
8
+ - me: a:27017
9
+ hosts:
10
+ - a:27017
11
+ - b:27017
12
+ ismaster: true
13
+ ok: 1
11
14
  setName: rs
12
- topologyType: ReplicaSetNoPrimary
13
- logicalSessionTimeoutMinutes: null
14
- responses:
15
- - - 'localhost:27017'
16
- - me: 'a:27017'
17
- hosts:
18
- - 'a:27017'
19
- - 'b:27017'
20
- ismaster: true
21
- ok: 1
22
- setName: rs
23
- minWireVersion: 0
24
- maxWireVersion: 6
25
- uri: 'mongodb://localhost:27017/?replicaSet=rs'
26
-
15
+ minWireVersion: 0
16
+ maxWireVersion: 6
17
+ outcome:
18
+ # Both of the hosts in the primary description are added to the topology.
19
+ # Existing server (localhost:27017) is removed from topology because
20
+ # its address is not in the list of hosts returned by the primary.
21
+ servers:
22
+ a:27017:
23
+ setName:
24
+ type: Unknown
25
+ b:27017:
26
+ setName:
27
+ type: Unknown
28
+ setName: rs
29
+ topologyType: ReplicaSetNoPrimary
30
+ logicalSessionTimeoutMinutes:
@@ -1,79 +1,56 @@
1
- description: "Primary to no primary with mismatched me"
2
-
3
- uri: "mongodb://a/?replicaSet=rs"
4
-
5
- phases: [
6
-
7
- {
8
- responses: [
9
-
10
- ["a:27017", {
11
-
12
- ok: 1,
13
- ismaster: true,
14
- hosts: ["a:27017", "b:27017"],
15
- me: "a:27017",
16
- setName: "rs",
17
- minWireVersion: 0,
18
- maxWireVersion: 6
19
- }]
20
- ],
21
-
22
- outcome: {
23
-
24
- servers: {
25
-
26
- "a:27017": {
27
-
28
- type: "RSPrimary",
29
- setName: "rs"
30
- },
31
-
32
- "b:27017": {
33
-
34
- type: "Unknown",
35
- setName:
36
- }
37
- },
38
- topologyType: "ReplicaSetWithPrimary",
39
- logicalSessionTimeoutMinutes: null,
40
- setName: "rs"
41
- }
42
- },
43
- {
44
- responses: [
45
-
46
- ["a:27017", {
47
-
48
- ok: 1,
49
- ismaster: true,
50
- hosts: ["c:27017", "d:27017"],
51
- me : "c:27017",
52
- setName: "rs",
53
- minWireVersion: 0,
54
- maxWireVersion: 6
55
- }]
56
- ],
57
-
58
- outcome: {
59
-
60
- servers: {
61
-
62
- "c:27017": {
63
-
64
- type: "Unknown",
65
- setName:
66
- },
67
-
68
- "d:27017": {
69
-
70
- type: "Unknown",
71
- setName:
72
- }
73
- },
74
- topologyType: "ReplicaSetNoPrimary",
75
- logicalSessionTimeoutMinutes: null,
76
- setName: "rs"
77
- }
78
- }
79
- ]
1
+ description: Primary to no primary with mismatched me
2
+ uri: mongodb://a/?replicaSet=rs
3
+
4
+ phases:
5
+ -
6
+ responses:
7
+ -
8
+ - a:27017
9
+ - ok: 1
10
+ ismaster: true
11
+ hosts:
12
+ - a:27017
13
+ - b:27017
14
+ me: a:27017
15
+ setName: rs
16
+ minWireVersion: 0
17
+ maxWireVersion: 6
18
+ outcome:
19
+ servers:
20
+ a:27017:
21
+ type: RSPrimary
22
+ setName: rs
23
+ b:27017:
24
+ type: Unknown
25
+ setName:
26
+ topologyType: ReplicaSetWithPrimary
27
+ logicalSessionTimeoutMinutes:
28
+ setName: rs
29
+
30
+ -
31
+ responses:
32
+ -
33
+ - a:27017
34
+ - ok: 1
35
+ ismaster: true
36
+ hosts:
37
+ - c:27017
38
+ - d:27017
39
+ me: c:27017
40
+ setName: rs
41
+ minWireVersion: 0
42
+ maxWireVersion: 6
43
+ outcome:
44
+ # Hosts from primary description (c:27017 and d:27017) added to the topoolgy.
45
+ # Hosts not in primary description (a:27017 and b:27017) are removed from
46
+ # the topology.
47
+ servers:
48
+ c:27017:
49
+ type: Unknown
50
+ setName:
51
+ d:27017:
52
+ type: Unknown
53
+ setName:
54
+ topologyType: ReplicaSetNoPrimary
55
+ logicalSessionTimeoutMinutes:
56
+ setName: rs
@@ -0,0 +1,21 @@
1
+ description: RS Primary whose address differs from client address but no me mismatch
2
+ uri: mongodb://localhost:27017/?connect=sharded
3
+ phases:
4
+ -
5
+ responses:
6
+ -
7
+ - localhost:27017
8
+ - hosts:
9
+ - a:27017
10
+ - b:27017
11
+ ismaster: true
12
+ ok: 1
13
+ setName: rs
14
+ minWireVersion: 0
15
+ maxWireVersion: 6
16
+ outcome:
17
+ # Since the server is of the wrong type, it is removed from the topology.
18
+ servers:
19
+ {}
20
+ topologyType: Sharded
21
+ logicalSessionTimeoutMinutes:
@@ -0,0 +1,22 @@
1
+ description: RS Primary w/mismatched me
2
+ uri: mongodb://localhost:27017/?connect=sharded
3
+ phases:
4
+ -
5
+ responses:
6
+ -
7
+ - localhost:27017
8
+ - me: a:27017
9
+ hosts:
10
+ - a:27017
11
+ - b:27017
12
+ ismaster: true
13
+ ok: 1
14
+ setName: rs
15
+ minWireVersion: 0
16
+ maxWireVersion: 6
17
+ outcome:
18
+ # Since the server is of the wrong type, it is removed from the topology.
19
+ servers:
20
+ {}
21
+ topologyType: Sharded
22
+ logicalSessionTimeoutMinutes: