public void TickTest() { TransactionManager target = new TransactionManager(); string inputString = "begin(T1);beginRO(T2)"; target.Tick(inputString); Assert.AreEqual(1, target.CurrentTimeStamp); Assert.AreEqual(0, target.waitingTransactions.Count); Assert.AreEqual(2, target.activeTransactions.Count); // test ticking one read op that succeeds inputString = "R(T1, x4)"; target.Tick(inputString); Assert.AreEqual(2, target.CurrentTimeStamp); Assert.AreEqual(0, target.waitingTransactions.Count); Assert.AreEqual(2, target.activeTransactions.Count); // test ticking one write op that succeeds inputString = "W(T1, x6,5)"; target.Tick(inputString); Assert.AreEqual(0, target.waitingTransactions.Count); Assert.AreEqual(2, target.activeTransactions.Count); //foreach (Site site in target.sites.Values) //{ // DataItem item = site.GetDataItemForDebugging(6); // Assert.AreEqual(5, item.DirtyValue); // //Assert.AreEqual(3, item.NewValueTimeStamp); -- we dont really use newValueTimeStamp // Assert.AreEqual(1, item.NewValueTransId); //} // test ticking one read op that succeeds because transaction is read only // same time, enter another r/w transaction inputString = "begin(T3);R(T2, x6)"; List<Result> results = target.Tick(inputString); Assert.AreEqual(0, target.waitingTransactions.Count); Assert.AreEqual(3, target.activeTransactions.Count); Result ROResult = results.Find(matching => matching.IssuingTransaction == 2); Assert.AreEqual(Enumerations.ResultStatus.Success, ROResult.Status); Assert.AreEqual(60, ROResult.Val); // test ticking one write op that fails due to lock conflict // Since this transaction came in later than T1 which currently holds the lock, this transaction is aborted inputString = "W(T3, x6,10)"; results = target.Tick(inputString); Assert.AreEqual(0, target.waitingTransactions.Count); Assert.AreEqual(2, target.activeTransactions.Count); Assert.AreEqual(1, target.abortedTransactions.Count); foreach (Site site in target.sites.Values) { LockManagerTableEntry entry = site.GetCopyOfEntry(6); //Assert.AreEqual(3, entry.WaitingLocks.Peek().TransactionId); Assert.AreEqual(1, entry.ActiveLocks[0].TransactionId); } // enter another transaction for later inputString = "begin(T4)"; target.Tick(inputString); Assert.AreEqual(3, target.activeTransactions.Count); // 3 bacuse T3 should have aborted this tick // lock up x8 inputString = "W(T4, x8,10)"; target.Tick(inputString); // test a read that fails because its waiting for T4 inputString = "R(T1, x8)"; results = target.Tick(inputString); Assert.AreEqual(1, target.waitingTransactions.Count); Assert.AreEqual(2, target.activeTransactions.Count); ROResult = results[0]; Assert.AreEqual(Enumerations.ResultStatus.Failure, ROResult.Status); Assert.AreEqual(1, ROResult.IssuingTransaction); Assert.AreEqual(8, ROResult.DataItem); Assert.AreEqual(0, ROResult.Val); // test ticking a commit by an RO transaction inputString = "end(T2)"; results = target.Tick(inputString); Assert.AreEqual(1, target.waitingTransactions.Count); Assert.AreEqual(1, target.activeTransactions.Count); Assert.AreEqual(1, target.committedTransactions.Count); // test ticking a commit by a regular transaction inputString = "end(T4)"; results = target.Tick(inputString); Assert.AreEqual(2, target.committedTransactions.Count); Assert.AreEqual(1, target.waitingTransactions.Count); // because T1 cannot be freed yet, it needs another tick to try the request again Assert.AreEqual(0, target.activeTransactions.Count); // test ticking a commit that will fail because the site has failed since first access // by failing and recovering each site inputString = "end(T1)"; foreach (Site site in target.sites.Values) site.Fail(target.CurrentTimeStamp); foreach (Site site in target.sites.Values) site.Recover(); target.Tick(inputString); Assert.AreEqual(2, target.committedTransactions.Count); Assert.AreEqual(1, target.waitingTransactions.Count); // because we failed the sites T1 still cannot read Assert.AreEqual(0, target.activeTransactions.Count); // start another transaction, have it write into x8 and commit, this way T1 will be freed and be able to continue inputString = "begin(T6)"; target.Tick(inputString); inputString = "W(T6,x8,4)"; target.Tick(inputString); inputString = "end(T6)"; target.Tick(inputString); // tick again so T1 can be freed up target.Tick(""); Assert.AreEqual(3, target.committedTransactions.Count); Assert.AreEqual(0, target.waitingTransactions.Count); Assert.AreEqual(1, target.activeTransactions.Count); inputString = "end(T1)"; target.Tick(inputString); Assert.AreEqual(3, target.committedTransactions.Count); Assert.AreEqual(0, target.waitingTransactions.Count); Assert.AreEqual(0, target.activeTransactions.Count); Assert.AreEqual(2, target.abortedTransactions.Count); inputString = "fail(1)"; target.Tick(inputString); Assert.AreEqual(Enumerations.SiteStatus.Failed, target.sites[1].Status); int siteFailedTS = target.sites[1].LastFailed[target.sites[1].LastFailed.Count - 1]; Assert.AreEqual(17, siteFailedTS); inputString = "recover(1)"; target.Tick(inputString); Assert.AreEqual(Enumerations.SiteStatus.Active, target.sites[1].Status); }