Skip to content

Commit

Permalink
refactor(#603): Add default console logger
Browse files Browse the repository at this point in the history
  • Loading branch information
HofmeisterAn committed Nov 21, 2022
1 parent 446f002 commit e2e20d9
Show file tree
Hide file tree
Showing 35 changed files with 135 additions and 128 deletions.
2 changes: 1 addition & 1 deletion build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Task("Tests")
Verbosity = param.Verbosity,
NoRestore = true,
NoBuild = true,
Loggers = new[] { "trx" },
Loggers = new[] { "trx" },
Filter = param.TestFilter,
ResultsDirectory = param.Paths.Directories.TestResultsDirectoryPath,
ArgumentCustomization = args => args
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ public virtual bool IsAvailable()
{
try
{
TaskFactory.StartNew(() => dockerClient.System.PingAsync()).Unwrap().GetAwaiter().GetResult();
TaskFactory.StartNew(() => dockerClient.System.PingAsync())
.Unwrap()
.ConfigureAwait(false)
.GetAwaiter()
.GetResult();

return true;
}
catch (Exception)
Expand Down
4 changes: 3 additions & 1 deletion src/Testcontainers/Clients/DockerImageOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ await this.DeleteAsync(image, ct)
await this.Docker.Images.BuildImageFromDockerfileAsync(buildParameters, dockerfileStream, Array.Empty<AuthConfig>(), new Dictionary<string, string>(), this.traceProgress, ct)
.ConfigureAwait(false);

var imageHasBeenCreated = await this.ExistsWithNameAsync(image.FullName, ct).ConfigureAwait(false);
var imageHasBeenCreated = await this.ExistsWithNameAsync(image.FullName, ct)
.ConfigureAwait(false);

if (!imageHasBeenCreated)
{
throw new InvalidOperationException($"Docker image {image.FullName} has not been created.");
Expand Down
3 changes: 1 addition & 2 deletions src/Testcontainers/Configurations/TestcontainersSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace DotNet.Testcontainers.Configurations
using DotNet.Testcontainers.Images;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;

/// <summary>
/// This class represents the Testcontainers settings.
Expand Down Expand Up @@ -83,7 +82,7 @@ static TestcontainersSettings()
[PublicAPI]
[NotNull]
public static ILogger Logger { get; set; }
= NullLogger.Instance;
= new Logger();

/// <summary>
/// Gets or sets the host operating system.
Expand Down
116 changes: 116 additions & 0 deletions src/Testcontainers/Logger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
namespace DotNet.Testcontainers
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging;

/// <summary>
/// An <see cref="ILogger" /> implementation that forwards messages to the console.
/// Not every test framework or environment supports this approach.
/// Developers may still need to configure their own logging implementation.
/// If VSTest.Console.exe loads the test adapter in a deterministic order,
/// we can write our own test adapter and intercept the IMessageLogger instance:
/// https://github.com/microsoft/vstest/issues/4125#issuecomment-1320880502.
/// To debug the test host and runner set the environment variables VSTEST_HOST_DEBUG and VSTEST_RUNNER_DEBUG to 1.
/// To enable VSTest logging set VSTEST_DIAG to 1 and VSTEST_DIAG_VERBOSITY to verbose.
/// The following example contains the ITestExecutor implementations. It is important that the assembly ends with TestAdapter.dll.
/// </summary>
/// <example>
/// <code>
/// [FileExtension(DllFileExtension)]
/// [FileExtension(ExeFileExtension)]
/// [DefaultExecutorUri(ExecutorUri)]
/// [ExtensionUri(ExecutorUri)]
/// [Category(Category)]
/// internal sealed class UssDiscovery : ITestDiscoverer, ITestExecutor
/// {
/// private const string DllFileExtension = &quot;.dll&quot;;
///
/// private const string ExeFileExtension = &quot;.exe&quot;;
///
/// private const string ExecutorUri = &quot;executor://testcontainers.org/v1&quot;;
///
/// private const string Category = &quot;managed&quot;;
///
/// public void DiscoverTests(IEnumerable&lt;string&gt; sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink)
/// {
/// }
///
/// public void RunTests(IEnumerable&lt;TestCase&gt; tests, IRunContext runContext, IFrameworkHandle frameworkHandle)
/// {
/// SetLogger(frameworkHandle);
/// }
///
/// public void RunTests(IEnumerable&lt;string&gt; sources, IRunContext runContext, IFrameworkHandle frameworkHandle)
/// {
/// SetLogger(frameworkHandle);
/// }
///
/// public void Cancel()
/// {
/// }
///
/// private static void SetLogger(IMessageLogger logger)
/// {
/// // Set the TestcontainersSettings.Logger. Use a semaphore to block the test execution until the logger is set.
/// }
/// }
/// </code>
/// </example>
internal sealed class Logger : ILogger, IDisposable
{
private readonly Stopwatch stopwatch = Stopwatch.StartNew();

public Logger()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Console.IsOutputRedirected && !Console.IsErrorRedirected)
{
Console.BufferWidth = short.MaxValue - 1;
}
}

public void Dispose()
{
}

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
TextWriter console;

switch (logLevel)
{
case LogLevel.Information:
console = Console.Out;
break;
case LogLevel.Warning:
console = Console.Out;
break;
case LogLevel.Error:
console = Console.Error;
break;
case LogLevel.Critical:
console = Console.Error;
break;
default:
console = TextWriter.Null;
break;
}

var message = string.Format(CultureInfo.CurrentCulture, "[testcontainers.org {0:hh\\:mm\\:ss\\.ff}] {1}", this.stopwatch.Elapsed, formatter.Invoke(state, exception));
console.WriteLine(message);
}

public bool IsEnabled(LogLevel logLevel)
{
return true;
}

public IDisposable BeginScope<TState>(TState state)
{
return this;
}
}
}
2 changes: 0 additions & 2 deletions src/Testcontainers/Networks/NonExistingDockerNetwork.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
namespace DotNet.Testcontainers.Networks
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using Docker.DotNet.Models;
Expand Down
19 changes: 0 additions & 19 deletions tests/Testcontainers.Tests/CustomSerilogLoggerFactory.cs

