mongo 2.0.6 → 2.1.0.beta
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +2 -0
- data/lib/mongo/bulk_write.rb +1 -0
- data/lib/mongo/bulk_write/bulk_writable.rb +87 -31
- data/lib/mongo/bulk_write/deletable.rb +8 -7
- data/lib/mongo/bulk_write/insertable.rb +4 -3
- data/lib/mongo/bulk_write/ordered_bulk_write.rb +6 -6
- data/lib/mongo/bulk_write/replacable.rb +4 -3
- data/lib/mongo/bulk_write/result.rb +138 -0
- data/lib/mongo/bulk_write/unordered_bulk_write.rb +5 -8
- data/lib/mongo/bulk_write/updatable.rb +8 -7
- data/lib/mongo/client.rb +36 -4
- data/lib/mongo/cluster.rb +39 -4
- data/lib/mongo/cluster/topology/replica_set.rb +20 -4
- data/lib/mongo/cluster/topology/sharded.rb +1 -1
- data/lib/mongo/collection.rb +282 -29
- data/lib/mongo/collection/view/aggregation.rb +32 -4
- data/lib/mongo/collection/view/iterable.rb +2 -1
- data/lib/mongo/collection/view/map_reduce.rb +3 -1
- data/lib/mongo/collection/view/readable.rb +89 -14
- data/lib/mongo/collection/view/writable.rb +11 -5
- data/lib/mongo/cursor.rb +11 -3
- data/lib/mongo/dbref.rb +113 -0
- data/lib/mongo/error.rb +6 -2
- data/lib/mongo/error/parser.rb +1 -1
- data/lib/mongo/event/description_changed.rb +1 -1
- data/lib/mongo/grid/file.rb +1 -1
- data/lib/mongo/grid/fs.rb +2 -5
- data/lib/mongo/monitoring.rb +199 -0
- data/lib/mongo/monitoring/command_log_subscriber.rb +88 -0
- data/lib/mongo/monitoring/event.rb +17 -0
- data/lib/mongo/monitoring/event/command_failed.rb +96 -0
- data/lib/mongo/monitoring/event/command_started.rb +88 -0
- data/lib/mongo/monitoring/event/command_succeeded.rb +96 -0
- data/lib/mongo/monitoring/publishable.rb +96 -0
- data/lib/mongo/operation.rb +1 -0
- data/lib/mongo/operation/executable.rb +1 -1
- data/lib/mongo/operation/parallel_scan.rb +76 -0
- data/lib/mongo/operation/parallel_scan/result.rb +72 -0
- data/lib/mongo/operation/specifiable.rb +18 -0
- data/lib/mongo/operation/write/bulk/bulk_delete.rb +1 -1
- data/lib/mongo/operation/write/bulk/bulk_insert.rb +1 -1
- data/lib/mongo/operation/write/bulk/bulk_mergable.rb +2 -2
- data/lib/mongo/operation/write/bulk/bulk_update.rb +1 -1
- data/lib/mongo/operation/write/bulk/bulk_update/result.rb +13 -1
- data/lib/mongo/protocol/delete.rb +8 -13
- data/lib/mongo/protocol/get_more.rb +13 -13
- data/lib/mongo/protocol/insert.rb +8 -13
- data/lib/mongo/protocol/kill_cursors.rb +7 -11
- data/lib/mongo/protocol/query.rb +58 -20
- data/lib/mongo/protocol/reply.rb +12 -0
- data/lib/mongo/protocol/update.rb +13 -14
- data/lib/mongo/server.rb +23 -2
- data/lib/mongo/server/connectable.rb +0 -22
- data/lib/mongo/server/connection.rb +29 -0
- data/lib/mongo/server/description.rb +23 -1
- data/lib/mongo/server/monitor.rb +17 -1
- data/lib/mongo/server/monitor/connection.rb +24 -0
- data/lib/mongo/socket/ssl.rb +28 -16
- data/lib/mongo/socket/tcp.rb +1 -1
- data/lib/mongo/socket/unix.rb +1 -1
- data/lib/mongo/uri.rb +12 -5
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/auth/cr_spec.rb +9 -1
- data/spec/mongo/auth/ldap_spec.rb +9 -1
- data/spec/mongo/auth/scram_spec.rb +9 -1
- data/spec/mongo/auth/x509_spec.rb +9 -1
- data/spec/mongo/{bulk/bulk_write_spec.rb → bulk_write_spec.rb} +15 -15
- data/spec/mongo/client_spec.rb +42 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +16 -9
- data/spec/mongo/cluster/topology/sharded_spec.rb +11 -3
- data/spec/mongo/cluster/topology/single_spec.rb +12 -4
- data/spec/mongo/cluster_spec.rb +55 -10
- data/spec/mongo/collection/view/aggregation_spec.rb +123 -1
- data/spec/mongo/collection/view/explainable_spec.rb +1 -1
- data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
- data/spec/mongo/collection/view/readable_spec.rb +251 -6
- data/spec/mongo/collection/view/writable_spec.rb +4 -4
- data/spec/mongo/collection/view_spec.rb +233 -71
- data/spec/mongo/collection_spec.rb +905 -9
- data/spec/mongo/crud_spec.rb +2 -2
- data/spec/mongo/cursor_spec.rb +3 -3
- data/spec/mongo/dbref_spec.rb +149 -0
- data/spec/mongo/monitoring_spec.rb +168 -0
- data/spec/mongo/operation/map_reduce_spec.rb +1 -1
- data/spec/mongo/operation/write/bulk/bulk_delete_spec.rb +1 -1
- data/spec/mongo/operation/write/bulk/bulk_insert_spec.rb +2 -2
- data/spec/mongo/operation/write/bulk/bulk_update_spec.rb +1 -1
- data/spec/mongo/operation/write/delete_spec.rb +1 -1
- data/spec/mongo/operation/write/insert_spec.rb +2 -2
- data/spec/mongo/operation/write/update_spec.rb +1 -1
- data/spec/mongo/protocol/query_spec.rb +0 -29
- data/spec/mongo/server/connection_pool_spec.rb +18 -6
- data/spec/mongo/server/connection_spec.rb +12 -4
- data/spec/mongo/server/description_spec.rb +7 -3
- data/spec/mongo/server/monitor_spec.rb +30 -0
- data/spec/mongo/server_discovery_and_monitoring_spec.rb +11 -4
- data/spec/mongo/server_selection_spec.rb +14 -6
- data/spec/mongo/server_spec.rb +27 -8
- data/spec/mongo/socket/ssl_spec.rb +94 -8
- data/spec/mongo/uri_spec.rb +25 -9
- data/spec/spec_helper.rb +29 -20
- data/spec/support/authorization.rb +19 -4
- data/spec/support/certificates/client.pem +4 -4
- data/spec/support/crud/read.rb +9 -10
- data/spec/support/crud/write.rb +24 -20
- data/spec/support/sdam/rs/equal_electionids.yml +45 -0
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +98 -0
- data/spec/support/sdam/rs/null_election_id.yml +144 -0
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +124 -0
- data/spec/support/sdam/sharded/mongos_disconnect.yml +104 -0
- data/spec/support/server_discovery_and_monitoring.rb +19 -2
- data/spec/support/shared/bulk_write.rb +26 -22
- data/spec/support/shared/server_selector.rb +2 -1
- metadata +31 -7
- metadata.gz.sig +0 -0
- data/lib/mongo/error/invalid_uri_option.rb +0 -38
| @@ -0,0 +1,144 @@ | |
| 1 | 
            +
            description: "Primaries with and without electionIds"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            uri: "mongodb://a/?replicaSet=rs"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            phases: [
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                # Primary A has no electionId.
         | 
| 8 | 
            +
                {
         | 
| 9 | 
            +
                    responses: [
         | 
| 10 | 
            +
                        ["a:27017", {
         | 
| 11 | 
            +
                            ok: 1,
         | 
| 12 | 
            +
                            ismaster: true,
         | 
| 13 | 
            +
                            hosts: ["a:27017", "b:27017", "c:27017"],
         | 
| 14 | 
            +
                            setName: "rs"
         | 
| 15 | 
            +
                        }]
         | 
| 16 | 
            +
                    ],
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    outcome: {
         | 
| 19 | 
            +
                        servers: {
         | 
| 20 | 
            +
                            "a:27017": {
         | 
| 21 | 
            +
                                type: "RSPrimary",
         | 
| 22 | 
            +
                                setName: "rs",
         | 
| 23 | 
            +
                                electionId:
         | 
| 24 | 
            +
                            },
         | 
| 25 | 
            +
                            "b:27017": {
         | 
| 26 | 
            +
                                type: "Unknown",
         | 
| 27 | 
            +
                                setName: ,
         | 
| 28 | 
            +
                                electionId:
         | 
| 29 | 
            +
                            },
         | 
| 30 | 
            +
                            "c:27017": {
         | 
| 31 | 
            +
                                type: "Unknown",
         | 
| 32 | 
            +
                                setName: ,
         | 
| 33 | 
            +
                                electionId:
         | 
| 34 | 
            +
                            }
         | 
| 35 | 
            +
                        },
         | 
| 36 | 
            +
                        topologyType: "ReplicaSetWithPrimary",
         | 
| 37 | 
            +
                        setName: "rs",
         | 
| 38 | 
            +
                    }
         | 
| 39 | 
            +
                },
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                # B is elected, it has an electionId.
         | 
| 42 | 
            +
                {
         | 
| 43 | 
            +
                    responses: [
         | 
| 44 | 
            +
                        ["b:27017", {
         | 
| 45 | 
            +
                            ok: 1,
         | 
| 46 | 
            +
                            ismaster: true,
         | 
| 47 | 
            +
                            hosts: ["a:27017", "b:27017", "c:27017"],
         | 
| 48 | 
            +
                            setName: "rs",
         | 
| 49 | 
            +
                            electionId: {"$oid": "000000000000000000000002"}
         | 
| 50 | 
            +
                        }]
         | 
| 51 | 
            +
                    ],
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    outcome: {
         | 
| 54 | 
            +
                        servers: {
         | 
| 55 | 
            +
                            "a:27017": {
         | 
| 56 | 
            +
                                type: "Unknown",
         | 
| 57 | 
            +
                                setName: ,
         | 
| 58 | 
            +
                                electionId:
         | 
| 59 | 
            +
                            },
         | 
| 60 | 
            +
                            "b:27017": {
         | 
| 61 | 
            +
                                type: "RSPrimary",
         | 
| 62 | 
            +
                                setName: "rs",
         | 
| 63 | 
            +
                                electionId: {"$oid": "000000000000000000000002"}
         | 
| 64 | 
            +
                            },
         | 
| 65 | 
            +
                            "c:27017": {
         | 
| 66 | 
            +
                                type: "Unknown",
         | 
| 67 | 
            +
                                setName: ,
         | 
| 68 | 
            +
                                electionId:
         | 
| 69 | 
            +
                            }
         | 
| 70 | 
            +
                        },
         | 
| 71 | 
            +
                        topologyType: "ReplicaSetWithPrimary",
         | 
| 72 | 
            +
                        setName: "rs",
         | 
| 73 | 
            +
                    }
         | 
| 74 | 
            +
                },
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                # A still claims to be primary, no electionId, we have to trust it.
         | 
| 77 | 
            +
                {
         | 
| 78 | 
            +
                    responses: [
         | 
| 79 | 
            +
                        ["a:27017", {
         | 
| 80 | 
            +
                            ok: 1,
         | 
| 81 | 
            +
                            ismaster: true,
         | 
| 82 | 
            +
                            hosts: ["a:27017", "b:27017", "c:27017"],
         | 
| 83 | 
            +
                            setName: "rs"
         | 
| 84 | 
            +
                        }]
         | 
| 85 | 
            +
                    ],
         | 
| 86 | 
            +
                    outcome: {
         | 
| 87 | 
            +
                        servers: {
         | 
| 88 | 
            +
                            "a:27017": {
         | 
| 89 | 
            +
                                type: "RSPrimary",
         | 
| 90 | 
            +
                                setName: "rs",
         | 
| 91 | 
            +
                                electionId:
         | 
| 92 | 
            +
                            },
         | 
| 93 | 
            +
                            "b:27017": {
         | 
| 94 | 
            +
                                type: "Unknown",
         | 
| 95 | 
            +
                                setName: ,
         | 
| 96 | 
            +
                                electionId:
         | 
| 97 | 
            +
                            },
         | 
| 98 | 
            +
                            "c:27017": {
         | 
| 99 | 
            +
                                type: "Unknown",
         | 
| 100 | 
            +
                                setName: ,
         | 
| 101 | 
            +
                                electionId:
         | 
| 102 | 
            +
                            }
         | 
| 103 | 
            +
                        },
         | 
| 104 | 
            +
                        topologyType: "ReplicaSetWithPrimary",
         | 
| 105 | 
            +
                        setName: "rs",
         | 
| 106 | 
            +
                    }
         | 
| 107 | 
            +
                },
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                # But we remember A's electionId, so when we finally hear from C
         | 
| 110 | 
            +
                # claiming it is primary, we ignore it due to its outdated electionId
         | 
| 111 | 
            +
                {
         | 
| 112 | 
            +
                    responses: [
         | 
| 113 | 
            +
                        ["c:27017", {
         | 
| 114 | 
            +
                            ok: 1,
         | 
| 115 | 
            +
                            ismaster: true,
         | 
| 116 | 
            +
                            hosts: ["a:27017", "b:27017", "c:27017"],
         | 
| 117 | 
            +
                            setName: "rs",
         | 
| 118 | 
            +
                            electionId: {"$oid": "000000000000000000000001"}
         | 
| 119 | 
            +
                        }]
         | 
| 120 | 
            +
                    ],
         | 
| 121 | 
            +
                    outcome: {
         | 
| 122 | 
            +
                        servers: {
         | 
| 123 | 
            +
                            # Still primary.
         | 
| 124 | 
            +
                            "a:27017": {
         | 
| 125 | 
            +
                                type: "RSPrimary",
         | 
| 126 | 
            +
                                setName: "rs",
         | 
| 127 | 
            +
                                electionId:
         | 
| 128 | 
            +
                            },
         | 
| 129 | 
            +
                            "b:27017": {
         | 
| 130 | 
            +
                                type: "Unknown",
         | 
| 131 | 
            +
                                setName: ,
         | 
| 132 | 
            +
                                electionId:
         | 
| 133 | 
            +
                            },
         | 
| 134 | 
            +
                            "c:27017": {
         | 
| 135 | 
            +
                                type: "Unknown",
         | 
| 136 | 
            +
                                setName: ,
         | 
| 137 | 
            +
                                electionId:
         | 
| 138 | 
            +
                            }
         | 
| 139 | 
            +
                        },
         | 
| 140 | 
            +
                        topologyType: "ReplicaSetWithPrimary",
         | 
| 141 | 
            +
                        setName: "rs",
         | 
| 142 | 
            +
                    }
         | 
| 143 | 
            +
                }
         | 
| 144 | 
            +
            ]
         | 
