using System; using System.Collections.Generic; using System.Linq; using System.Text; using FluentAssertions; using Machine.Specifications; using MongoDB.Driver; namespace Mongo2GoTests.Runner { [Subject("Runner Transaction Test")] public class when_transaction_completes : MongoTransactionTest { private static TestDocument mainDocument; private static TestDocument dependentDocument; Establish context = () => { CreateConnection(); database.DropCollection(_mainCollectionName); database.DropCollection(_dependentCollectionName); _mainCollection.InsertOne(TestDocument.DummyData2()); _dependentCollection.InsertOne(TestDocument.DummyData2()); }; private Because of = () => { var filter = Builders.Filter.Where(x => x.IntTest == 23); var update = Builders.Update.Inc(i => i.IntTest, 10); using (var sessionHandle = client.StartSession()) { try { var i = 0; while (i < 10) { try { i++; sessionHandle.StartTransaction(new TransactionOptions( readConcern: ReadConcern.Local, writeConcern: WriteConcern.W1)); try { var first = _mainCollection.UpdateOne(sessionHandle, filter, update); var second = _dependentCollection.UpdateOne(sessionHandle, filter, update); } catch (Exception) { sessionHandle.AbortTransaction(); throw; } var j = 0; while (j < 10) { try { j++; sessionHandle.CommitTransaction(); break; } catch (MongoException e) { if (e.HasErrorLabel("UnknownTransactionCommitResult")) continue; throw; } } break; } catch (MongoException e) { if (e.HasErrorLabel("TransientTransactionError")) continue; throw; } } } catch (Exception) { } } mainDocument = _mainCollection.FindSync(Builders.Filter.Empty).FirstOrDefault(); dependentDocument = _dependentCollection.FindSync(Builders.Filter.Empty).FirstOrDefault(); }; It main_should_be_33 = () => mainDocument.IntTest.Should().Be(33); It dependent_should_be_33 = () => dependentDocument.IntTest.Should().Be(33); Cleanup cleanup = () => _runner.Dispose(); } [Subject("Runner Transaction Test")] public class when_transaction_is_aborted_before_commit : MongoTransactionTest { private static TestDocument mainDocument; private static TestDocument dependentDocument; private static TestDocument mainDocument_before_commit; private static TestDocument dependentDocument_before_commit; Establish context = () => { CreateConnection(); database.DropCollection(_mainCollectionName); database.DropCollection(_dependentCollectionName); _mainCollection.InsertOne(TestDocument.DummyData2()); _dependentCollection.InsertOne(TestDocument.DummyData2()); }; private Because of = () => { var filter = Builders.Filter.Where(x => x.IntTest == 23); var update = Builders.Update.Inc(i => i.IntTest, 10); using (var sessionHandle = client.StartSession()) { try { var i = 0; while (i < 2) { try { i++; sessionHandle.StartTransaction(new TransactionOptions( readConcern: ReadConcern.Local, writeConcern: WriteConcern.W1)); try { var first = _mainCollection.UpdateOne(sessionHandle, filter, update); var second = _dependentCollection.UpdateOne(sessionHandle, filter, update); mainDocument_before_commit = _mainCollection.FindSync(sessionHandle, Builders.Filter.Empty).ToList().FirstOrDefault(); dependentDocument_before_commit = _dependentCollection.FindSync(sessionHandle, Builders.Filter.Empty).ToList().FirstOrDefault(); } catch (Exception) { sessionHandle.AbortTransaction(); throw; } //Throw exception and do not commit throw new ApplicationException(); } catch (MongoException e) { if (e.HasErrorLabel("TransientTransactionError")) continue; throw; } } } catch (Exception) { } } mainDocument = _mainCollection.FindSync(Builders.Filter.Empty).FirstOrDefault(); dependentDocument = _dependentCollection.FindSync(Builders.Filter.Empty).FirstOrDefault(); }; It main_should_be_still_23_after_aborting = () => mainDocument.IntTest.Should().Be(23); It dependent_should_be_still_23_after_aborting = () => dependentDocument.IntTest.Should().Be(23); It main_should_be_33_before_aborting = () => mainDocument_before_commit.IntTest.Should().Be(33); It dependent_should_be_33_before_aborting = () => dependentDocument_before_commit.IntTest.Should().Be(33); Cleanup cleanup = () => _runner.Dispose(); } [Subject("Runner Transaction Test")] public class when_replica_set_not_ready_before_timeout_expires : MongoTransactionTest { private static Exception exception; Because of = () => exception = Catch.Exception(() => CreateConnection(0)); // this passes on Windows (TimeoutException as expected) // but breaks on my Mac (MongoDB.Driver.MongoCommandException: Command replSetInitiate failed: already initialized.) It should_throw_timeout_exception = () => { Console.WriteLine(exception.ToString()); exception.Should().BeOfType(); }; } }