Skip to content

Commit

Permalink
Blame Sequence File Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
vagisha-nidhi committed Aug 3, 2018
1 parent 2e18a57 commit 353998e
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class BlameCollector : DataCollector, ITestExecutionEnvironmentSpecifier
private DataCollectionEvents events;
private DataCollectionLogger logger;
private IProcessDumpUtility processDumpUtility;
private List<TestCase> testSequence;
private List<BlameTestObject> testSequence;
private IBlameReaderWriter blameReaderWriter;
private XmlElement configurationElement;
private int testStartCount;
Expand Down Expand Up @@ -88,7 +88,7 @@ public override void Initialize(
this.dataCollectionSink = dataSink;
this.context = environmentContext;
this.configurationElement = configurationElement;
this.testSequence = new List<TestCase>();
this.testSequence = new List<BlameTestObject>();
this.logger = logger;

// Subscribing to events
Expand Down Expand Up @@ -155,7 +155,7 @@ private void EventsTestCaseStart(object sender, TestCaseStartEventArgs e)
EqtTrace.Info("Blame Collector : Test Case Start");
}

this.testSequence.Add(e.TestElement);
this.testSequence.Add(new BlameTestObject(e.TestElement));
this.testStartCount++;
}

Expand All @@ -172,6 +172,14 @@ private void EventsTestCaseEnd(object sender, TestCaseEndEventArgs e)
}

this.testEndCount++;

