Esempio n. 1
0
        /// <summary>
        /// Gets the stub associated with the work item if it exists, otherwise a new one is
        /// created, added to the collection and returned
        /// </summary>
        /// <param name="wi">The Work Item to check</param>
        /// <returns>The associated WorkItemStub</returns>
        private WorkItemStub CheckStub(WorkItem wi)
        {
            //Perform a find on the ID, if it is found, s is populated
            WorkItemStub s = GetStub((int)wi.Fields[CoreField.Id].Value);

            //If it isn't found, create a new work item stub
            if (s == null)
            {
                s                  = new WorkItemStub();
                s.ID               = (int)wi.Fields[CoreField.Id].Value;
                s.Title            = wi.Fields[CoreField.Title].Value.ToString();
                s.WorkItemTypeName = wi.Fields[CoreField.WorkItemType].Value.ToString();
                s.Iteration        = wi.Fields[CoreField.IterationPath].Value.ToString();

                if (!_allNodeTypes.Contains(s.WorkItemTypeName))
                {
                    _allNodeTypes.Add(s.WorkItemTypeName);
                }

                //Check to see if the iteration exists in the list of iterations and add it if it doesn't
                if (!_iterations.Contains(s.Iteration))
                {
                    _iterations.Add(s.Iteration);
                }

                _workItemStubs.Add(s);
            }

            return(s);
        }
Esempio n. 2
0
        /// <summary>
        /// Checks to see if the work item stub exists
        /// </summary>
        /// <param name="id">The ID of the work item to find</param>
        /// <returns>The work item stub or null if it isn't found</returns>
        private WorkItemStub GetStub(int id)
        {
            //Perform a find on the ID, if it is found, s is populated
            WorkItemStub s = _workItemStubs.Find(
                delegate(WorkItemStub stub)
            {
                return(stub.ID == id);
            }
                );

            return(s);
        }
