Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TRX Reporter for MultiNode tests #3904

Merged
merged 19 commits into from Oct 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.fsx
Expand Up @@ -289,7 +289,7 @@ Target "MultiNodeTests" (fun _ ->

let args = StringBuilder()
|> append assembly
|> append (sprintf "-Dmultinode.teamcity=%b" hasTeamCity)
|> append (sprintf "-Dmultinode.reporter=%s" (if hasTeamCity then "teamcity" else "trx"))
valdisz marked this conversation as resolved.
Show resolved Hide resolved
|> append "-Dmultinode.enable-filesink=on"
|> append (sprintf "-Dmultinode.output-directory=\"%s\"" outputMultiNode)
|> appendIfNotNullOrEmpty spec "-Dmultinode.spec="
Expand Down Expand Up @@ -328,7 +328,7 @@ Target "MultiNodeTestsNetCore" (fun _ ->
let args = StringBuilder()
|> append multiNodeTestPath
|> append assembly
|> append "-Dmultinode.teamcity=true"
|> append "-Dmultinode.reporter=trx"
|> append "-Dmultinode.enable-filesink=on"
|> append (sprintf "-Dmultinode.output-directory=\"%s\"" outputMultiNode)
|> append "-Dmultinode.platform=netcore"
Expand Down
@@ -0,0 +1,83 @@
// -----------------------------------------------------------------------
// <copyright file="ResultSummaryTests.cs" company="Akka.NET Project">
// Copyright (C) 2009-2019 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2019 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------
using System.Collections.Generic;
using Akka.MultiNodeTestRunner.TrxReporter.Models;
using FluentAssertions;
using Xunit;

namespace Akka.MultiNodeTestRunner.TrxReporter.Tests
{
public class ResultSummaryTests
{
public static IEnumerable<object[]> ResultsSummaryOutcomeData
{
get
{
yield return new object[]
{
new UnitTest[] { },
TestOutcome.NotExecuted
};

yield return new object[]
{
new[]
{
new UnitTest("", "", Identifier.Empty, "")
{
Results =
{
new UnitTestResult(Identifier.Empty, Identifier.Empty, Identifier.Empty, "", "")
{
Outcome = TestOutcome.Passed
}
}
},
},
TestOutcome.Passed
};

yield return new object[]
{
new[]
{
new UnitTest("", "", Identifier.Empty, "")
{
Results =
{
new UnitTestResult(Identifier.Empty, Identifier.Empty, Identifier.Empty, "", "")
{
Outcome = TestOutcome.Passed
}
}
},
new UnitTest("", "", Identifier.Empty, "")
{
Results =
{
new UnitTestResult(Identifier.Empty, Identifier.Empty, Identifier.Empty, "", "")
{
Outcome = TestOutcome.Failed
}
}
},
},
TestOutcome.Failed
};
}
}

[Theory]
[MemberData(nameof(ResultsSummaryOutcomeData))]
public void ResultsSummaryOutcome(UnitTest[] tests, TestOutcome outcome)
{
var summary = new ResultSummary(tests, new Output());

summary.Outcome.ShouldBeEquivalentTo(outcome);
}
}
}
Expand Up @@ -49,7 +49,7 @@ public UnsubscribeFactCompletionMessages(IActorRef subscriber)
Subscriber = subscriber;
}


public IActorRef Subscriber { get; private set; }
}

Expand Down
@@ -0,0 +1,25 @@
// -----------------------------------------------------------------------
// <copyright file="ErrorInfo.cs" company="Akka.NET Project">
// Copyright (C) 2009-2019 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2019 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------
using System.Xml.Linq;
using static Akka.MultiNodeTestRunner.TrxReporter.Models.XmlHelper;

namespace Akka.MultiNodeTestRunner.TrxReporter.Models
{
public class ErrorInfo : ITestEntity
{
public string Message { get; set; }
public string StackTrace { get; set; }

public XElement Serialize()
{
return Elem("ErrorInfo",
Elem("Message", Text(Message ?? "")),
Elem("StackTrace", Text(StackTrace ?? ""))
);
}
}
}
@@ -0,0 +1,15 @@
// -----------------------------------------------------------------------
// <copyright file="ITestEntity.cs" company="Akka.NET Project">
// Copyright (C) 2009-2019 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2019 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------
using System.Xml.Linq;

namespace Akka.MultiNodeTestRunner.TrxReporter.Models
{
public interface ITestEntity
{
XElement Serialize();
}
}
@@ -0,0 +1,28 @@
// -----------------------------------------------------------------------
// <copyright file="Identifier.cs" company="Akka.NET Project">
// Copyright (C) 2009-2019 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2019 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------
using System;

namespace Akka.MultiNodeTestRunner.TrxReporter.Models
{
public struct Identifier
{
public Identifier(Guid value)
{
Value = value;
}

public static readonly Identifier Empty = Create(Guid.Empty);

public Guid Value { get; }

public override string ToString() => Value.ToString("D");

public static Identifier Create() => new Identifier(Guid.NewGuid());

public static Identifier Create(Guid value) => new Identifier(value);
}
}
@@ -0,0 +1,42 @@
// -----------------------------------------------------------------------
// <copyright file="Output.cs" company="Akka.NET Project">
// Copyright (C) 2009-2019 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2019 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using static Akka.MultiNodeTestRunner.TrxReporter.Models.XmlHelper;