| @@ -0,0 +1,124 @@ | |
| 1 | 
            +
            description: "Disconnected from primary, reject stale primary"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            uri: "mongodb://a/?replicaSet=rs"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            phases: [
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                # A is elected, then B.
         | 
| 8 | 
            +
                {
         | 
| 9 | 
            +
                    responses: [
         | 
| 10 | 
            +
                        ["a:27017", {
         | 
| 11 | 
            +
                            ok: 1,
         | 
| 12 | 
            +
                            ismaster: true,
         | 
| 13 | 
            +
                            hosts: ["a:27017", "b:27017"],
         | 
| 14 | 
            +
                            setName: "rs",
         | 
| 15 | 
            +
                            electionId: {"$oid": "000000000000000000000001"}
         | 
| 16 | 
            +
                        }],
         | 
| 17 | 
            +
                        ["b:27017", {
         | 
| 18 | 
            +
                            ok: 1,
         | 
| 19 | 
            +
                            ismaster: true,
         | 
| 20 | 
            +
                            hosts: ["a:27017", "b:27017"],
         | 
| 21 | 
            +
                            setName: "rs",
         | 
| 22 | 
            +
                            electionId: {"$oid": "000000000000000000000002"}
         | 
| 23 | 
            +
                        }]
         | 
| 24 | 
            +
                    ],
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    outcome: {
         | 
| 27 | 
            +
                        servers: {
         | 
| 28 | 
            +
                            "a:27017": {
         | 
| 29 | 
            +
                                type: "Unknown",
         | 
| 30 | 
            +
                                setName: ,
         | 
| 31 | 
            +
                                electionId:
         | 
| 32 | 
            +
                            },
         | 
| 33 | 
            +
                            "b:27017": {
         | 
| 34 | 
            +
                                type: "RSPrimary",
         | 
| 35 | 
            +
                                setName: "rs",
         | 
| 36 | 
            +
                                electionId: {"$oid": "000000000000000000000002"}
         | 
| 37 | 
            +
                            }
         | 
| 38 | 
            +
                        },
         | 
| 39 | 
            +
                        topologyType: "ReplicaSetWithPrimary",
         | 
| 40 | 
            +
                        setName: "rs",
         | 
| 41 | 
            +
                    }
         | 
| 42 | 
            +
                },
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                # Disconnected from B.
         | 
| 45 | 
            +
                {
         | 
| 46 | 
            +
                    responses: [
         | 
| 47 | 
            +
                        ["b:27017", {}]
         | 
| 48 | 
            +
                    ],
         | 
| 49 | 
            +
                    outcome: {
         | 
| 50 | 
            +
                        servers: {
         | 
| 51 | 
            +
                            "a:27017": {
         | 
| 52 | 
            +
                                type: "Unknown",
         | 
| 53 | 
            +
                                setName: ,
         | 
| 54 | 
            +
                                electionId:
         | 
| 55 | 
            +
                            },
         | 
| 56 | 
            +
                            "b:27017": {
         | 
| 57 | 
            +
                                type: "Unknown",
         | 
| 58 | 
            +
                                setName: ,
         | 
| 59 | 
            +
                                electionId:
         | 
| 60 | 
            +
                            }
         | 
| 61 | 
            +
                        },
         | 
| 62 | 
            +
                        topologyType: "ReplicaSetNoPrimary",
         | 
| 63 | 
            +
                        setName: "rs",
         | 
| 64 | 
            +
                    }
         | 
| 65 | 
            +
                },
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                # A still claims to be primary but it's ignored.
         | 
| 68 | 
            +
                {
         | 
| 69 | 
            +
                    responses: [
         | 
| 70 | 
            +
                        ["a:27017", {
         | 
| 71 | 
            +
                            ok: 1,
         | 
| 72 | 
            +
                            ismaster: true,
         | 
| 73 | 
            +
                            hosts: ["a:27017", "b:27017"],
         | 
| 74 | 
            +
                            setName: "rs",
         | 
| 75 | 
            +
                            electionId: {"$oid": "000000000000000000000001"}
         | 
| 76 | 
            +
                        }]
         | 
| 77 | 
            +
                    ],
         | 
| 78 | 
            +
                    outcome: {
         | 
| 79 | 
            +
                        servers: {
         | 
| 80 | 
            +
                            "a:27017": {
         | 
| 81 | 
            +
                                type: "Unknown",
         | 
| 82 | 
            +
                                setName: ,
         | 
| 83 | 
            +
                                electionId:
         | 
| 84 | 
            +
                            },
         | 
| 85 | 
            +
                            "b:27017": {
         | 
| 86 | 
            +
                                type: "Unknown",
         | 
| 87 | 
            +
                                setName: ,
         | 
| 88 | 
            +
                                electionId:
         | 
| 89 | 
            +
                            }
         | 
| 90 | 
            +
                        },
         | 
| 91 | 
            +
                        topologyType: "ReplicaSetNoPrimary",
         | 
| 92 | 
            +
                        setName: "rs",
         | 
| 93 | 
            +
                    }
         | 
| 94 | 
            +
                },
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                # Now A is re-elected.
         | 
| 97 | 
            +
                {
         | 
| 98 | 
            +
                    responses: [
         | 
| 99 | 
            +
                        ["a:27017", {
         | 
| 100 | 
            +
                            ok: 1,
         | 
| 101 | 
            +
                            ismaster: true,
         | 
| 102 | 
            +
                            hosts: ["a:27017", "b:27017"],
         | 
| 103 | 
            +
                            setName: "rs",
         | 
| 104 | 
            +
                            electionId: {"$oid": "000000000000000000000003"}
         | 
| 105 | 
            +
                        }]
         | 
| 106 | 
            +
                    ],
         | 
| 107 | 
            +
                    outcome: {
         | 
| 108 | 
            +
                        servers: {
         | 
| 109 | 
            +
                            "a:27017": {
         | 
| 110 | 
            +
                                type: "RSPrimary",
         | 
| 111 | 
            +
                                setName: "rs",
         | 
| 112 | 
            +
                                electionId: {"$oid": "000000000000000000000003"}
         | 
| 113 | 
            +
                            },
         | 
| 114 | 
            +
                            "b:27017": {
         | 
| 115 | 
            +
                                type: "Unknown",
         | 
| 116 | 
            +
                                setName: ,
         | 
| 117 | 
            +
                                electionId:
         | 
| 118 | 
            +
                            }
         | 
| 119 | 
            +
                        },
         | 
| 120 | 
            +
                        topologyType: "ReplicaSetWithPrimary",
         | 
| 121 | 
            +
                        setName: "rs",
         | 
| 122 | 
            +
                    }
         | 
| 123 | 
            +
                }
         | 
| 124 | 
            +
            ]
         | 
