public void Link_DeleteParentTest() { TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_DisableContextSync); // add a work item on source side string title1 = string.Format("Parent {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemId1 = SourceAdapter.AddWorkItem("Bug", title1, "description1"); string title2 = string.Format("Child {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemId2 = SourceAdapter.AddWorkItem("Bug", title2, "description2"); RunAndNoValidate(); TfsSourceAdapter.AddParentChildLink(workitemId1, workitemId2); RunAndNoValidate(true); TfsSourceAdapter.DeleteParentChildLink(workitemId1, workitemId2); RunAndNoValidate(true); // verify there's no conflicts raised ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(0, conflicts.Count, "There should be no conflicts"); // verify sync result WitDiffResult result = GetDiffResult(); // ignore Area/Iteration path mismatches VerifySyncResult(result, new List <string> { FIELD_ITERATION_PATH, FIELD_AREA_PATH }); int mirroredId = QueryMirroredWorkItemID(workitemId1); Assert.AreEqual(0, TfsTargetAdapter.GetRelatedLinkCount(mirroredId)); }
public void Mapping_ConditionalExplicitValueMapWildCardinTargetValueTest() { TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_DisableContextSync); TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(SetConditionalExplicitPriorityValueWithWildCardinTargetValueMap); // add a work item on source side int workitemId = SourceAdapter.AddWorkItem("Bug", "title", ConditionalValueMapDescription); WITChangeAction action1 = new WITChangeAction(); action1.Priority = "2"; SourceAdapter.UpdateWorkItem(workitemId, action1); RunAndNoValidate(); // verify there's no conflicts raised ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(0, conflicts.Count, "There should be no conflicts"); // verify sync result excluding expected mismatches WitDiffResult result = GetDiffResult(); VerifySyncResult(result, new List <string> { FIELD_ITERATION_PATH, FIELD_AREA_PATH, FIELD_PRIORITY }); // P1 == P2 int targetId = QueryTargetWorkItemID(workitemId); string sourcePriority = SourceAdapter.GetFieldValue(workitemId, FIELD_PRIORITY); string targetPriority = TargetAdapter.GetFieldValue(targetId, FIELD_PRIORITY); Assert.AreEqual(sourcePriority, "2"); Assert.AreEqual(targetPriority, "2"); }
public void Mapping_AggregatedFieldTest() { TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_DisableContextSync); TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(SetAggregatedFieldMap); // add a work item on source side int workitemId = SourceAdapter.AddWorkItem("Bug", "title", "description1"); RunAndNoValidate(); // verify there's no conflicts raised ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(0, conflicts.Count, "There should be no conflicts"); // Title <-> Description int targetId = QueryTargetWorkItemID(workitemId); string srcTitle = SourceAdapter.GetFieldValue(workitemId, FIELD_TITLE); string srcRev = SourceAdapter.GetFieldValue(workitemId, "System.Rev"); string tarDesc = TargetAdapter.GetFieldValue(targetId, FIELD_DESCRIPTION); Assert.AreEqual(tarDesc, string.Format(AggregationFormat, srcTitle, srcRev)); }
public void Mapping_ExcludeFieldMapTest() { TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_DisableContextSync); TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(SetExcludePriorityFieldMap); TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_EnableBypassRulesOnTarget); // add a work item on source side string title = string.Format("{0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemId = SourceAdapter.AddWorkItem("Bug", title, "description1"); RunAndNoValidate(); // verify there's no conflicts raised ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(0, conflicts.Count, "There should be no conflicts"); // verify sync result excluding expected mismatches WitDiffResult result = GetDiffResult(); VerifySyncResult(result, new List <string> { FIELD_ITERATION_PATH, FIELD_AREA_PATH, FIELD_TITLE, FIELD_DESCRIPTION }); int mirroredId = QueryMirroredWorkItemID(workitemId); string srcTitle = SourceAdapter.GetFieldValue(workitemId, FIELD_TITLE); string srcDesc = SourceAdapter.GetFieldValue(workitemId, FIELD_DESCRIPTION); string tarTitle = TargetAdapter.GetFieldValue(mirroredId, FIELD_TITLE); string tarDesc = TargetAdapter.GetFieldValue(mirroredId, FIELD_DESCRIPTION); Assert.AreEqual(tarTitle, srcTitle); Assert.AreEqual(string.Empty, tarDesc); }
public void Attachment_AttachmentTest() { TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_EnableBypassRulesOnTarget); // add a work item on source side string title = string.Format("{0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemId = SourceAdapter.AddWorkItem("Bug", title, "description1"); WITAttachmentChangeAction action1 = new WITAttachmentChangeAction(); action1.AddAttachment(new WITAttachment("attachment1.txt", "comment 1")); SourceAdapter.UpdateAttachment(workitemId, action1); RunAndNoValidate(); // verify there's no conflicts raised ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(0, conflicts.Count, "There should be no conflicts"); // verify migration result VerifySyncResult(); }
public void Link_TwoParentsTest() { // Legend: x->y (y is a parent of x) // T1: Source: c->b->a // T2: Sync // T3: Target: c->b->a // T4: Source: delete c->b, add a->c ==> b->a->c // Target: delete b->a, add a->b ==> a->b, c->b (b has two children) // T5: Sync // add a work item on source side int sourceIdA = SourceAdapter.AddWorkItem("Bug", "A", "A"); int sourceIdB = SourceAdapter.AddWorkItem("Bug", "B", "B"); int sourceIdC = SourceAdapter.AddWorkItem("Bug", "C", "C"); RunAndNoValidate(); // T1-T3: c->b->a TfsSourceAdapter.AddParentChildLink(sourceIdB, sourceIdC); TfsSourceAdapter.AddParentChildLink(sourceIdA, sourceIdB); RunAndNoValidate(true); // T4: // Source: delete c->b, add a->c ==> b->a->c (a is the child of c) TfsSourceAdapter.DeleteParentChildLink(sourceIdB, sourceIdC); TfsSourceAdapter.AddParentChildLink(sourceIdC, sourceIdA); // Target: delete b->a, add a->b ==> a->b, c->b (a is the child of b) int targetId1 = QueryTargetWorkItemID(sourceIdA); int targetId2 = QueryTargetWorkItemID(sourceIdB); int targetIdC = QueryTargetWorkItemID(sourceIdC); TfsTargetAdapter.DeleteParentChildLink(targetId1, targetId2); TfsTargetAdapter.AddParentChildLink(targetId2, targetId1); // after sync: // source: b->a->c // target: a->b (adding a->c is conflicted) RunAndNoValidate(true); // verify the expected conflict ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Guid TFSMulitpleParentLinkConflictTypeReferenceName = new Guid("ADCE870C-33C0-46bc-9350-31660A463F9A"); // Workaround for Bug 529648: Accept 1 or more conflicts. We should only generate 1 conflict, but for Two-way scenarios we generate 2. Assert.IsTrue(conflicts.Count > 0, "There should be 1 or more conflicts"); foreach (RTConflict conflict in conflicts) { Assert.IsTrue(TFSMulitpleParentLinkConflictTypeReferenceName.Equals(conflict.ConflictTypeReference.Value.ReferenceName), "It should be a TFSMultipleParentLinkConflict"); } // fix the hierarchy on target, delete a->b // target: a, b, c TfsTargetAdapter.DeleteParentChildLink(targetId2, targetId1); foreach (RTConflict conflict in conflicts) { // resolve the conflict(s) by taking source side changes conflictResolver.TryResolveConflict(conflict, new ManualConflictResolutionAction(), "/"); } // restart the migration tool, after sync // source: b->a->c // target: a->c RunAndNoValidate(true); conflicts = conflictResolver.GetConflicts(); if (TestEnvironment.MigrationTestType == MigrationTestType.OneWay) { Assert.IsTrue(conflicts.Count == 0, "There should be no conflict"); // One way migration should have source/target out of sync Assert.AreEqual(2, TfsSourceAdapter.GetRelatedLinkCount(sourceIdA)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdB)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdC)); } else { // In two-way case, add a->b on Target at T4 above causes multi-parent conflict // when migrated back to source because a->c already exists on source. Assert.IsTrue(conflicts.Count == 1, "There should be one conflict"); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdA)); Assert.AreEqual(0, TfsSourceAdapter.GetRelatedLinkCount(sourceIdB)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdC)); } Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(targetId1)); Assert.AreEqual(0, TfsTargetAdapter.GetRelatedLinkCount(targetId2)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(targetIdC)); }
public void Link_CyclicLinkTest() { // Legend: x->y (y is a parent of x) // T1: Source: a->b->c d // T2: Sync // T3: Target: a->b->c d // T4: Source: delete b->c, add c->a ==> a->b c->a d // Target: delete b->c, add b->d , d->c ==> a->b->d->c // T5: Sync // We should detect cyclic link and raise a conflict // add a work item on source side int sourceIdA = SourceAdapter.AddWorkItem("Bug", "A", "A"); int sourceIdB = SourceAdapter.AddWorkItem("Bug", "B", "B"); int sourceIdC = SourceAdapter.AddWorkItem("Bug", "C", "C"); int sourceIdD = SourceAdapter.AddWorkItem("Bug", "D", "D"); RunAndNoValidate(); // add b->c TfsSourceAdapter.AddParentChildLink(sourceIdC, sourceIdB); // add a->b TfsSourceAdapter.AddParentChildLink(sourceIdB, sourceIdA); // after sync, // Source: a->b->c d // Target: a->b->c d RunAndNoValidate(true); int targetIdA = QueryTargetWorkItemID(sourceIdA); int targetIdB = QueryTargetWorkItemID(sourceIdB); int targetIdC = QueryTargetWorkItemID(sourceIdC); int targetIdD = QueryTargetWorkItemID(sourceIdD); // Source: delete b->c, add c->a, now source is c->a->b d TfsSourceAdapter.DeleteParentChildLink(sourceIdC, sourceIdB); TfsSourceAdapter.AddParentChildLink(sourceIdA, sourceIdC); // Target: delete b->c, add b->d , d->c, now target is a->b->d->c TfsTargetAdapter.DeleteParentChildLink(targetIdC, targetIdB); TfsTargetAdapter.AddParentChildLink(targetIdD, targetIdB); TfsTargetAdapter.AddParentChildLink(targetIdC, targetIdD); // c->a from source will create cyclic link on target RunAndNoValidate(true); // verify the expected conflict ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Guid TFSCyclicLinkConflictTypeReferenceName = new Guid("BF1277E9-A218-4a2d-8C3C-A9501D30ECD5"); // Workaround for Bug 529648: Accept 1 or more conflicts. We should only generate 1 conflict, but for Two-way scenarios we generate 2. Assert.IsTrue(conflicts.Count > 0, "There should be 1 or more conflicts"); foreach (RTConflict conflict in conflicts) { Assert.IsTrue(TFSCyclicLinkConflictTypeReferenceName.Equals(conflict.ConflictTypeReference.Value.ReferenceName), "Conflict should be a TFS cyclic link reference conflict"); } // fix the hierarchy on target, delete d->c => a->b->d c TfsTargetAdapter.DeleteParentChildLink(targetIdC, targetIdD); foreach (RTConflict rtConflict in conflicts) { // resolve the conflict by retrying conflictResolver.TryResolveConflict(rtConflict, new ManualConflictResolutionAction(), "/"); // restart the migration tool, after sync, RunAndNoValidate(true); } conflicts = conflictResolver.GetConflicts(); Assert.IsTrue(conflicts.Count == 0, "There should be no conflict"); // hiearchy should be c->a->b->d Assert.AreEqual(2, TfsTargetAdapter.GetRelatedLinkCount(targetIdA)); Assert.AreEqual(2, TfsTargetAdapter.GetRelatedLinkCount(targetIdB)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(targetIdC)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(targetIdD)); if (TestEnvironment.MigrationTestType == MigrationTestType.OneWay) { // for one-way migration the source should be out of sync with the target now Assert.AreEqual(2, TfsSourceAdapter.GetRelatedLinkCount(sourceIdA)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdB)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdC)); Assert.AreEqual(0, TfsSourceAdapter.GetRelatedLinkCount(sourceIdD)); } else { // Two-way sync should be in sync with target now // TODO: why does this work for TwoWayLeft but not TwoWayRight? Assert.AreEqual(2, TfsSourceAdapter.GetRelatedLinkCount(sourceIdA)); Assert.AreEqual(2, TfsSourceAdapter.GetRelatedLinkCount(sourceIdB)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdC)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdD)); // verify sync result WitDiffResult result = GetDiffResult(); // ignore Area/Iteration path mismatches VerifySyncResult(result, new List <string> { FIELD_ITERATION_PATH, FIELD_AREA_PATH }); } }
public void Link_CyclicLinkSamePairTest() { // Legend: x->y (y is a parent of x) // T1: Source: a b // T2: Sync // T3: Target: a b // T4: Source: add a->b ==> a->b // Target: add b->a ==> b->a // T5: Sync // We should detect cyclic link and raise a conflict // add a work item on source side int sourceIdA = SourceAdapter.AddWorkItem("Bug", "A", "A"); int sourceIdB = SourceAdapter.AddWorkItem("Bug", "B", "B"); RunAndNoValidate(); int targetId1 = QueryTargetWorkItemID(sourceIdA); int targetId2 = QueryTargetWorkItemID(sourceIdB); TfsSourceAdapter.AddParentChildLink(sourceIdB, sourceIdA); TfsTargetAdapter.AddParentChildLink(targetId1, targetId2); RunAndNoValidate(true); // verify the expected conflict ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Guid TFSCyclicLinkConflictTypeReferenceName = new Guid("BF1277E9-A218-4a2d-8C3C-A9501D30ECD5"); // Workaround for Bug 529648: Accept 1 or more conflicts. We should only generate 1 conflict, but for Two-way scenarios we generate 2. Assert.IsTrue(conflicts.Count > 0, "There should be 1 or more conflicts"); foreach (RTConflict conflict in conflicts) { Assert.IsTrue(TFSCyclicLinkConflictTypeReferenceName.Equals(conflict.ConflictTypeReference.Value.ReferenceName), "Conflict should be a TFS cyclic link reference conflict"); } // fix the hierarchy on target, delete b->a ==> a b TfsTargetAdapter.DeleteParentChildLink(targetId1, targetId2); foreach (RTConflict conflict in conflicts) { // resolve the conflict by retrying conflictResolver.TryResolveConflict(conflict, new ManualConflictResolutionAction(), "/"); // restart the session RunAndNoValidate(true); } conflicts = conflictResolver.GetConflicts(); if (TestEnvironment.MigrationTestType == MigrationTestType.OneWay) { Assert.IsTrue(conflicts.Count == 0, "There should be no conflict"); } else { // In two-way cases, migration back from target to source will still generate a conflict // because we have not deleted a->b on the source Assert.IsTrue(conflicts.Count == 1, "There should be one conflict"); } Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdA)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(sourceIdB)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(targetId1)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(targetId2)); // verify sync result WitDiffResult result = GetDiffResult(); // ignore Area/Iteration path mismatches VerifySyncResult(result, new List <string> { FIELD_ITERATION_PATH, FIELD_AREA_PATH }); }
public void LinkScenarioExperienceTest() { const int ExperienceCount = 10; // On Left add 1 Scenario and a bunch of Experiences int sourceScenarioId = SourceAdapter.AddWorkItem("Scenario", "scenario title", "source scenario description"); Console.WriteLine("Source Scenario ID = {0}", sourceScenarioId); int[] sourceExperienceIDs = new int[ExperienceCount]; int[] targetExperienceIDs = new int[ExperienceCount]; for (int index = 0; index < ExperienceCount; index++) { string title = string.Format("Experience {0}", index); sourceExperienceIDs[index] = SourceAdapter.AddWorkItem("Experience", title, title); } // sync RunAndNoValidate(); // get the migrated target ID int targetScenarioId = QueryTargetWorkItemID(sourceScenarioId); Console.WriteLine("Target Scenario ID = {0}", targetScenarioId); // Modify some field of the scenario: this should create a revision of the work item that has no link changes to get migrated WITChangeAction sourceAction = new WITChangeAction() { History = "Adding scenario-experience links on the source side", }; SourceAdapter.UpdateWorkItem(sourceScenarioId, sourceAction); // Link source scenario to all the experiences for (int index = 0; index < ExperienceCount; index++) { TfsSourceAdapter.AddScenarioExperienceLink(sourceScenarioId, sourceExperienceIDs[index]); } // Modify the history again forcing the above links to get migrated WITChangeAction sourceAction2 = new WITChangeAction() { AssignedTo = "billbar", }; SourceAdapter.UpdateWorkItem(sourceScenarioId, sourceAction2); for (int index = 0; index < ExperienceCount; index++) { Console.WriteLine("Getting mirrored TargetWorkItemID for target experience: " + sourceExperienceIDs[index].ToString()); targetExperienceIDs[index] = QueryTargetWorkItemID(sourceExperienceIDs[index]); Console.WriteLine("Mirrored TargetWorkItemID: " + targetExperienceIDs[index].ToString()); } /* * // on target modify field of the mirrored Ids of each of the Experience * // This should cause them to get sync'd back to the source side * WITChangeAction targetAction = new WITChangeAction() * { * History = "Touch the target experience work item", * }; * foreach (int targetExperienceID in targetExperienceIDs) * { * TargetAdapter.UpdateWorkItem(targetExperienceID, targetAction); * } */ // sync RunAndNoValidate(true); ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(0, conflicts.Count, "There should be no conflicts"); // verify sync result WitDiffResult result = GetDiffResult(); // ignore Area/Iteration path mismatches VerifySyncResult(result, new List <string> { FIELD_ITERATION_PATH, FIELD_AREA_PATH }); Assert.AreEqual(ExperienceCount, TfsSourceAdapter.GetRelatedLinkCount(sourceScenarioId)); Assert.AreEqual(ExperienceCount, TfsSourceAdapter.GetRelatedLinkCount(targetScenarioId)); }
public void Link_MultiAddDeleteRelatedLinkTest() { for (int i = 0; i < 7; ++i) { // add a work item on source side string title = "title " + i.ToString(); int id = SourceAdapter.AddWorkItem("Bug", title, "description1"); SourceWorkItemIdList[i] = id; } TfsSourceAdapter.AddRelatedWorkItemLink(SourceWorkItemIdList[1], SourceWorkItemIdList[0]); TfsSourceAdapter.AddRelatedWorkItemLink(SourceWorkItemIdList[1], SourceWorkItemIdList[2]); TfsSourceAdapter.AddRelatedWorkItemLink(SourceWorkItemIdList[1], SourceWorkItemIdList[3]); RunAndNoValidate(); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[0])); Assert.AreEqual(3, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[1])); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[2])); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[3])); TfsSourceAdapter.DeleteRelatedWorkItemLink(SourceWorkItemIdList[1], SourceWorkItemIdList[0]); TfsSourceAdapter.DeleteRelatedWorkItemLink(SourceWorkItemIdList[1], SourceWorkItemIdList[2]); TfsSourceAdapter.DeleteRelatedWorkItemLink(SourceWorkItemIdList[1], SourceWorkItemIdList[3]); TfsSourceAdapter.AddRelatedWorkItemLink(SourceWorkItemIdList[1], SourceWorkItemIdList[4]); TfsSourceAdapter.AddRelatedWorkItemLink(SourceWorkItemIdList[1], SourceWorkItemIdList[5]); TfsSourceAdapter.AddRelatedWorkItemLink(SourceWorkItemIdList[1], SourceWorkItemIdList[6]); RunAndNoValidate(true); RunAndNoValidate(true); // verify there's no conflicts raised ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(0, conflicts.Count, "There should be no conflicts"); //// verify sync result //WitDiffResult result = GetDiffResult(); //// ignore Area/Iteration path mismatches //VerifySyncResult(result, new List<string> { FIELD_ITERATION_PATH, FIELD_AREA_PATH }); Assert.AreEqual(0, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[0])); Assert.AreEqual(3, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[1])); Assert.AreEqual(0, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[2])); Assert.AreEqual(0, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[3])); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[4])); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[5])); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(SourceWorkItemIdList[6])); int[] targetWorkItemIds = new int[SourceWorkItemIdList.Count]; for (int i = 0; i < SourceWorkItemIdList.Count; ++i) { targetWorkItemIds[i] = QueryTargetWorkItemID(SourceWorkItemIdList[i]); } Assert.AreEqual(0, TfsTargetAdapter.GetRelatedLinkCount(targetWorkItemIds[0])); Assert.AreEqual(3, TfsTargetAdapter.GetRelatedLinkCount(targetWorkItemIds[1])); Assert.AreEqual(0, TfsTargetAdapter.GetRelatedLinkCount(targetWorkItemIds[2])); Assert.AreEqual(0, TfsTargetAdapter.GetRelatedLinkCount(targetWorkItemIds[3])); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(targetWorkItemIds[4])); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(targetWorkItemIds[5])); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(targetWorkItemIds[6])); }
public void Link_TwoParentsTest() { TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_DisableContextSync); TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_SetOneWayNoContextSync); // Legend: x->y (y is a parent of x) // T1: Source: c->b->a // T2: Sync // T3: Target: c->b->a // T4: Source: delete c->b, add a->c ==> b->a->c // Target: delete b->a, add a->b ==> a->b, c->b (b has two children) // T5: Sync // add a work item on source side string title1 = string.Format("A {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemIdA = SourceAdapter.AddWorkItem("Bug", title1, "A"); string title2 = string.Format("B {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemIdB = SourceAdapter.AddWorkItem("Bug", title2, "B"); string title3 = string.Format("C {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemIdC = SourceAdapter.AddWorkItem("Bug", title3, "C"); TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(SetTargetFilterString); RunAndNoValidate(); // T1-T3: c->b->a TfsSourceAdapter.AddParentChildLink(workitemIdB, workitemIdC); TfsSourceAdapter.AddParentChildLink(workitemIdA, workitemIdB); RunAndNoValidate(true); // T4: // Source: delete c->b, add a->c ==> b->a->c (a is the child of c) TfsSourceAdapter.DeleteParentChildLink(workitemIdB, workitemIdC); TfsSourceAdapter.AddParentChildLink(workitemIdC, workitemIdA); // Target: delete b->a, add a->b ==> a->b, c->b (a is the child of b) int mirroredIdA = QueryMirroredWorkItemID(workitemIdA); int mirroredIdB = QueryMirroredWorkItemID(workitemIdB); int mirroredIdC = QueryMirroredWorkItemID(workitemIdC); TfsTargetAdapter.DeleteParentChildLink(mirroredIdA, mirroredIdB); TfsTargetAdapter.AddParentChildLink(mirroredIdB, mirroredIdA); // after sync: // source: b->a->c // target: a->b (adding a->c is conflicted) RunAndNoValidate(true); // verify the expected conflict ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(1, conflicts.Count, "There should be 1 conflict"); Guid TFSMulitpleParentLinkConflictTypeReferenceName = new Guid("ADCE870C-33C0-46bc-9350-31660A463F9A"); Assert.IsTrue(TFSMulitpleParentLinkConflictTypeReferenceName.Equals(conflicts[0].ConflictTypeReference.Value.ReferenceName), "It should be a TFSMulitpleParentLinkConflict"); // fix the hierarchy on target, delete a->b // target: a, b, c TfsTargetAdapter.DeleteParentChildLink(mirroredIdB, mirroredIdA); // resolve the conflict by taking source side changes conflictResolver.TryResolveConflict(conflicts[0], new ManualConflictResolutionAction(), "/"); // restart the migration tool, after sync // source: b->a->c // target: a->c RunAndNoValidate(true); conflicts = conflictResolver.GetConflicts(); Assert.IsTrue(conflicts.Count == 0, "There should be no conflict"); Assert.AreEqual(2, TfsSourceAdapter.GetRelatedLinkCount(workitemIdA)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(workitemIdB)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(workitemIdC)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(mirroredIdA)); Assert.AreEqual(0, TfsTargetAdapter.GetRelatedLinkCount(mirroredIdB)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(mirroredIdC)); }
private void Link_CyclicLinkScenarioTwoWay() { // Legend: x->y (y is a parent of x) // T1: Source: a->b->c d // T2: Sync // T3: Target: a->b->c d // T4: Source: delete b->c, add c->a ==> a->b c->a d // Target: delete b->c, add b->d , d->c ==> a->b->d->c // T5: Sync // We should detect cyclic link and raise a conflict // add a work item on source side string titleA = string.Format("A {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemIdA = SourceAdapter.AddWorkItem("Bug", titleA, "A"); string titleB = string.Format("B {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemIdB = SourceAdapter.AddWorkItem("Bug", titleB, "B"); string titleC = string.Format("C {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemIdC = SourceAdapter.AddWorkItem("Bug", titleC, "C"); string titleD = string.Format("C {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemIdD = SourceAdapter.AddWorkItem("Bug", titleD, "D"); TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(SetTargetFilterString); RunAndNoValidate(); TfsSourceAdapter.AddParentChildLink(workitemIdC, workitemIdB); TfsSourceAdapter.AddParentChildLink(workitemIdB, workitemIdA); // after sync, // Source: a->b->c d // Target: a->b->c d RunAndNoValidate(true); // Source: delete b->c, add c->a => c->a->b d TfsSourceAdapter.DeleteParentChildLink(workitemIdC, workitemIdB); TfsSourceAdapter.AddParentChildLink(workitemIdA, workitemIdC); // Target: delete b->c, add b->d , d->c => a->b->d->c int mirroredIdA = QueryMirroredWorkItemID(workitemIdA); int mirroredIdB = QueryMirroredWorkItemID(workitemIdB); int mirroredIdC = QueryMirroredWorkItemID(workitemIdC); int mirroredIdD = QueryMirroredWorkItemID(workitemIdD); TfsTargetAdapter.DeleteParentChildLink(mirroredIdC, mirroredIdB); TfsTargetAdapter.AddParentChildLink(mirroredIdD, mirroredIdB); TfsTargetAdapter.AddParentChildLink(mirroredIdC, mirroredIdD); // c->a from source will create cyclic link on target RunAndNoValidate(true); // verify the expected conflict ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(2, conflicts.Count, "There should be 2 conflicts"); Guid TFSCyclicLinkConflictTypeReferenceName = new Guid("BF1277E9-A218-4a2d-8C3C-A9501D30ECD5"); Assert.IsTrue(TFSCyclicLinkConflictTypeReferenceName.Equals(conflicts[0].ConflictTypeReference.Value.ReferenceName), "It should be a TFS cyclic link reference conflict"); Assert.IsTrue(TFSCyclicLinkConflictTypeReferenceName.Equals(conflicts[1].ConflictTypeReference.Value.ReferenceName), "It should be a TFS cyclic link reference conflict"); // fix the hierarchy on target, delete a->b => a b->d->c TfsTargetAdapter.DeleteParentChildLink(mirroredIdB, mirroredIdA); // resolve the conflict by retrying conflictResolver.TryResolveConflict(conflicts[0], new ManualConflictResolutionAction(), "/"); // restart the migration tool, after sync, RunAndNoValidate(true); // resolve the conflict by retrying conflictResolver.TryResolveConflict(conflicts[1], new ManualConflictResolutionAction(), "/"); RunAndNoValidate(true); conflicts = conflictResolver.GetConflicts(); Assert.IsTrue(conflicts.Count == 0, "There should be no conflict"); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(workitemIdA)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(workitemIdB)); Assert.AreEqual(2, TfsSourceAdapter.GetRelatedLinkCount(workitemIdC)); Assert.AreEqual(2, TfsSourceAdapter.GetRelatedLinkCount(workitemIdD)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(mirroredIdA)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(mirroredIdB)); Assert.AreEqual(2, TfsTargetAdapter.GetRelatedLinkCount(mirroredIdC)); Assert.AreEqual(2, TfsTargetAdapter.GetRelatedLinkCount(mirroredIdD)); }
public void Link_CyclicLinkSamePairBidirectionalTest() { TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_DisableContextSync); TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(ConfigCustomizer.CustomActions_SetBidirectionalNoContextSync); // Legend: x->y (y is a parent of x) // T1: Source: a b // T2: Sync // T3: Target: a b // T4: Source: add a->b ==> a->b // Target: add b->a ==> b->a // T5: Sync // We should detect cyclic link and raise a conflict // add a work item on source side string titleA = string.Format("A {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemIdA = SourceAdapter.AddWorkItem("Bug", titleA, "A"); string titleB = string.Format("B {0} {1}", TestContext.TestName, DateTime.Now.ToString("HH'_'mm'_'ss")); int workitemIdB = SourceAdapter.AddWorkItem("Bug", titleB, "B"); TestEnvironment.CustomActions += new MigrationTestEnvironment.Customize(SetTargetFilterString); RunAndNoValidate(); int mirroredIdA = QueryMirroredWorkItemID(workitemIdA); int mirroredIdB = QueryMirroredWorkItemID(workitemIdB); TfsSourceAdapter.AddParentChildLink(workitemIdB, workitemIdA); TfsTargetAdapter.AddParentChildLink(mirroredIdA, mirroredIdB); RunAndNoValidate(true); // verify the expected conflict ConflictResolver conflictResolver = new ConflictResolver(Configuration); List <RTConflict> conflicts = conflictResolver.GetConflicts(); Assert.AreEqual(2, conflicts.Count, "There should be 2 conflicts"); Guid TFSCyclicLinkConflictTypeReferenceName = new Guid("BF1277E9-A218-4a2d-8C3C-A9501D30ECD5"); Assert.IsTrue(TFSCyclicLinkConflictTypeReferenceName.Equals(conflicts[0].ConflictTypeReference.Value.ReferenceName), "It should be a TFS cyclic link reference conflict"); Assert.IsTrue(TFSCyclicLinkConflictTypeReferenceName.Equals(conflicts[1].ConflictTypeReference.Value.ReferenceName), "It should be a TFS cyclic link reference conflict"); // fix the hierarchy on target, delete b->a ==> a b TfsTargetAdapter.DeleteParentChildLink(mirroredIdA, mirroredIdB); // resolve the conflict by retrying conflictResolver.TryResolveConflict(conflicts[0], new ManualConflictResolutionAction(), "/"); // restart the session RunAndNoValidate(true); // resolve the conflict by retrying conflictResolver.TryResolveConflict(conflicts[1], new ManualConflictResolutionAction(), "/"); // restart the session RunAndNoValidate(true); conflicts = conflictResolver.GetConflicts(); Assert.IsTrue(conflicts.Count == 0, "There should be no conflict"); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(workitemIdA)); Assert.AreEqual(1, TfsSourceAdapter.GetRelatedLinkCount(workitemIdB)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(mirroredIdA)); Assert.AreEqual(1, TfsTargetAdapter.GetRelatedLinkCount(mirroredIdB)); // verify sync result WitDiffResult result = GetDiffResult(); // ignore Area/Iteration path mismatches VerifySyncResult(result, new List <string> { FIELD_ITERATION_PATH, FIELD_AREA_PATH }); }