namespace Akka.MultiNodeTestRunner.TrxReporter.Models
{
public class Output : ITestEntity
{
public List<string> StdOut { get; } = new List<string>();
public List<string> StdErr { get; } = new List<string>();
public List<string> DebugTrace { get; } = new List<string>();
public ErrorInfo ErrorInfo { get; set; }
public List<string> TextMessages { get; } = new List<string>();

public XElement Serialize()
{
XElement TextElem(string element, List<string> lines) =>
lines.Count > 0
? Elem(element, Text(string.Join(Environment.NewLine, lines)))
: null;

return Elem("Output",
TextElem("StdOut", StdOut),
TextElem("StdErr", StdErr),
TextElem("DebugTrace", DebugTrace),
ErrorInfo,
ElemList(
"TextMessages",
TextMessages.Select(x => Elem("Message", Text(x)))
)
);
}
}
}
@@ -0,0 +1,100 @@
// -----------------------------------------------------------------------
// <copyright file="ResultSummary.cs" company="Akka.NET Project">
// Copyright (C) 2009-2019 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2019 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using static Akka.MultiNodeTestRunner.TrxReporter.Models.XmlHelper;

namespace Akka.MultiNodeTestRunner.TrxReporter.Models
{
public class ResultSummary : ITestEntity
{
public ResultSummary(IEnumerable<UnitTest> unitTests, Output output)
{
Output = output;

var stats = unitTests
.SelectMany(x => x.Results)
.GroupBy(x => x.Outcome)
.ToDictionary(k => k.Key, v => v.Count());

Total = stats.Values.Sum();
Executed = Total;

int GetStats(TestOutcome outcome)
{
return stats.TryGetValue(outcome, out var value) ? value : 0;
}

Passed = GetStats(TestOutcome.Passed);
Failed = GetStats(TestOutcome.Failed);
Error = GetStats(TestOutcome.Error);
Timeout = GetStats(TestOutcome.Timeout);
Aborted = GetStats(TestOutcome.Aborted);
Inconclusive = GetStats(TestOutcome.Inconclusive);
PassedButRunAborted = GetStats(TestOutcome.PassedButRunAborted);
NotRunnable = GetStats(TestOutcome.NotRunnable);
NotExecuted = GetStats(TestOutcome.NotExecuted);
Disconnected = GetStats(TestOutcome.Disconnected);
Warning = GetStats(TestOutcome.Warning);
Completed = GetStats(TestOutcome.Completed);
InProgress = GetStats(TestOutcome.InProgress);
Pending = GetStats(TestOutcome.Pending);

Outcome = Total == 0
? TestOutcome.NotExecuted
: Passed == Total
? TestOutcome.Passed
: TestOutcome.Failed;
}

public TestOutcome Outcome { get; }

public int Total { get; }
public int Executed { get; }
public int Passed { get; }
public int Failed { get; }
public int Error { get; }
public int Timeout { get; }
public int Aborted { get; }
public int Inconclusive { get; }
public int PassedButRunAborted { get; }
public int NotRunnable { get; }
public int NotExecuted { get; }
public int Disconnected { get; }
public int Warning { get; }
public int Completed { get; }
public int InProgress { get; }
public int Pending { get; }

public Output Output { get; }

public XElement Serialize() => Elem("ResultSummary",
Attr("outcome", Enum.GetName(typeof(TestOutcome), Outcome)),
Elem("Counters",
Attr("total", Total),
Attr("executed", Executed),
Attr("passed", Passed),
Attr("failed", Failed),
Attr("error", Error),
Attr("timeout", Timeout),
Attr("aborted", Aborted),
Attr("inconclusive", Inconclusive),
Attr("passedButRunAborted", PassedButRunAborted),
Attr("notRunnable", NotRunnable),
Attr("notExecuted", NotExecuted),
Attr("disconnected", Disconnected),
Attr("warning", Warning),
Attr("completed", Completed),
Attr("inProgress", InProgress),
Attr("pending", Pending)
),
Output
);
}
}
@@ -0,0 +1,31 @@
// -----------------------------------------------------------------------
// <copyright file="TestEntry.cs" company="Akka.NET Project">
// Copyright (C) 2009-2019 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2019 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------
using System.Xml.Linq;
using static Akka.MultiNodeTestRunner.TrxReporter.Models.XmlHelper;

namespace Akka.MultiNodeTestRunner.TrxReporter.Models
{
public class TestEntry : ITestEntity
{
public TestEntry(Identifier testId, Identifier executionId, Identifier testListId)
{
TestId = testId;
ExecutionId = executionId;
TestListId = testListId;
}

public Identifier TestId { get; }
public Identifier ExecutionId { get; }
public Identifier TestListId { get; }

public XElement Serialize() => Elem("TestEntry",
Attr("testId", TestId),
Attr("executionId", ExecutionId),
Attr("testListId", TestListId)
);
}
}
@@ -0,0 +1,27 @@
// -----------------------------------------------------------------------
// <copyright file="TestList.cs" company="Akka.NET Project">
// Copyright (C) 2009-2019 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2019 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
// -----------------------------------------------------------------------
using System.Xml.Linq;
using static Akka.MultiNodeTestRunner.TrxReporter.Models.XmlHelper;

namespace Akka.MultiNodeTestRunner.TrxReporter.Models
{
public class TestList : ITestEntity
{
public TestList(string name)
{
Name = name;
}

public Identifier Id { get; } = Identifier.Create();
public string Name { get; }

public XElement Serialize() => Elem("TestList",
Attr("id", Id),
Attr("name", Name)
);
}
}