foreach (var testObject in this.testSequence)
{
if (testObject.Id == e.TestElement.Id)
{
testObject.IsCompleted = true;
}
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.TestPlatform.Extensions.BlameDataCollector
{
using System;
using System.IO;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;

public class BlameTestObject
{
private Guid id;
private string fullyQualifiedName;
private string source;
private bool isCompleted;
private string displayName;

#region Constructor

/// <summary>
/// Initializes a new instance of the <see cref="BlameTestObject"/> class.
/// </summary>
public BlameTestObject()
{
// Default constructor
}

/// <summary>
/// Initializes a new instance of the <see cref="BlameTestObject"/> class.
/// </summary>
/// <param name="fullyQualifiedName">
/// Fully qualified name of the test case.
/// </param>
/// <param name="executorUri">
/// The Uri of the executor to use for running this test.
/// </param>
/// <param name="source">
/// Test container source from which the test is discovered.
/// </param>
public BlameTestObject(string fullyQualifiedName, Uri executorUri, string source)
{
ValidateArg.NotNullOrEmpty(fullyQualifiedName, "fullyQualifiedName");
ValidateArg.NotNull(executorUri, "executorUri");
ValidateArg.NotNullOrEmpty(source, "source");

this.Id = Guid.Empty;
this.FullyQualifiedName = fullyQualifiedName;
this.ExecutorUri = executorUri;
this.Source = source;
this.IsCompleted = false;
}

/// <summary>
/// Initializes a new instance of the <see cref="BlameTestObject"/> class.
/// </summary>
/// <param name="testCase">
/// The test case
/// </param>
public BlameTestObject(TestCase testCase)
{
this.Id = testCase.Id;
this.FullyQualifiedName = testCase.FullyQualifiedName;
this.ExecutorUri = testCase.ExecutorUri;
this.Source = testCase.Source;
this.DisplayName = testCase.DisplayName;
this.IsCompleted = false;
}

#endregion

#region Properties

/// <summary>
/// Gets or sets the id of the test case.
/// </summary>
public Guid Id
{
get
{
if (this.id == Guid.Empty)
{
this.id = this.GetTestId();
}

return this.id;
}

set
{
this.id = value;
}
}

/// <summary>
/// Gets or sets the fully qualified name of the test case.
/// </summary>
public string FullyQualifiedName
{
get
{
return this.fullyQualifiedName;
}

set
{
this.fullyQualifiedName = value;
}
}

/// <summary>
/// Gets or sets the Uri of the Executor to use for running this test.
/// </summary>
public Uri ExecutorUri
{
get; set;
}

/// <summary>
/// Gets or sets the test container source from which the test is discovered.
/// </summary>
public string Source
{
get
{
return this.source;
}

set
{
this.source = value;
}
}

/// <summary>
/// Gets or sets a value indicating whether test case is completed or not.
/// </summary>
public bool IsCompleted
{
get
{
return this.isCompleted;
}

set
{
this.isCompleted = value;
}
}

/// <summary>
/// Gets or sets the display name of the test case
/// </summary>
public string DisplayName
{
get
{
return this.displayName;
}

set
{
this.displayName = value;
}
}

#endregion

#region Private Methods

/// <summary>
/// Creates a Id of TestCase
/// </summary>
/// <returns>Guid test id</returns>
private Guid GetTestId()
{
// To generate id hash "ExecutorUri + source + Name";
string source = this.Source;
try
{
// If source name is malformed, GetFileName API will throw exception, so use same input malformed string to generate ID
source = Path.GetFileName(source);
}
catch
{
// do nothing
}

string testcaseFullName = this.ExecutorUri + source + this.FullyQualifiedName;
return EqtHash.GuidFromString(testcaseFullName);
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ internal static class Constants
/// </summary>
public const string TestSourceAttribute = "Source";

/// <summary>
/// Test Completed Attribute.
/// </summary>
public const string TestCompletedAttribute = "Completed";

/// <summary>
/// Test Display Name Attribute.
/// </summary>
public const string TestDisplayNameAttribute = "DisplayName";

/// <summary>
/// Friendly name of the data collector
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public interface IBlameReaderWriter
/// <param name="testSequence">List of tests in sequence</param>
/// <param name="filePath">The path of file</param>
/// <returns>File Path</returns>
string WriteTestSequence(List<TestCase> testSequence, string filePath);
string WriteTestSequence(List<BlameTestObject> testSequence, string filePath);

/// <summary>
/// Reads all tests from file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ protected XmlReaderWriter(IFileHelper fileHelper)
/// The file Path.
/// </param>
/// <returns>File path</returns>
public string WriteTestSequence(List<TestCase> testSequence, string filePath)
public string WriteTestSequence(List<BlameTestObject> testSequence, string filePath)
{
ValidateArg.NotNull(testSequence, nameof(testSequence));
ValidateArg.NotNullOrEmpty(filePath, nameof(filePath));
Expand All @@ -72,7 +72,9 @@ public string WriteTestSequence(List<TestCase> testSequence, string filePath)
{
var testElement = xmlDocument.CreateElement(Constants.BlameTestNode);
testElement.SetAttribute(Constants.TestNameAttribute, testCase.FullyQualifiedName);
testElement.SetAttribute(Constants.TestDisplayNameAttribute, testCase.DisplayName);
testElement.SetAttribute(Constants.TestSourceAttribute, testCase.Source);
testElement.SetAttribute(Constants.TestCompletedAttribute, testCase.IsCompleted.ToString());

blameTestRoot.AppendChild(testElement);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ public void TriggerSessionEndedHandlerShouldWriteToFileIfTestHostCrash()
TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll");

// Setup and Raise TestCaseStart and Session End Event
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<TestCase>>(), It.IsAny<string>()))
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<BlameTestObject>>(), It.IsAny<string>()))
.Returns(this.filepath);

this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase));
this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(this.dataCollectionContext));

// Verify WriteTestSequence Call
this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny<List<TestCase>>(), It.IsAny<string>()), Times.Once);
this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny<List<BlameTestObject>>(), It.IsAny<string>()), Times.Once);
}

/// <summary>
Expand All @@ -118,13 +118,13 @@ public void TriggerSessionEndedHandlerShouldNotWriteToFileIfNoTestHostCrash()
TestCase testcase = new TestCase("TestProject.UnitTest.TestMethod", new Uri("test:/abc"), "abc.dll");

