I'm writing tests for functions that use transactions.
Transactions only work on replica sets or mongos :
pymongo.errors.OperationFailure: Transaction numbers are only allowed on a replica set member or mongos, full error: {'ok': 0.0, 'errmsg': 'Transaction numbers are only allowed on a replica set member or mongos', 'code': 20, 'codeName': 'IllegalOperation'}
I would like those tests to be skipped if the database is a standalone mongod instance.
How can I check from Python code (eg with a pymongo function) that I'm using an adequate environment?
I can configure the CI Pipeline to use a replica set. I can, and did, configure that on my machine. But I don't want those few tests to be a hassle for potential contributors, so I'd rather skip them.
Alternatively, I could catch the OperationFailure
and try to ensure it is exactly the error above, not another OperationFailure
, by matching the string, but this would be a sorry workaround.
Perhaps I could use something like
MongoClient('localhost', 27017).admin.command("replSetGetStatus")
Before going through a tough trial and error session, I'd be happy to get an informed advice.
Here is a way to check if the MongoDB instance is a replica-set:
Every mongod
instance has its own local database ( local
is the database name), which stores data used in the replication process, and other instance-specific data. The system.replset
collection in the local
database holds the replica set's configuration object as its single document.
To view this configuration, issue rs.conf()
from the mongo
shell. You can also query this collection directly (see below code used in a method).
client = pymongo.MongoClient(url)
collection = client.local.system.replset
try:
doc = collection.find()[0]
print(doc['_id'])
return True
except Exception as e:
print("local.system.replset doesn't exist: " + str(e))
return False
Note the code raises an exception if cursor is empty, ie, when the system.replset
collection doesn't exist in the local
database and the query fails (and the query fails for a standalone instance).
In the code, the doc['_id']
is the replica-set name.
Here's what I came up with:
def is_replica_set():
try:
pymongo.MongoClient().admin.command("replSetGetStatus")
return True
except pymongo.errors.OperationFailure:
return False
@pytest.mark.skipif(not is_replica_set(), reason="Replica set required")
def test_transaction():
...
Send {ismaster: 1}
command and follow the rules here for parsing the response.
Replica set node will have setName
field set in the response.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.