Esempio n. 3
0
        /// <summary>
        /// The work item to process
        /// </summary>
        /// <param name="wi"></param>
        private void ProcessWorkItemCS(WorkItem wi)
        {
            //Get a reference to or add the wi to the workitemstub list
            WorkItemStub s = CheckStub(wi);

            //Loop through the work items linked to this work item
            for (int i = 0; i < wi.WorkItemLinks.Count; i++)
            {
                if (_full)
                {
                    ProcessLinks(wi, wi.WorkItemLinks[i], s);
                }
                else
                {
                    if (IsLinkSelected(wi.WorkItemLinks[i].LinkTypeEnd.Name))
                    {
                        ProcessLinks(wi, wi.WorkItemLinks[i], s);
                    }
                }
            }

            if (_full)
            {
                GetChangesets(wi, s);
            }
            else
            {
                if (IsLinkSelected("Changesets"))
                {
                    GetChangesets(wi, s);
                }
            }

            if (s.WorkItemTypeName == "Test Case")
            {
                if (_full)
                {
                    GetTestResults(s, wi.Project.Name);
                }
                else
                {
                    if (IsLinkSelected("Test Results"))
                    {
                        GetTestResults(s, wi.Project.Name);
                    }
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// The work item to process
        /// </summary>
        /// <param name="wi"></param>
        private void ProcessWorkItemCS(WorkItem wi)
        {
            //Get a reference to or add the wi to the workitemstub list
            WorkItemStub s = CheckStub(wi);

            //Loop through the work items linked to this work item
            for (int i = 0; i < wi.WorkItemLinks.Count; i++)
            {
                if (IsLinkSelected(wi.WorkItemLinks[i].LinkTypeEnd.Name))
                {
                    int targetID = wi.WorkItemLinks[i].TargetId;
                    //Check to see if the work item is in the list of work items and if not, add it by
                    //calling this method recursively. If it is in the list of work items then we've already
                    //seen this work item and we just have to figure out how it is linked to this work item
                    WorkItemStub result = _workItemStubs.Find(
                        delegate(WorkItemStub stub)
                    {
                        return(stub.ID == targetID);
                    }
                        );

                    //If the work item hasn't been processed yet, process it
                    if (result == null)
                    {
                        ProcessWorkItemCS(_wis.GetWorkItem(targetID));
                    }

                    s.Related.Add(new WorkItemRelationship()
                    {
                        ID = targetID, Relationship = wi.WorkItemLinks[i].LinkTypeEnd.Name
                    });
                }
            }

            if (IsLinkSelected("Changesets"))
            {
                GetChangesets(wi, s);
            }

            if (IsLinkSelected("Test Results"))
            {
                //Get the test results if this is a test case
                if (s.WorkItemTypeName == "Test Case")
                {
                    GetTestResults(s, wi.Project.Name);
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Gets all work item stubs related to a given work item stub
        /// </summary>
        /// <param name="stub">The work item to get relationships for</param>
        /// <returns>A list of related work item stubs</returns>
        private List <WorkItemStub> GetRelatedWorkItems(WorkItemStub stub)
        {
            List <WorkItemStub> related = new List <WorkItemStub>();

            for (int i = 0; i < _workItemStubs.Count; i++)
            {
                for (int k = 0; k < _workItemStubs[i].Related.Count; k++)
                {
                    if ((_workItemStubs[i].Related[k].ID == stub.ID) && (_workItemStubs[i].Related[k].End == "Child"))
                    {
                        related.Add(_workItemStubs[i]);
                    }
                }
            }
            return(related);
        }
Esempio n. 6
0
        /// <summary>
        /// This method takes a work item and examines it's relationships to determine what
        /// the root work item is. The use of this method is in dependency analysis which
        /// takes the following ReqA --> TaskB --> ChangesetC and changes it to
        /// ReqA --> Changeset C. This base work item has changesets otherwise we would
        /// not be processing it. For our purposes we would be starting with TaskB and
        /// looking for ReqA or some other parent
        /// </summary>
        /// <param name="wi">The work item to discover the parent of</param>
        private void GetWorkItemParent(WorkItemStub stub)
        {
            //The rules for discovery are as follows:
            //1. Walk the parent/child relationship from the reverse to the forward node
            //2. Check the related work item ONLY when going from a Bug to a Test Case
            //   - never the reverse or you get trapped in a recursive loop
            //3. Check the affected by/affects from the reverse to the forward (in other
            //   words the standard relationship is a Requiremenet is Affected By a
            //   Change Request which has an associated changeset or child task

            WorkItemStub s     = null;  //stores the related work item stubs
            bool         found = false; //indicates if we found a valid link to persue

            //Because of how the relationships are constructed, only one end of the relationship has
            //the actual link to the relationship. For example, Story1 has relationships with Task1
            //and Task2 but Task1 and Task2 don't know anything about Story1. So, when we are going
            //through this list, we have to determine which other work items are related to the work
            //item we're looking at right now.

            //NOTE I may have to come back to this because it may be a fallacy that just because
            //story1 is related to task1 and task2 doesn't mean that there isn't a "story3" that
            //is the parent of Story1
            //This returns a list of parent work items that are related to thsi work item.
            List <WorkItemStub> r = GetRelatedWorkItems(stub);

            for (int i = 0; i < r.Count; i++)
            {
                s = GetStub(r[i].ID);
                GetWorkItemParent(s);
                found = true;
            }

            //If we haven't found any other links that are parent/child then this
            //must be the root that we are associating the changesets with
            if (!found)
            {
                if (_tempStub != stub)
                {
                    //Associate the changeset with this work item
                    for (int k = 0; k < _tempStub.Changesets.Count; k++)
                    {
                        stub.Changesets.Add(_tempStub.Changesets[k]);
                    }
                }
            }
        }
Esempio n. 7
0
        private void Process(WorkItem[] workItems)
        {
            _workItemStubs = new List <WorkItemStub>();
            _allNodeTypes  = new List <string>();

            //Get the full list of link types for assigning category relationships
            _links = LoadLinkTypes(_projectName);

            //Process all work items
            for (int i = 0; i < workItems.Length; i++)
            {
                ProcessWorkItemCS(workItems[i]);
            }

            //The colors for all other node types (i.e. not work item types)
            _allNodeTypes.Add("Changeset");
            _allNodeTypes.Add("Iteration");
            _allNodeTypes.Add("File");
            _allNodeTypes.Add("Test Plan");
            _allNodeTypes.Add("Test Run");
            _allNodeTypes.Add("Test Result");

            //Process the changesets so they are also related to the actual root work item
            if (_dependendyAnalysis)
            {
                //Only process work items that have changesets
                for (int i = 0; i < _workItemStubs.Count; i++)
                {
                    if (_workItemStubs[i].Changesets.Count > 0)
                    {
                        _tempStub = _workItemStubs[i];
                        GetWorkItemParent(_tempStub);
                    }
                }
            }

            //Output the results
            WriteChangesetInfo(_outputFile, _projectName);
        }
Esempio n. 8
0
        /// <summary>
        /// Traces the path of the work item to it's root
        /// </summary>
        /// <param name="stub">The work item stub to trace</param>
        private void GetRootWorkItem(WorkItemStub stub)
        {
            WorkItemStub s = null;

            for (int i = 0; i < stub.Related.Count; i++)
            {
                s = _workItemStubs.Find(
                    delegate(WorkItemStub wiStub)
                {
                    return(wiStub.ID == stub.Related[i].ID);
                }
                    );

                if ((s.WorkItemTypeName == "User Story") || (s.WorkItemTypeName == "Requirement"))
                {
                    _analysisStubs.Add(s);
                }
                else
                {
                    GetRootWorkItem(s);
                }
            }
        }
        /// <summary>
        /// Retrieves changesets associated with a work item
        /// </summary>
        /// <param name="wi">The work item to retrieve changesets for</param>
        /// <param name="stub">The work item stub to add them to</param>
        private void GetChangesets(WorkItem wi, WorkItemStub stub)
        {
            //Loop through all of the links in the work item. Note that this is the links
            //not the work item links so this includes things like hyperlinks, versioned items
            //and changeset links
            for (int i = 0; i < wi.Links.Count; i++)
            {
                //Determine if this is an external link which is an indication of a changeset link
                if (wi.Links[i].BaseType == BaseLinkType.ExternalLink)
                {
                    int cs_id;
                    ExternalLink ex = (ExternalLink)wi.Links[i];

                    //Try to get the changeset ID by parsing the end of the linked artifact URI
                    //For a changeset this will always be a numeric value
                    if (int.TryParse(ex.LinkedArtifactUri.Substring(ex.LinkedArtifactUri.LastIndexOf('/') + 1), out cs_id))
                    {
                        //It is a changeset, validate that we haven't processed it already
                        ChangesetStub c = stub.Changesets.Find(
                               delegate(ChangesetStub s)
                               {
                                   return s.ID == cs_id;
                               }
                           );

                        //It wasn't found, process it
                        if (c == null)
                        {
                            //It is a changeset so get the specific changeset
                            Changeset cs = _vcs.GetChangeset(cs_id);
                            ChangesetStub csStub = new ChangesetStub();
                            csStub.ID = cs_id;

                            //Loop through the files in the changeset which is represented by the Changes
                            for (int j = 0; j < cs.Changes.Count(); j++)
                            {
                                //Add the files to the changeset stub
                                FileChangeInfo fc = new FileChangeInfo();
                                fc.ChangeType = cs.Changes[j].ChangeType.ToString();
                                fc.FullPath = cs.Changes[j].Item.ServerItem;
                                csStub.Files.Add(fc);

                                //Check to see if we have added this file to the master list,
                                //if we haven't, add it
                                if (!_allFiles.Contains(fc.FileName))
                                    _allFiles.Add(fc.FileName);
                            }
                            stub.Changesets.Add(csStub);

                            //Loop through the files in the changeset which is represented by the Changes
                            for (int j = 0; j < cs.Changes.Count(); j++)
                            {
                                ChangesetFilesToWorkItems(cs.Changes[j].Item.ServerItem);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Get the results associated with a test case
        /// </summary>
        /// <param name="stub">The work item to get the results for</param>
        private void GetTestResults(WorkItemStub stub, string project)
        {
            //Return all of the test results in which this test case was executed
            string query  = string.Format("SELECT * FROM TestResult WHERE TestCaseId = {0}", stub.ID);
            int    planId = 0;

            //Get the list of results for the test case
            foreach (ITestCaseResult tcr in _tmp.TestResults.Query(query))
            {
                #region Get the Test Plan
                string runQuery = string.Format("SELECT * FROM TestRun WHERE TestRunId = {0}", tcr.TestRunId);

                //There should only be one value returned so just get the first one
                foreach (ITestRun tr in _tms.QueryTestRuns(runQuery))
                {
                    planId = tr.TestPlanId;
                    break;
                }

                //Is this part of a test plan that we already have?
                TestPlanInfo plan = _testPlans.Find(
                    delegate(TestPlanInfo tpi)
                {
                    return(tpi.TestPlanID == planId);
                }
                    );

                //If not, add it
                if (plan == null)
                {
                    string planQuery = string.Format("SELECT * FROM TestPlan WHERE PlanId = {0}", planId);
                    foreach (ITestPlan testPlan in _tmp.TestPlans.Query(planQuery))
                    {
                        plan = new TestPlanInfo()
                        {
                            TestPlanID = planId, TestPlanName = testPlan.Name
                        };
                        _testPlans.Add(plan);
                        break;
                    }
                }
                #endregion

                //Check to see if we've added the test run already
                bool found = false;
                for (int k = 0; k < plan.TestRuns.Count; k++)
                {
                    if (plan.TestRuns[k].ID == tcr.TestRunId)
                    {
                        found = true;
                    }
                }

                //If not, add it
                if (!found)
                {
                    plan.TestRuns.Add(new TestRunStub()
                    {
                        ID = tcr.TestRunId, Url = GetURL(UrlType.TestRun, tcr.TestRunId, 0, project)
                    });
                }

                //add the results
                TestResultStub resultStub = new TestResultStub();
                resultStub.TestPlan     = plan;
                resultStub.TestCaseID   = tcr.TestCaseId;
                resultStub.TestResultID = tcr.TestResultId;
                resultStub.TestRunID    = tcr.TestRunId;
                resultStub.Outcome      = tcr.Outcome;
                resultStub.Url          = GetURL(UrlType.TestResult, tcr.TestRunId, tcr.TestResultId, project);
                stub.TestResults.Add(resultStub);
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Retrieves changesets associated with a work item
        /// </summary>
        /// <param name="wi">The work item to retrieve changesets for</param>
        /// <param name="stub">The work item stub to add them to</param>
        private void GetChangesets(WorkItem wi, WorkItemStub stub)
        {
            //Loop through all of the links in the work item. Note that this is the links
            //not the work item links so this includes things like hyperlinks, versioned items
            //and changeset links
            for (int i = 0; i < wi.Links.Count; i++)
            {
                //Determine if this is an external link which is an indication of a changeset link
                if (wi.Links[i].BaseType == BaseLinkType.ExternalLink)
                {
                    int          cs_id;
                    ExternalLink ex = (ExternalLink)wi.Links[i];

                    //We have a valid changeset link type
                    if (ex.ArtifactLinkType.Equals(_wis.RegisteredLinkTypes[ArtifactLinkIds.Changeset]))
                    {
                        //Get the ID of the changeset
                        ArtifactId artifact = LinkingUtilities.DecodeUri(ex.LinkedArtifactUri);
                        cs_id = Convert.ToInt32(artifact.ToolSpecificId);

                        //It is a changeset, validate that we haven't processed it already
                        ChangesetStub c = stub.Changesets.Find(
                            delegate(ChangesetStub s)
                        {
                            return(s.ID == cs_id);
                        }
                            );

                        //It wasn't found, process it
                        if (c == null)
                        {
                            //It is a changeset so get the specific changeset
                            Changeset     cs     = _vcs.GetChangeset(cs_id);
                            ChangesetStub csStub = new ChangesetStub();
                            csStub.ID = cs_id;

                            //Loop through the files in the changeset which is represented by the Changes
                            for (int j = 0; j < cs.Changes.Count(); j++)
                            {
                                //Add the files to the changeset stub
                                FileChangeInfo fc = new FileChangeInfo();
                                fc.ChangeType = cs.Changes[j].ChangeType.ToString();
                                fc.FullPath   = cs.Changes[j].Item.ServerItem;
                                csStub.Files.Add(fc);

                                //Check to see if we have added this file to the master list,
                                //if we haven't, add it
                                if (!_allFiles.Contains(fc.FileName))
                                {
                                    _allFiles.Add(fc.FileName);
                                }
                            }
                            stub.Changesets.Add(csStub);

                            //Loop through the files in the changeset which is represented by the Changes
                            for (int j = 0; j < cs.Changes.Count(); j++)
                            {
                                ChangesetFilesToWorkItems(cs.Changes[j].Item.ServerItem);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Gets the stub associated with the work item if it exists, otherwise a new one is
        /// created, added to the collection and returned
        /// </summary>
        /// <param name="wi">The Work Item to check</param>
        /// <returns>The associated WorkItemStub</returns>
        private WorkItemStub CheckStub(WorkItem wi)
        {
            //Perform a find on the ID, if it is found, s is populated
            WorkItemStub s = GetStub((int)wi.Fields[CoreField.Id].Value);

            //If it isn't found, create a new work item stub
            if (s == null)
            {
                s = new WorkItemStub();
                s.ID = (int)wi.Fields[CoreField.Id].Value;
                s.Title = wi.Fields[CoreField.Title].Value.ToString();
                s.WorkItemTypeName = wi.Fields[CoreField.WorkItemType].Value.ToString();
                s.Iteration = wi.Fields[CoreField.IterationPath].Value.ToString();

                if (!_allNodeTypes.Contains(s.WorkItemTypeName))
                    _allNodeTypes.Add(s.WorkItemTypeName);

                //Check to see if the iteration exists in the list of iterations and add it if it doesn't
                if (!_iterations.Contains(s.Iteration))
                    _iterations.Add(s.Iteration);

                _workItemStubs.Add(s);
            }

            return s;
        }
        /// <summary>
        /// Retrieves changesets associated with a work item
        /// </summary>
        /// <param name="wi">The work item to retrieve changesets for</param>
        /// <param name="stub">The work item stub to add them to</param>
        private void GetChangesets(WorkItem wi, WorkItemStub stub)
        {
            //Loop through all of the links in the work item. Note that this is the links
            //not the work item links so this includes things like hyperlinks, versioned items
            //and changeset links
            for (int i = 0; i < wi.Links.Count; i++)
            {
                //Determine if this is an external link which is an indication of a changeset link
                if (wi.Links[i].BaseType == BaseLinkType.ExternalLink)
                {
                    int cs_id;
                    ExternalLink ex = (ExternalLink)wi.Links[i];

                    //We have a valid changeset link type
                    if (ex.ArtifactLinkType.Equals(_wis.RegisteredLinkTypes[ArtifactLinkIds.Changeset]))
                    {
                        //Get the ID of the changeset
                        ArtifactId artifact = LinkingUtilities.DecodeUri(ex.LinkedArtifactUri);
                        cs_id = Convert.ToInt32(artifact.ToolSpecificId);

                        //It is a changeset, validate that we haven't processed it already
                        ChangesetStub c = stub.Changesets.Find(
                               delegate(ChangesetStub s)
                               {
                                   return s.ID == cs_id;
                               }
                           );

                        //It wasn't found, process it
                        if (c == null)
                        {
                            //It is a changeset so get the specific changeset
                            Changeset cs = _vcs.GetChangeset(cs_id);
                            ChangesetStub csStub = new ChangesetStub();
                            csStub.ID = cs_id;

                            //Loop through the files in the changeset which is represented by the Changes
                            for (int j = 0; j < cs.Changes.Count(); j++)
                            {
                                //Add the files to the changeset stub
                                FileChangeInfo fc = new FileChangeInfo();
                                fc.ChangeType = cs.Changes[j].ChangeType.ToString();
                                fc.FullPath = cs.Changes[j].Item.ServerItem;
                                csStub.Files.Add(fc);

                                //Check to see if we have added this file to the master list,
                                //if we haven't, add it
                                if (!_allFiles.Contains(fc.FileName))
                                    _allFiles.Add(fc.FileName);
                            }
                            stub.Changesets.Add(csStub);

                            //Loop through the files in the changeset which is represented by the Changes
                            for (int j = 0; j < cs.Changes.Count(); j++)
                            {
                                ChangesetFilesToWorkItems(cs.Changes[j].Item.ServerItem);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Processes a relationship between two work items
        /// </summary>
        /// <param name="wi">The source work item</param>
        /// <param name="wiLink">The link to the target work item</param>
        /// <param name="s">The work item stub that corrosponds to the source work item</param>
        private void ProcessLinks(WorkItem wi, WorkItemLink wiLink, WorkItemStub s)
        {
            int targetID = wiLink.TargetId;
            //Check to see if the work item that is related to this one is in the list of work items and if not, add it by
            //calling this method recursively. If it is in the list of work items then we've already
            //seen this work item and we just have to figure out how it is linked to this work item
            WorkItemStub result = _workItemStubs.Find(
                delegate(WorkItemStub stub)
            {
                return(stub.ID == targetID);
            }
                );

            //If the work item hasn't been processed yet, process it
            if (result == null)
            {
                ProcessWorkItemCS(_wis.GetWorkItem(targetID));
            }

            //Check to see if the ID and relationship match (we can have more than one relationship between two work items
            //for example, we could have a parent/child relationship and also a predecessor/successor relationship
            WorkItemRelationship result1 = s.Related.Find(
                delegate(WorkItemRelationship stub)
            {
                return(stub.ToString() == targetID.ToString() + wiLink.LinkTypeEnd.Name);
            }
                );

            if (result1 == null)
            {
                bool found = false;
                //Before we add this relationship in, make sure we have never added this relationship anywhere at all
                //so we make sure each relationship (forward/reverse end of the same relationship) is unique in the
                //entire result set.
                for (int j = 0; j < _workItemStubs.Count; j++)
                {
                    if (_workItemStubs[j].ID == targetID)
                    {
                        for (int k = 0; k < _workItemStubs[j].Related.Count; k++)
                        {
                            if (_workItemStubs[j].Related[k].ID == wi.Id)
                            {
                                found = true;
                                break;
                            }
                        }
                    }

                    if (found)
                    {
                        break;
                    }
                }

                //If we didn't find an existing relationship, make sure we add it to the
                //work item at the reverse end of the relationship. For example, in a Parent/
                //Child relationship the Child is the Forward end of the relationship and
                //Parent is the reverse end of the relationship. We need to add this relationship
                //to the Parent to say that the parent has children so when the links are
                //written out to the DGML they point the right direction
                if (!found)
                {
                    //get the relationship
                    TempLinkType2 t = GetRelationship(wiLink.LinkTypeEnd.Name);
                    //Determine if this is the forward or reverse end of the relationship
                    if (t.Reverse == wiLink.LinkTypeEnd.Name)
                    {
                        //This is the reverse end of the relationship so add it, otherwise skip it altogether
                        s.Related.Add(new WorkItemRelationship()
                        {
                            ID = targetID, End = wiLink.LinkTypeEnd.Name, Relationship = GetRelationship(wiLink.LinkTypeEnd.Name)
                        });
                    }
                }
            }
        }
        /// <summary>
        /// Gets all work item stubs related to a given work item stub
        /// </summary>
        /// <param name="stub">The work item to get relationships for</param>
        /// <returns>A list of related work item stubs</returns>
        private List<WorkItemStub> GetRelatedWorkItems(WorkItemStub stub)
        {
            List<WorkItemStub> related = new List<WorkItemStub>();

            for (int i = 0; i < _workItemStubs.Count; i++)
            {
                for (int k = 0; k < _workItemStubs[i].Related.Count; k++)
                {
                    if ((_workItemStubs[i].Related[k].ID == stub.ID) && (_workItemStubs[i].Related[k].End == "Child"))
                    {
                        related.Add(_workItemStubs[i]);
                    }
                }
            }
            return related;
        }
        /// <summary>
        /// Get the results associated with a test case
        /// </summary>
        /// <param name="stub">The work item to get the results for</param>
        private void GetTestResults(WorkItemStub stub, string project)
        {
            //Return all of the test results in which this test case was executed
            string query = string.Format("SELECT * FROM TestResult WHERE TestCaseId = {0}", stub.ID);
            int planId = 0;

            //Get the list of results for the test case
            foreach (ITestCaseResult tcr in _tmp.TestResults.Query(query))
            {
                #region Get the Test Plan
                string runQuery = string.Format("SELECT * FROM TestRun WHERE TestRunId = {0}", tcr.TestRunId);

                //There should only be one value returned so just get the first one
                foreach (ITestRun tr in _tms.QueryTestRuns(runQuery))
                {
                    planId = tr.TestPlanId;
                    break;
                }

                //Is this part of a test plan that we already have?
                TestPlanInfo plan = _testPlans.Find(
                    delegate(TestPlanInfo tpi)
                    {
                        return tpi.TestPlanID == planId;
                    }
                );

                //If not, add it
                if (plan == null)
                {
                    string planQuery = string.Format("SELECT * FROM TestPlan WHERE PlanId = {0}", planId);
                    foreach (ITestPlan testPlan in _tmp.TestPlans.Query(planQuery))
                    {
                        plan = new TestPlanInfo() { TestPlanID = planId, TestPlanName = testPlan.Name };
                        _testPlans.Add(plan);
                        break;
                    }
                }
                #endregion

                //Check to see if we've added the test run already
                bool found = false;
                for (int k = 0; k < plan.TestRuns.Count; k++)
                {
                    if (plan.TestRuns[k].ID == tcr.TestRunId)
                    {
                        found = true;
                    }
                }

                //If not, add it
                if (!found)
                    plan.TestRuns.Add(new TestRunStub() { ID = tcr.TestRunId, Url = GetURL(UrlType.TestRun, tcr.TestRunId, 0, project) });

                //add the results
                TestResultStub resultStub = new TestResultStub();
                resultStub.TestPlan = plan;
                resultStub.TestCaseID = tcr.TestCaseId;
                resultStub.TestResultID = tcr.TestResultId;
                resultStub.TestRunID = tcr.TestRunId;
                resultStub.Outcome = tcr.Outcome;
                resultStub.Url = GetURL(UrlType.TestResult, tcr.TestRunId, tcr.TestResultId, project);
                stub.TestResults.Add(resultStub);
            }
        }
        /// <summary>
        /// This method takes a work item and examines it's relationships to determine what
        /// the root work item is. The use of this method is in dependency analysis which
        /// takes the following ReqA --> TaskB --> ChangesetC and changes it to 
        /// ReqA --> Changeset C. This base work item has changesets otherwise we would
        /// not be processing it. For our purposes we would be starting with TaskB and
        /// looking for ReqA or some other parent
        /// </summary>
        /// <param name="wi">The work item to discover the parent of</param>
        private void GetWorkItemParent(WorkItemStub stub)
        {
            //The rules for discovery are as follows:
            //1. Walk the parent/child relationship from the reverse to the forward node
            //2. Check the related work item ONLY when going from a Bug to a Test Case
            //   - never the reverse or you get trapped in a recursive loop
            //3. Check the affected by/affects from the reverse to the forward (in other
            //   words the standard relationship is a Requiremenet is Affected By a
            //   Change Request which has an associated changeset or child task

            WorkItemStub s = null;  //stores the related work item stubs
            bool found = false;     //indicates if we found a valid link to persue

            //Because of how the relationships are constructed, only one end of the relationship has
            //the actual link to the relationship. For example, Story1 has relationships with Task1
            //and Task2 but Task1 and Task2 don't know anything about Story1. So, when we are going
            //through this list, we have to determine which other work items are related to the work
            //item we're looking at right now.

            //NOTE I may have to come back to this because it may be a fallacy that just because
            //story1 is related to task1 and task2 doesn't mean that there isn't a "story3" that
            //is the parent of Story1
            //This returns a list of parent work items that are related to thsi work item.
            List<WorkItemStub> r = GetRelatedWorkItems(stub);
            for (int i = 0; i < r.Count; i++)
            {
                s = GetStub(r[i].ID);
                GetWorkItemParent(s);
                found = true;
            }

            //If we haven't found any other links that are parent/child then this
            //must be the root that we are associating the changesets with
            if (!found)
            {
                if (_tempStub != stub)
                {
                    //Associate the changeset with this work item
                    for (int k = 0; k < _tempStub.Changesets.Count; k++)
                    {
                        stub.Changesets.Add(_tempStub.Changesets[k]);
                    }
                }
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Retrieves changesets associated with a work item
        /// </summary>
        /// <param name="wi">The work item to retrieve changesets for</param>
        /// <param name="stub">The work item stub to add them to</param>
        private void GetChangesets(WorkItem wi, WorkItemStub stub)
        {
            //Loop through all of the links in the work item. Note that this is the links
            //not the work item links so this includes things like hyperlinks, versioned items
            //and changeset links
            for (int i = 0; i < wi.Links.Count; i++)
            {
                //Determine if this is an external link which is an indication of a changeset link
                if (wi.Links[i].BaseType == BaseLinkType.ExternalLink)
                {
                    int          cs_id;
                    ExternalLink ex = (ExternalLink)wi.Links[i];

                    //Try to get the changeset ID by parsing the end of the linked artifact URI
                    //For a changeset this will always be a numeric value
                    if (int.TryParse(ex.LinkedArtifactUri.Substring(ex.LinkedArtifactUri.LastIndexOf('/') + 1), out cs_id))
                    {
                        //It is a changeset, validate that we haven't processed it already
                        ChangesetStub c = stub.Changesets.Find(
                            delegate(ChangesetStub s)
                        {
                            return(s.ID == cs_id);
                        }
                            );

                        //It wasn't found, process it
                        if (c == null)
                        {
                            //It is a changeset so get the specific changeset
                            Changeset     cs     = _vcs.GetChangeset(cs_id);
                            ChangesetStub csStub = new ChangesetStub();
                            csStub.ID = cs_id;

                            //Loop through the files in the changeset which is represented by the Changes
                            for (int j = 0; j < cs.Changes.Count(); j++)
                            {
                                //Add the files to the changeset stub
                                FileChangeInfo fc = new FileChangeInfo();
                                fc.ChangeType = cs.Changes[j].ChangeType.ToString();
                                fc.FullPath   = cs.Changes[j].Item.ServerItem;
                                csStub.Files.Add(fc);

                                //Check to see if we have added this file to the master list,
                                //if we haven't, add it
                                if (!_allFiles.Contains(fc.FileName))
                                {
                                    _allFiles.Add(fc.FileName);
                                }
                            }
                            stub.Changesets.Add(csStub);

                            //Loop through the files in the changeset which is represented by the Changes
                            for (int j = 0; j < cs.Changes.Count(); j++)
                            {
                                ChangesetFilesToWorkItems(cs.Changes[j].Item.ServerItem);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Traces the path of the work item to it's root
        /// </summary>
        /// <param name="stub">The work item stub to trace</param>
        private void GetRootWorkItem(WorkItemStub stub)
        {
            WorkItemStub s = null;

            for (int i = 0; i < stub.Related.Count; i++)
            {
                s = _workItemStubs.Find(
                    delegate(WorkItemStub wiStub)
                    {
                        return wiStub.ID == stub.Related[i].ID;
                    }
                );

                if ((s.WorkItemTypeName == "User Story") || (s.WorkItemTypeName == "Requirement"))
                    _analysisStubs.Add(s);
                else
                    GetRootWorkItem(s);
            }
        }
        /// <summary>
        /// Processes a relationship between two work items
        /// </summary>
        /// <param name="wi">The source work item</param>
        /// <param name="wiLink">The link to the target work item</param>
        /// <param name="s">The work item stub that corrosponds to the source work item</param>
        private void ProcessLinks(WorkItem wi, WorkItemLink wiLink, WorkItemStub s)
        {
            int targetID = wiLink.TargetId;
            //Check to see if the work item that is related to this one is in the list of work items and if not, add it by
            //calling this method recursively. If it is in the list of work items then we've already
            //seen this work item and we just have to figure out how it is linked to this work item
            WorkItemStub result = _workItemStubs.Find(
                delegate(WorkItemStub stub)
                {
                    return stub.ID == targetID;
                }
            );

            //If the work item hasn't been processed yet, process it
            if (result == null)
                ProcessWorkItemCS(_wis.GetWorkItem(targetID));

            //Check to see if the ID and relationship match (we can have more than one relationship between two work items
            //for example, we could have a parent/child relationship and also a predecessor/successor relationship
            WorkItemRelationship result1 = s.Related.Find(
                delegate(WorkItemRelationship stub)
                {
                    return stub.ToString() == targetID.ToString() + wiLink.LinkTypeEnd.Name;
                }
            );

            if (result1 == null)
            {
                bool found = false;
                //Before we add this relationship in, make sure we have never added this relationship anywhere at all
                //so we make sure each relationship (forward/reverse end of the same relationship) is unique in the
                //entire result set.
                for (int j = 0; j < _workItemStubs.Count; j++)
                {
                    if (_workItemStubs[j].ID == targetID)
                    {
                        for (int k = 0; k < _workItemStubs[j].Related.Count; k++)
                        {
                            if (_workItemStubs[j].Related[k].ID == wi.Id)
                            {
                                found = true;
                                break;
                            }
                        }
                    }

                    if (found)
                        break;
                }

                //If we didn't find an existing relationship, make sure we add it to the
                //work item at the reverse end of the relationship. For example, in a Parent/
                //Child relationship the Child is the Forward end of the relationship and
                //Parent is the reverse end of the relationship. We need to add this relationship
                //to the Parent to say that the parent has children so when the links are
                //written out to the DGML they point the right direction
                if (!found)
                {
                    //get the relationship
                    TempLinkType2 t = GetRelationship(wiLink.LinkTypeEnd.Name);
                    //Determine if this is the forward or reverse end of the relationship
                    if (t.Reverse == wiLink.LinkTypeEnd.Name)
                    {
                        //This is the reverse end of the relationship so add it, otherwise skip it altogether
                        s.Related.Add(new WorkItemRelationship() { ID = targetID, End = wiLink.LinkTypeEnd.Name, Relationship = GetRelationship(wiLink.LinkTypeEnd.Name) });
                    }
                }
            }
        }
        private void Process(WorkItem[] workItems)
        {
            _workItemStubs = new List<WorkItemStub>();
            _allNodeTypes = new List<string>();

            //Get the full list of link types for assigning category relationships
            _links = LoadLinkTypes(_projectName);

            //Process all work items
            for (int i = 0; i < workItems.Length; i++)
            {
                ProcessWorkItemCS(workItems[i]);
            }

            //The colors for all other node types (i.e. not work item types)
            _allNodeTypes.Add("Changeset");
            _allNodeTypes.Add("Iteration");
            _allNodeTypes.Add("File");
            _allNodeTypes.Add("Test Plan");
            _allNodeTypes.Add("Test Run");
            _allNodeTypes.Add("Test Result");

            //Process the changesets so they are also related to the actual root work item
            if (_dependendyAnalysis)
            {
                //Only process work items that have changesets
                for (int i = 0; i < _workItemStubs.Count; i++)
                {
                    if (_workItemStubs[i].Changesets.Count > 0)
                    {
                        _tempStub = _workItemStubs[i];
                        GetWorkItemParent(_tempStub);

                    }
                }
            }

            //Output the results
            WriteChangesetInfo(_outputFile, _projectName);
        }