| @@ -0,0 +1,104 @@ | |
| 1 | 
            +
            description: "Mongos disconnect"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            uri: "mongodb://a,b"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            phases: [
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                {
         | 
| 8 | 
            +
                    responses: [
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                            ["a:27017", {
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                                ok: 1,
         | 
| 13 | 
            +
                                ismaster: true,
         | 
| 14 | 
            +
                                msg: "isdbgrid"
         | 
| 15 | 
            +
                            }],
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                            ["b:27017", {
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                                ok: 1,
         | 
| 20 | 
            +
                                ismaster: true,
         | 
| 21 | 
            +
                                msg: "isdbgrid"
         | 
| 22 | 
            +
                            }]
         | 
| 23 | 
            +
                    ],
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    outcome: {
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                        servers: {
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                            "a:27017": {
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                                type: "Mongos",
         | 
| 32 | 
            +
                                setName:
         | 
| 33 | 
            +
                            },
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                            "b:27017": {
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                                type: "Mongos",
         | 
| 38 | 
            +
                                setName:
         | 
| 39 | 
            +
                            }
         | 
| 40 | 
            +
                        },
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                        topologyType: "Sharded",
         | 
| 43 | 
            +
                        setName:
         | 
| 44 | 
            +
                    }
         | 
| 45 | 
            +
                },
         | 
| 46 | 
            +
                {
         | 
| 47 | 
            +
                    responses: [
         | 
| 48 | 
            +
                            ["a:27017", {}],  # Hangup.
         | 
| 49 | 
            +
                    ],
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    outcome: {
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                        servers: {
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                            "a:27017": {
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                                type: "Unknown",
         | 
| 58 | 
            +
                                setName:
         | 
| 59 | 
            +
                            },
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                            "b:27017": {
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                                type: "Mongos",
         | 
| 64 | 
            +
                                setName:
         | 
| 65 | 
            +
                            }
         | 
| 66 | 
            +
                        },
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                        topologyType: "Sharded",
         | 
| 69 | 
            +
                        setName:
         | 
| 70 | 
            +
                    }
         | 
| 71 | 
            +
                },
         | 
| 72 | 
            +
                {
         | 
| 73 | 
            +
                    responses: [
         | 
| 74 | 
            +
                            # Back in action.
         | 
| 75 | 
            +
                            ["a:27017", {
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                                ok: 1,
         | 
| 78 | 
            +
                                ismaster: true,
         | 
| 79 | 
            +
                                msg: "isdbgrid"
         | 
| 80 | 
            +
                            }],
         | 
| 81 | 
            +
                    ],
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    outcome: {
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                        servers: {
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                            "a:27017": {
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                                type: "Mongos",
         | 
| 90 | 
            +
                                setName:
         | 
| 91 | 
            +
                            },
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                            "b:27017": {
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                                type: "Mongos",
         | 
| 96 | 
            +
                                setName:
         | 
| 97 | 
            +
                            }
         | 
| 98 | 
            +
                        },
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                        topologyType: "Sharded",
         | 
| 101 | 
            +
                        setName:
         | 
| 102 | 
            +
                    }
         | 
| 103 | 
            +
                }
         | 
| 104 | 
            +
            ]
         | 
