def test_callback_not_retried_after_timeout(self): listener = OvertCommandListener() client = rs_client(event_listeners=[listener]) self.addCleanup(client.close) coll = client[self.db.name].test def callback(session): coll.insert_one({}, session=session) err = { 'ok': 0, 'errmsg': 'Transaction 7819 has been aborted.', 'code': 251, 'codeName': 'NoSuchTransaction', 'errorLabels': ['TransientTransactionError'], } raise OperationFailure(err['errmsg'], err['code'], err) # Create the collection. coll.insert_one({}) listener.results.clear() with client.start_session() as s: with PatchSessionTimeout(0): with self.assertRaises(OperationFailure): s.with_transaction(callback) self.assertEqual(listener.started_command_names(), ['insert', 'abortTransaction'])
def test_callback_not_retried_after_commit_timeout(self): listener = OvertCommandListener() client = rs_client(event_listeners=[listener]) self.addCleanup(client.close) coll = client[self.db.name].test def callback(session): coll.insert_one({}, session=session) # Create the collection. coll.insert_one({}) self.set_fail_point({ 'configureFailPoint': 'failCommand', 'mode': { 'times': 1 }, 'data': { 'failCommands': ['commitTransaction'], 'errorCode': 251, # NoSuchTransaction } }) self.addCleanup(self.set_fail_point, { 'configureFailPoint': 'failCommand', 'mode': 'off' }) listener.results.clear() with client.start_session() as s: with PatchSessionTimeout(0): with self.assertRaises(OperationFailure): s.with_transaction(callback) self.assertEqual(listener.started_command_names(), ['insert', 'commitTransaction'])
def test_transaction_starts_with_batched_write(self): if 'PyPy' in sys.version and client_context.tls: self.skipTest('PYTHON-2937 PyPy is so slow sending large ' 'messages over TLS that this test fails') # Start a transaction with a batch of operations that needs to be # split. listener = OvertCommandListener() client = rs_client(event_listeners=[listener]) coll = client[self.db.name].test coll.delete_many({}) listener.reset() self.addCleanup(client.close) self.addCleanup(coll.drop) large_str = '\0' * (10 * 1024 * 1024) ops = [InsertOne({'a': large_str}) for _ in range(10)] with client.start_session() as session: with session.start_transaction(): coll.bulk_write(ops, session=session) # Assert commands were constructed properly. self.assertEqual(['insert', 'insert', 'insert', 'commitTransaction'], listener.started_command_names()) first_cmd = listener.results['started'][0].command self.assertTrue(first_cmd['startTransaction']) lsid = first_cmd['lsid'] txn_number = first_cmd['txnNumber'] for event in listener.results['started'][1:]: self.assertNotIn('startTransaction', event.command) self.assertEqual(lsid, event.command['lsid']) self.assertEqual(txn_number, event.command['txnNumber']) self.assertEqual(10, coll.count_documents({}))
def test_commit_not_retried_after_timeout(self): listener = OvertCommandListener() client = rs_client(event_listeners=[listener]) coll = client[self.db.name].test def callback(session): coll.insert_one({}, session=session) # Create the collection. coll.insert_one({}) self.set_fail_point({ 'configureFailPoint': 'failCommand', 'mode': { 'times': 2 }, 'data': { 'failCommands': ['commitTransaction'], 'closeConnection': True } }) self.addCleanup(self.set_fail_point, { 'configureFailPoint': 'failCommand', 'mode': 'off' }) listener.results.clear() with client.start_session() as s: with PatchSessionTimeout(0): with self.assertRaises(ConnectionFailure): s.with_transaction(callback) # One insert for the callback and two commits (includes the automatic # retry). self.assertEqual(listener.started_command_names(), ['insert', 'commitTransaction', 'commitTransaction'])
def test_commit_not_retried_after_timeout(self): listener = OvertCommandListener() client = rs_client(event_listeners=[listener]) coll = client[self.db.name].test def callback(session): coll.insert_one({}, session=session) # Create the collection. coll.insert_one({}) self.set_fail_point({ 'configureFailPoint': 'failCommand', 'mode': {'times': 2}, 'data': { 'failCommands': ['commitTransaction'], 'closeConnection': True}}) self.addCleanup(self.set_fail_point, { 'configureFailPoint': 'failCommand', 'mode': 'off'}) listener.results.clear() with client.start_session() as s: with PatchSessionTimeout(0): with self.assertRaises(ConnectionFailure): s.with_transaction(callback) # One insert for the callback and two commits (includes the automatic # retry). self.assertEqual(listener.started_command_names(), ['insert', 'commitTransaction', 'commitTransaction'])
def test_callback_not_retried_after_commit_timeout(self): listener = OvertCommandListener() client = rs_client(event_listeners=[listener]) coll = client[self.db.name].test def callback(session): coll.insert_one({}, session=session) # Create the collection. coll.insert_one({}) self.set_fail_point({ 'configureFailPoint': 'failCommand', 'mode': {'times': 1}, 'data': { 'failCommands': ['commitTransaction'], 'errorCode': 251, # NoSuchTransaction }}) self.addCleanup(self.set_fail_point, { 'configureFailPoint': 'failCommand', 'mode': 'off'}) listener.results.clear() with client.start_session() as s: with PatchSessionTimeout(0): with self.assertRaises(OperationFailure): s.with_transaction(callback) self.assertEqual(listener.started_command_names(), ['insert', 'commitTransaction'])
def test_callback_not_retried_after_timeout(self): listener = OvertCommandListener() client = rs_client(event_listeners=[listener]) coll = client[self.db.name].test def callback(session): coll.insert_one({}, session=session) err = { 'ok': 0, 'errmsg': 'Transaction 7819 has been aborted.', 'code': 251, 'codeName': 'NoSuchTransaction', 'errorLabels': ['TransientTransactionError'], } raise OperationFailure(err['errmsg'], err['code'], err) # Create the collection. coll.insert_one({}) listener.results.clear() with client.start_session() as s: with PatchSessionTimeout(0): with self.assertRaises(OperationFailure): s.with_transaction(callback) self.assertEqual(listener.started_command_names(), ['insert', 'abortTransaction'])