diff --git a/source/Halibut.Tests/Support/LatestClientAndLatestServiceBuilder.cs b/source/Halibut.Tests/Support/LatestClientAndLatestServiceBuilder.cs index 8a4b41319..87a675a1f 100644 --- a/source/Halibut.Tests/Support/LatestClientAndLatestServiceBuilder.cs +++ b/source/Halibut.Tests/Support/LatestClientAndLatestServiceBuilder.cs @@ -49,7 +49,7 @@ public class LatestClientAndLatestServiceBuilder : IClientAndServiceBuilder Reference? portForwarderReference; Func? pollingReconnectRetryPolicy; ProxyFactory? proxyFactory; - LogLevel halibutLogLevel = LogLevel.Trace; + LogLevel halibutLogLevel = LogLevel.Info; ConcurrentDictionary? clientInMemoryLoggers; ConcurrentDictionary? serviceInMemoryLoggers; ITrustProvider clientTrustProvider; diff --git a/source/Halibut.Tests/Support/SerilogLoggerBuilder.cs b/source/Halibut.Tests/Support/SerilogLoggerBuilder.cs index d447c312a..bc8a0f0b7 100644 --- a/source/Halibut.Tests/Support/SerilogLoggerBuilder.cs +++ b/source/Halibut.Tests/Support/SerilogLoggerBuilder.cs @@ -39,7 +39,7 @@ static SerilogLoggerBuilder() Logger = new LoggerConfiguration() .MinimumLevel.Verbose() - .WriteTo.Sink(new NonProgressNUnitSink(new MessageTemplateTextFormatter(nUnitOutputTemplate)), LogEventLevel.Debug) + .WriteTo.Sink(new NonProgressNUnitSink(new MessageTemplateTextFormatter(nUnitOutputTemplate))) .WriteTo.Sink(new TraceLogsForFailedTestsSink(new MessageTemplateTextFormatter(localOutputTemplate))) .CreateLogger(); } @@ -67,6 +67,7 @@ public ILogger Build() { TraceLoggers.AddOrUpdate(testName, traceFileLogger, (_, _) => throw new Exception("This should never be updated. If it is, it means that a test is being run multiple times in a single test run")); traceFileLogger.SetTestHash(testHash); + traceFileLogger.SetTestName(testName); } return logger; @@ -98,6 +99,12 @@ public void Emit(LogEvent logEvent) throw new ArgumentNullException(nameof(logEvent)); if (TestContext.Out == null) return; + + // SerilogLoggerBuilder creates this sink with Verbose logging, but we only want Verbose logging + // if we're running locally, as Verbose logs spam the TeamCity build log. + if (TeamCityDetection.IsRunningInTeamCity() && logEvent.Level < LogEventLevel.Debug) + return; + var output = new StringWriter(); if (logEvent.Properties.TryGetValue("SourceContext", out var sourceContext)) { diff --git a/source/Halibut.Tests/TraceLogFileLogger.cs b/source/Halibut.Tests/TraceLogFileLogger.cs index cbb0ebf63..a65ad526f 100644 --- a/source/Halibut.Tests/TraceLogFileLogger.cs +++ b/source/Halibut.Tests/TraceLogFileLogger.cs @@ -4,6 +4,8 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using JetBrains.TeamCity.ServiceMessages.Write; +using JetBrains.TeamCity.ServiceMessages.Write.Special; using Microsoft.VisualStudio.Threading; namespace Halibut.Tests @@ -13,6 +15,10 @@ public class TraceLogFileLogger : IDisposable readonly AsyncQueue queue = new(); readonly string tempFilePath = Path.GetTempFileName(); string testHash; + string testName; + + ITeamCityWriter teamCityWriter; + ITeamCityTestWriter testWriter; readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); readonly Task writeDataToDiskTask; @@ -27,6 +33,13 @@ public void SetTestHash(string testHash) this.testHash = testHash; } + public void SetTestName(string name) + { + this.testName = name; + teamCityWriter = new TeamCityServiceMessages().CreateWriter(Console.WriteLine); + testWriter = teamCityWriter.OpenTest(testName); + } + public void WriteLine(string logMessage) { if (cancellationTokenSource.IsCancellationRequested) return; @@ -74,6 +87,12 @@ void FinishWritingLogs() public bool CopyLogFileToArtifacts() { FinishWritingLogs(); + return CopyFileToArtifactsDirectory(); + } + + bool CopyFileToArtifactsDirectory() + { + // The current directory is expected to have the following structure // (w/ variance depending on Debug/Release and dotnet framework used (net6.0, net48 etc): // @@ -87,9 +106,23 @@ public bool CopyLogFileToArtifacts() var traceLogsDirectory = rootDirectory.CreateSubdirectory("artifacts").CreateSubdirectory("trace-logs"); var fileName = $"{testHash}.tracelog"; + try { - File.Copy(tempFilePath, Path.Combine(traceLogsDirectory.ToString(), fileName), true); + var traceLogFilePath = Path.Combine(traceLogsDirectory.ToString(), fileName); + File.Copy(tempFilePath, traceLogFilePath, true); + + teamCityWriter.PublishArtifact($"{traceLogFilePath} => adrian-test-trace-logs"); + var artifactUri = $"adrian-test-trace-logs/{fileName}"; + testWriter.WriteValue("some random value", "Adrian test value"); + testWriter.WriteFile(artifactUri, "Trace logs"); + teamCityWriter.WriteRawMessage(new ServiceMessage("testMetadata") + { + { "testName", testName }, + { "type", "artifact" }, + { "value", artifactUri } + }); + return true; } catch @@ -102,6 +135,8 @@ public void Dispose() { try { + testWriter.Dispose(); + teamCityWriter.Dispose(); File.Delete(tempFilePath); } catch @@ -111,4 +146,4 @@ public void Dispose() } } } -} \ No newline at end of file +} diff --git a/source/Halibut.Tests/UsageFixture.cs b/source/Halibut.Tests/UsageFixture.cs index 026bd7555..9a5c1e391 100644 --- a/source/Halibut.Tests/UsageFixture.cs +++ b/source/Halibut.Tests/UsageFixture.cs @@ -16,6 +16,26 @@ namespace Halibut.Tests { public class UsageFixture : BaseTest { + [Test] + [LatestAndPreviousClientAndServiceVersionsTestCases()] + public async Task AlwaysFail(ClientAndServiceTestCase clientAndServiceTestCase) + { + await using (var clientAndService = await clientAndServiceTestCase.CreateTestCaseBuilder() + .WithStandardServices() + .Build(CancellationToken)) + { + var echo = clientAndService.CreateAsyncClient(); + (await echo.SayHelloAsync("Deploy package A")).Should().Be("Deploy package A..."); + + for (var i = 0; i < clientAndServiceTestCase.RecommendedIterations; i++) + { + (await echo.SayHelloAsync($"Deploy package A {i}")).Should().Be($"Deploy package A {i}..."); + } + } + + Assert.Fail(); + } + [Test] [LatestAndPreviousClientAndServiceVersionsTestCases()] public async Task OctopusCanSendMessagesToTentacle_WithEchoService(ClientAndServiceTestCase clientAndServiceTestCase)