| @@ -45,6 +45,15 @@ module Mongo | |
| 45 45 | 
             
                  client.cluster.instance_variable_get(:@servers).detect{ |s| s.address.to_s == uri }
         | 
| 46 46 | 
             
                end
         | 
| 47 47 |  | 
| 48 | 
            +
                # Helper to convert an extended JSON ObjectId electionId to BSON::ObjectId.
         | 
| 49 | 
            +
                #
         | 
| 50 | 
            +
                # @since 2.1.0
         | 
| 51 | 
            +
                def self.convert_election_ids(docs)
         | 
| 52 | 
            +
                  docs.each do |doc |
         | 
| 53 | 
            +
                    doc['electionId'] = BSON::ObjectId.from_string(doc['electionId']['$oid']) if doc['electionId']
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 48 57 | 
             
                # Represents a specification.
         | 
| 49 58 | 
             
                #
         | 
| 50 59 | 
             
                # @since 2.0.0
         | 
| @@ -102,7 +111,7 @@ module Mongo | |
| 102 111 | 
             
                  # @since 2.0.0
         | 
| 103 112 | 
             
                  def initialize(phase, uri)
         | 
| 104 113 | 
             
                    @phase = phase
         | 
| 105 | 
            -
                    @responses = @phase['responses'].map{ |response| Response.new(response, uri) }
         | 