// Setup and Raise TestCaseStart and Session End Event
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<TestCase>>(), It.IsAny<string>())).Returns(this.filepath);
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<BlameTestObject>>(), It.IsAny<string>())).Returns(this.filepath);
this.mockDataColectionEvents.Raise(x => x.TestCaseStart += null, new TestCaseStartEventArgs(testcase));
this.mockDataColectionEvents.Raise(x => x.TestCaseEnd += null, new TestCaseEndEventArgs(testcase, TestOutcome.Passed));
this.mockDataColectionEvents.Raise(x => x.SessionEnd += null, new SessionEndEventArgs(this.dataCollectionContext));

// Verify WriteTestSequence Call
this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny<List<TestCase>>(), this.filepath), Times.Never);
this.mockBlameReaderWriter.Verify(x => x.WriteTestSequence(It.IsAny<List<BlameTestObject>>(), this.filepath), Times.Never);
}

/// <summary>
Expand All @@ -143,7 +143,7 @@ public void TriggerSessionEndedHandlerShouldGetDumpFileIfProcDumpEnabled()

// Setup
this.mockProcessDumpUtility.Setup(x => x.GetDumpFile()).Returns(this.filepath);
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<TestCase>>(), It.IsAny<string>()))
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<BlameTestObject>>(), It.IsAny<string>()))
.Returns(this.filepath);

// Raise
Expand Down Expand Up @@ -171,7 +171,7 @@ public void TriggerSessionEndedHandlerShouldNotGetDumpFileIfNoCrash()

// Setup
this.mockProcessDumpUtility.Setup(x => x.GetDumpFile()).Returns(this.filepath);
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<TestCase>>(), It.IsAny<string>()))
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<BlameTestObject>>(), It.IsAny<string>()))
.Returns(this.filepath);

// Raise
Expand All @@ -198,7 +198,7 @@ public void TriggerSessionEndedHandlerShouldGetDumpFileIfCollectDumpOnExitIsEnab

// Setup
this.mockProcessDumpUtility.Setup(x => x.GetDumpFile()).Returns(this.filepath);
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<TestCase>>(), It.IsAny<string>()))
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<BlameTestObject>>(), It.IsAny<string>()))
.Returns(this.filepath);

// Raise
Expand All @@ -224,7 +224,7 @@ public void TriggerSessionEndedHandlerShouldLogWarningIfGetDumpFileThrowsFileNot
this.context);

// Setup and raise events
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<TestCase>>(), It.IsAny<string>()))
this.mockBlameReaderWriter.Setup(x => x.WriteTestSequence(It.IsAny<List<BlameTestObject>>(), It.IsAny<string>()))
.Returns(this.filepath);
this.mockProcessDumpUtility.Setup(x => x.GetDumpFile()).Throws(new FileNotFoundException());
this.mockDataColectionEvents.Raise(x => x.TestHostLaunched += null, new TestHostLaunchedEventArgs(this.dataCollectionContext, 1234));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public class XmlReaderWriterTests
private TestableXmlReaderWriter xmlReaderWriter;
private Mock<IFileHelper> mockFileHelper;
private Mock<Stream> mockStream;
private List<TestCase> testCaseList;
private TestCase testcase;
private List<BlameTestObject> testCaseList;
private BlameTestObject testcase;

/// <summary>
/// Initializes a new instance of the <see cref="XmlReaderWriterTests"/> class.
Expand All @@ -34,10 +34,10 @@ public XmlReaderWriterTests()
this.mockFileHelper = new Mock<IFileHelper>();
this.xmlReaderWriter = new TestableXmlReaderWriter(this.mockFileHelper.Object);
this.mockStream = new Mock<Stream>();
this.testCaseList = new List<TestCase>();
this.testcase = new TestCase
this.testCaseList = new List<BlameTestObject>();
this.testcase = new BlameTestObject
{
Id = Guid.NewGuid(),
ExecutorUri = new Uri("test:/abc"),
FullyQualifiedName = "TestProject.UnitTest.TestMethod",
Source = "abc.dll"
};
Expand Down

0 comments on commit 353998e

Please sign in to comment.