jaraco / jaraco.mongodb

MongoDB Utilities including an oplog replay tool
MIT License
5 stars 2 forks source link

OperationFailure in test_index_deletion #27

Closed jaraco closed 3 years ago

jaraco commented 3 years ago
_____________________________________________ TestOplogReplication.test_index_deletion _____________________________________________

self = <test_oplog.TestOplogReplication object at 0x7fc2b22a71f0>, replicaset_factory = <itertools.starmap object at 0x7fc2b22a73a0>

    def test_index_deletion(self, replicaset_factory):
        """
        A delete index operation should be able to be applied to a replica
        """
        source = next(replicaset_factory).get_connection()
        dest = next(replicaset_factory).get_connection()
        source_oplog = oplog.Oplog(source.local.oplog.rs)
        before_ts = source_oplog.get_latest_ts()
        source.index_deletion_test.stuff.create_index("foo")
        for op in source_oplog.since(before_ts):
>           oplog.apply(dest, op)

jaraco/mongodb/tests/test_oplog.py:92: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
jaraco/mongodb/oplog.py:464: in apply
    db[dbname].command("applyOps", [op], codec_options=opts)
.tox/python/lib/python3.9/site-packages/pymongo/database.py:738: in command
    return self._command(sock_info, command, slave_ok, value,
.tox/python/lib/python3.9/site-packages/pymongo/database.py:626: in _command
    return sock_info.command(
.tox/python/lib/python3.9/site-packages/pymongo/pool.py:683: in command
    return command(self, dbname, spec, slave_ok,
.tox/python/lib/python3.9/site-packages/pymongo/network.py:159: in command
    helpers._check_command_response(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

response = {'$clusterTime': {'clusterTime': Timestamp(1605985832, 3), 'signature': {'hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x0...\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'keyId': 0}}, 'applied': 1, 'code': 115, 'codeName': 'CommandNotSupported', ...}
max_wire_version = 9, allowable_errors = None, parse_write_concern_error = False

    def _check_command_response(response, max_wire_version,
                                allowable_errors=None,
                                parse_write_concern_error=False):
        """Check the response to a command for errors.
        """
        if "ok" not in response:
            # Server didn't recognize our message as a command.
            raise OperationFailure(response.get("$err"),
                                   response.get("code"),
                                   response,
                                   max_wire_version)

        if parse_write_concern_error and 'writeConcernError' in response:
            _raise_write_concern_error(response['writeConcernError'])

        if response["ok"]:
            return

        details = response
        # Mongos returns the error details in a 'raw' object
        # for some errors.
        if "raw" in response:
            for shard in itervalues(response["raw"]):
                # Grab the first non-empty raw error from a shard.
                if shard.get("errmsg") and not shard.get("ok"):
                    details = shard
                    break

        errmsg = details["errmsg"]
        code = details.get("code")

        # For allowable errors, only check for error messages when the code is not
        # included.
        if allowable_errors:
            if code is not None:
                if code in allowable_errors:
                    return
            elif errmsg in allowable_errors:
                return

        # Server is "not master" or "recovering"
        if code in _NOT_MASTER_CODES:
            raise NotMasterError(errmsg, response)
        elif "not master" in errmsg or "node is recovering" in errmsg:
            raise NotMasterError(errmsg, response)

        # Other errors
        # findAndModify with upsert can raise duplicate key error
        if code in (11000, 11001, 12582):
            raise DuplicateKeyError(errmsg, code, response, max_wire_version)
        elif code == 50:
            raise ExecutionTimeout(errmsg, code, response, max_wire_version)
        elif code == 43:
            raise CursorNotFound(errmsg, code, response, max_wire_version)

>       raise OperationFailure(errmsg, code, response, max_wire_version)
E       pymongo.errors.OperationFailure: The createIndexes operation is not supported in applyOps mode, full error: {'applied': 1, 'code': 115, 'codeName': 'CommandNotSupported', 'errmsg': 'The createIndexes operation is not supported in applyOps mode', 'results': [False], 'ok': 0.0, '$clusterTime': {'clusterTime': Timestamp(1605985832, 3), 'signature': {'hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'keyId': 0}}, 'operationTime': Timestamp(1605985832, 3)}

.tox/python/lib/python3.9/site-packages/pymongo/helpers.py:160: OperationFailure

This operation worked in previous versions of MongoDB, but not in 4.4.

jaraco commented 3 years ago

I posted a request for help at server development forum, but the post is pending moderation, so I can't link it directly.

jaraco commented 3 years ago

Thanks to Dan for providing an answer. With MongoDB 4.4, the applyOps needs to be applied independently.