| 114 | 
            +
                    @responses = @phase['responses'].map{ |response| Response.new(SDAM::convert_election_ids(response), uri) }
         | 
| 106 115 | 
             
                    @outcome = Outcome.new(@phase['outcome'])
         | 
| 107 116 | 
             
                  end
         | 
| 108 117 | 
             
                end
         | 
| @@ -158,10 +167,18 @@ module Mongo | |
| 158 167 | 
             
                  #
         | 
| 159 168 | 
             
                  # @since 2.0.0
         | 
| 160 169 | 
             
                  def initialize(outcome)
         | 
| 161 | 
            -
                    @servers = outcome['servers']
         | 
| 170 | 
            +
                    @servers = process_servers(outcome['servers'])
         | 
| 162 171 | 
             
                    @set_name = outcome['setName']
         | 
| 163 172 | 
             
                    @topology_type = outcome['topologyType']
         | 
| 164 173 | 
             
                  end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                  private
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                  def process_servers(servers)
         | 
| 178 | 
            +
                    servers.each do |s|
         | 
| 179 | 
            +
                      SDAM::convert_election_ids([ s[1] ])
         | 
| 180 | 
            +
                    end
         | 
| 181 | 
            +
                  end
         | 
| 165 182 | 
             
                end
         | 
| 166 183 | 
             
              end
         | 