This file was deleted.

28 changes: 0 additions & 28 deletions tests/Testcontainers.Tests/Initialization.cs

This file was deleted.

39 changes: 0 additions & 39 deletions tests/Testcontainers.Tests/Initialized.cs

This file was deleted.

8 changes: 6 additions & 2 deletions tests/Testcontainers.Tests/SkipOnLinuxEngineAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ namespace DotNet.Testcontainers.Tests
{
using System;
using System.Diagnostics;
using DotNet.Testcontainers.Configurations;
using Xunit;

public sealed class SkipOnLinuxEngineAttribute : FactAttribute
{
private static readonly bool IsLinuxEngineEnabled = GetIsLinuxEngineEnabled();
static SkipOnLinuxEngineAttribute()
{
TestcontainersSettings.ResourceReaperEnabled = GetIsLinuxEngineEnabled();
}

public SkipOnLinuxEngineAttribute()
{
if (IsLinuxEngineEnabled)
if (TestcontainersSettings.ResourceReaperEnabled)
{
this.Skip = "Windows Docker engine is not available.";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ private sealed class AuthProviderTestData : List<object[]>
{
public AuthProviderTestData()
{
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
var defaultConfiguration = new PropertiesFileConfiguration(Array.Empty<string>());
var dockerTlsConfiguration = new PropertiesFileConfiguration("docker.tls=true", $"docker.cert.path={CertificatesDirectoryPath}");
var dockerMTlsConfiguration = new PropertiesFileConfiguration("docker.tls.verify=true", $"docker.cert.path={CertificatesDirectoryPath}");
Expand All @@ -66,8 +65,8 @@ public AuthProviderTestData()
this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider(DockerHostConfiguration), true });
this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider(Array.Empty<ICustomConfiguration>()), false });
this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider(defaultConfiguration, DockerHostConfiguration), true });
this.Add(new object[] { new NpipeEndpointAuthenticationProvider(), isWindows });
this.Add(new object[] { new UnixEndpointAuthenticationProvider(), !isWindows });
this.Add(new object[] { new NpipeEndpointAuthenticationProvider(), RuntimeInformation.IsOSPlatform(OSPlatform.Windows) });
this.Add(new object[] { new UnixEndpointAuthenticationProvider(), !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) });
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace DotNet.Testcontainers.Tests.Unit