| 167 184 | 
             
            end
         | 
| @@ -35,7 +35,7 @@ shared_examples 'a bulk write object' do | |
| 35 35 | 
             
                  end
         | 
| 36 36 |  | 
| 37 37 | 
             
                  it 'returns n_inserted of 1' do
         | 
| 38 | 
            -
                    expect(bulk.execute | 
| 38 | 
            +
                    expect(bulk.execute.inserted_count).to eq(1)
         | 
| 39 39 | 
             
                  end
         | 
| 40 40 |  | 
| 41 41 | 
             
                  it 'only inserts that document' do
         | 
| @@ -94,7 +94,7 @@ shared_examples 'a bulk write object' do | |
| 94 94 | 
             
                context 'when multiple documents match delete selector' do
         | 
| 95 95 |  | 
| 96 96 | 
             
                  it 'reports n_removed correctly' do
         | 
| 97 | 
            -
                    expect(bulk.execute | 
| 97 | 
            +
                    expect(bulk.execute.deleted_count).to eq(1)
         | 
| 98 98 | 
             
                  end
         | 
| 99 99 |  | 
| 100 100 | 
             
                  it 'deletes only matching documents' do
         | 
| @@ -136,7 +136,7 @@ shared_examples 'a bulk write object' do | |
| 136 136 | 
             
                  context 'when multiple documents match delete selector' do
         | 
| 137 137 |  | 
| 138 138 | 
             
                    it 'reports n_removed correctly' do
         | 
| 139 | 
            -
                      expect(bulk.execute | 
| 139 | 
            +
                      expect(bulk.execute.deleted_count).to eq(2)
         | 
| 140 140 | 
             
                    end
         | 
| 141 141 |  | 
| 142 142 | 
             
                    it 'deletes all matching documents' do
         | 
| @@ -156,7 +156,7 @@ shared_examples 'a bulk write object' do | |
| 156 156 | 
             
                    end
         | 
| 157 157 |  | 
| 158 158 | 
             
                    it 'reports n_removed correctly' do
         | 
| 159 | 
            -
                      expect(bulk.execute | 
| 159 | 
            +
                      expect(bulk.execute.deleted_count).to eq(1)
         | 
| 160 160 | 
             
                    end
         | 
| 161 161 |  | 
| 162 162 | 
             
                    it 'deletes all matching documents' do
         | 
| @@ -233,7 +233,7 @@ shared_examples 'a bulk write object' do | |
| 233 233 | 
             
                  end
         | 
| 234 234 |  | 
| 235 235 | 
             
                  it 'reports n_matched correctly' do
         | 
| 236 | 
            -
                    expect(bulk.execute | 
| 236 | 
            +
                    expect(bulk.execute.matched_count).to eq(1)
         | 
| 237 237 | 
             
                  end
         | 
| 238 238 |  | 
| 239 239 | 
             
                  it 'only applies the replacement to one matching document' do
         | 
| @@ -260,7 +260,7 @@ shared_examples 'a bulk write object' do | |
| 260 260 | 
             
                    end
         | 
| 261 261 |  | 
| 262 262 | 
             
                    it 'reports n_matched correctly' do
         | 
| 263 | 
            -
                      expect(bulk.execute | 
| 263 | 
            +
                      expect(bulk.execute.matched_count).to eq(0)
         | 
| 264 264 | 
             
                    end
         | 
| 265 265 |  | 
| 266 266 | 
             
                    it 'does not replace any documents' do
         | 
| @@ -331,19 +331,19 @@ shared_examples 'a bulk write object' do | |
| 331 331 | 
             
                context 'when a valid update document is specified' do
         | 
| 332 332 |  | 
| 333 333 | 
             
                  it 'reports n_modified correctly', if: write_command_enabled?  do
         | 
| 334 | 
            -
                    expect(bulk.execute | 
| 334 | 
            +
                    expect(bulk.execute.modified_count).to eq(1)
         | 
| 335 335 | 
             
                  end
         | 
| 336 336 |  | 
| 337 337 | 
             
                  it 'reports n_modified correctly', unless: write_command_enabled?  do
         | 
| 338 | 
            -
                    expect(bulk.execute | 
| 338 | 
            +
                    expect(bulk.execute.modified_count).to eq(nil)
         | 
| 339 339 | 
             
                  end
         | 
| 340 340 |  | 
| 341 341 | 
             
                  it 'reports n_upserted correctly' do
         | 
| 342 | 
            -
                    expect(bulk.execute | 
| 342 | 
            +
                    expect(bulk.execute.upserted_count).to eq(0)
         | 
| 343 343 | 
             
                  end
         | 
| 344 344 |  | 
| 345 345 | 
             
                  it 'reports n_matched correctly' do
         | 
| 346 | 
            -
                    expect(bulk.execute | 
| 346 | 
            +
                    expect(bulk.execute.matched_count).to eq(1)
         | 
| 347 347 | 
             
                  end
         | 
| 348 348 |  | 
| 349 349 | 
             
                  it 'applies the correct writes' do
         | 
| @@ -365,19 +365,23 @@ shared_examples 'a bulk write object' do | |
| 365 365 | 
             
                    end
         | 
| 366 366 |  | 
| 367 367 | 
             
                    it 'reports n_modified correctly', if: write_command_enabled?  do
         | 
| 368 | 
            -
                      expect(bulk.execute | 
| 368 | 
            +
                      expect(bulk.execute.modified_count).to eq(0)
         | 
| 369 369 | 
             
                    end
         | 
| 370 370 |  | 
| 371 371 | 
             
                    it 'reports n_modified correctly', unless: write_command_enabled?  do
         | 
| 372 | 
            -
                      expect(bulk.execute | 
| 372 | 
            +
                      expect(bulk.execute.modified_count).to eq(nil)
         | 
| 373 373 | 
             
                    end
         | 
| 374 374 |  | 
| 375 375 | 
             
                    it 'reports n_upserted correctly' do
         | 
| 376 | 
            -
                      expect(bulk.execute | 
| 376 | 
            +
                      expect(bulk.execute.upserted_count).to eq(1)
         | 
| 377 | 
            +
                    end
         | 
| 378 | 
            +
             | 
| 379 | 
            +
                    it 'returns the upserted ids', if: write_command_enabled? do
         | 
| 380 | 
            +
                      expect(bulk.execute.upserted_ids.size).to eq(1)
         | 
| 377 381 | 
             
                    end
         | 
| 378 382 |  | 
| 379 383 | 
             
                    it 'reports n_matched correctly' do
         | 
| 380 | 
            -
                      expect(bulk.execute | 
| 384 | 
            +
                      expect(bulk.execute.matched_count).to eq(0)
         | 
| 381 385 | 
             
                    end
         | 
| 382 386 |  | 
| 383 387 | 
             
                    it 'applies the correct writes' do
         | 
| @@ -444,19 +448,19 @@ shared_examples 'a bulk write object' do | |
| 444 448 | 
             
                context 'when a valid update document is specified' do
         | 
| 445 449 |  | 
| 446 450 | 
             
                  it 'reports n_modified correctly', if: write_command_enabled?  do
         | 
| 447 | 
            -
                    expect(bulk.execute | 
| 451 | 
            +
                    expect(bulk.execute.modified_count).to eq(2)
         | 
| 448 452 | 
             
                  end
         | 
| 449 453 |  | 
| 450 454 | 
             
                  it 'reports n_modified correctly', unless: write_command_enabled?  do
         | 
| 451 | 
            -
                    expect(bulk.execute | 
| 455 | 
            +
                    expect(bulk.execute.modified_count).to eq(nil)
         | 
| 452 456 | 
             
                  end
         | 
| 453 457 |  | 
| 454 458 | 
             
                  it 'reports n_upserted correctly' do
         | 
| 455 | 
            -
                    expect(bulk.execute | 
| 459 | 
            +
                    expect(bulk.execute.upserted_count).to eq(0)
         | 
| 456 460 | 
             
                  end
         | 
| 457 461 |  | 
| 458 462 | 
             
                  it 'reports n_matched correctly' do
         | 
| 459 | 
            -
                    expect(bulk.execute | 
| 463 | 
            +
                    expect(bulk.execute.matched_count).to eq(2)
         | 
| 460 464 | 
             
                  end
         | 
| 461 465 |  | 
| 462 466 | 
             
                  it 'applies the correct writes' do
         | 
| @@ -478,19 +482,19 @@ shared_examples 'a bulk write object' do | |
| 478 482 | 
             
                    end
         | 
| 479 483 |  | 
| 480 484 | 
             
                    it 'reports n_modified correctly', if: write_command_enabled?  do
         | 
| 481 | 
            -
                      expect(bulk.execute | 
| 485 | 
            +
                      expect(bulk.execute.modified_count).to eq(0)
         | 
| 482 486 | 
             
                    end
         | 
| 483 487 |  | 
| 484 488 | 
             
                    it 'reports n_modified correctly', unless: write_command_enabled?  do
         | 
| 485 | 
            -
                      expect(bulk.execute | 
| 489 | 
            +
                      expect(bulk.execute.modified_count).to eq(nil)
         | 
| 486 490 | 
             
                    end
         | 
| 487 491 |  | 
| 488 492 | 
             
                    it 'reports n_upserted correctly' do
         | 
| 489 | 
            -
                      expect(bulk.execute | 
| 493 | 
            +
                      expect(bulk.execute.upserted_count).to eq(1)
         | 
| 490 494 | 
             
                    end
         | 
| 491 495 |  | 
| 492 496 | 
             
                    it 'reports n_matched correctly' do
         | 
| 493 | 
            -
                      expect(bulk.execute | 
| 497 | 
            +
                      expect(bulk.execute.matched_count).to eq(0)
         | 
| 494 498 | 
             
                    end
         | 
| 495 499 |  | 
| 496 500 | 
             
                    it 'applies the correct writes' do
         |