public static class TestcontainersAccessInformationTest
{
[Collection(nameof(Testcontainers))]
public sealed class AccessDockerInformation
{
private const string DoesNotExist = nameof(TestcontainersAccessInformationTest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ private static async Task EstablishConnection(AzuriteFixture.AzuriteDefaultFixtu
Assert.Contains(TableServiceDataFileName, execResult.Stdout);
}

[Collection(nameof(Testcontainers))]
public sealed class CommonContainerPorts : IClassFixture<AzuriteFixture.AzuriteDefaultFixture>
{
private readonly AzuriteFixture.AzuriteDefaultFixture commonContainerPorts;
Expand All @@ -109,7 +108,6 @@ public async Task ConnectionEstablished()
}
}

[Collection(nameof(Testcontainers))]
public sealed class CustomContainerPorts : IClassFixture<AzuriteFixture.AzuriteWithCustomContainerPortsFixture>
{
private readonly AzuriteFixture.AzuriteDefaultFixture customContainerPorts;
Expand All @@ -128,7 +126,6 @@ public async Task ConnectionEstablished()
}
}

[Collection(nameof(Testcontainers))]
public sealed class BlobServiceEnabled : IClassFixture<AzuriteFixture.AzuriteWithBlobOnlyFixture>
{
private readonly AzuriteFixture.AzuriteDefaultFixture azurite;
Expand Down Expand Up @@ -171,7 +168,6 @@ await Assert.ThrowsAsync<RequestFailedException>(() => tableServiceClient.GetPro
}
}

[Collection(nameof(Testcontainers))]
public sealed class QueueServiceEnabled : IClassFixture<AzuriteFixture.AzuriteWithQueueOnlyFixture>
{
private readonly AzuriteFixture.AzuriteDefaultFixture azurite;
Expand Down Expand Up @@ -214,7 +210,6 @@ await Assert.ThrowsAsync<RequestFailedException>(() => tableServiceClient.GetPro
}
}

[Collection(nameof(Testcontainers))]
public sealed class TableServiceEnabled : IClassFixture<AzuriteFixture.AzuriteWithTableOnlyFixture>
{
private readonly AzuriteFixture.AzuriteDefaultFixture azurite;
Expand Down Expand Up @@ -257,7 +252,6 @@ await Assert.ThrowsAsync<RequestFailedException>(() => queueServiceClient.GetPro
}
}

[Collection(nameof(Testcontainers))]
public sealed class CustomLocation : IClassFixture<AzuriteFixture.AzuriteWithCustomWorkspaceFixture>
{
private readonly IEnumerable<string> dataFiles;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace DotNet.Testcontainers.Tests.Unit

public static class CosmosDbTestcontainerTest
{
[Collection(nameof(Testcontainers))]
public sealed class ConnectionTests : IClassFixture<CosmosDbFixture>, IDisposable
{
private const string SkipReason = "The Cosmos DB Linux Emulator Docker image does not run on every CI environment."; // https://github.com/Azure/azure-cosmos-db-emulator-docker/issues/45.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace DotNet.Testcontainers.Tests.Unit
using DotNet.Testcontainers.Tests.Fixtures;
using Xunit;

[Collection(nameof(Testcontainers))]
public sealed class CouchDbTestcontainerTest : IClassFixture<CouchDbFixture>
{
private readonly CouchDbFixture couchDbFixture;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace DotNet.Testcontainers.Tests.Unit
using DotNet.Testcontainers.Tests.Fixtures;
using Xunit;

[Collection(nameof(Testcontainers))]
public sealed class CouchbaseTestcontainerTest : IClassFixture<CouchbaseFixture>
{
private readonly CouchbaseFixture couchbaseFixture;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace DotNet.Testcontainers.Tests.Unit
using DotNet.Testcontainers.Tests.Fixtures;
using Xunit;

[Collection(nameof(Testcontainers))]
public sealed class ElasticsearchTestcontainerTest : IClassFixture<ElasticsearchFixture>
{
private readonly ElasticsearchFixture elasticsearchFixture;
Expand Down
Loading

0 comments on commit e2e20d9

Please sign in to comment.