InfrastructureFixture.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using System.Runtime.InteropServices;
  2. using DotNet.Testcontainers.Builders;
  3. using DotNet.Testcontainers.Containers;
  4. using DotNet.Testcontainers.Images;
  5. using Microsoft.Extensions.Logging;
  6. namespace Renci.SshNet.IntegrationTests.TestsFixtures
  7. {
  8. public sealed class InfrastructureFixture : IDisposable
  9. {
  10. private InfrastructureFixture()
  11. {
  12. _loggerFactory = LoggerFactory.Create(builder =>
  13. {
  14. builder.SetMinimumLevel(LogLevel.Debug);
  15. builder.AddFilter("testcontainers", LogLevel.Information);
  16. builder.AddConsole();
  17. });
  18. SshNetLoggingConfiguration.InitializeLogging(_loggerFactory);
  19. }
  20. public static InfrastructureFixture Instance { get; } = new InfrastructureFixture();
  21. private readonly ILoggerFactory _loggerFactory;
  22. private IContainer _sshServer;
  23. private IFutureDockerImage _sshServerImage;
  24. public string SshServerHostName { get; private set; }
  25. public ushort SshServerPort { get; private set; }
  26. public SshUser AdminUser { get; } = new SshUser("sshnetadm", "ssh4ever");
  27. public SshUser User { get; } = new SshUser("sshnet", "ssh4ever");
  28. public async Task InitializeAsync()
  29. {
  30. #pragma warning disable MA0144 // use System.OperatingSystem to check the current OS
  31. // for the Windows Tests in CI, the Container is set up in WSL2 with Podman
  32. if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
  33. Environment.GetEnvironmentVariable("CI") == "true")
  34. #pragma warning restore MA0144 // use System.OperatingSystem to check the current OS
  35. {
  36. SshServerPort = 2222;
  37. SshServerHostName = "127.0.0.1";
  38. await Task.Delay(1_000);
  39. return;
  40. }
  41. var containerLogger = _loggerFactory.CreateLogger("testcontainers");
  42. _sshServerImage = new ImageFromDockerfileBuilder()
  43. .WithName("renci-ssh-tests-server-image")
  44. .WithDockerfileDirectory(CommonDirectoryPath.GetSolutionDirectory(), Path.Combine("test", "Renci.SshNet.IntegrationTests"))
  45. .WithDockerfile("Dockerfile")
  46. .WithDeleteIfExists(true)
  47. .WithLogger(containerLogger)
  48. .Build();
  49. await _sshServerImage.CreateAsync();
  50. _sshServer = new ContainerBuilder()
  51. .WithHostname("renci-ssh-tests-server")
  52. .WithImage(_sshServerImage)
  53. .WithPortBinding(22, true)
  54. .WithLogger(containerLogger)
  55. .Build();
  56. await _sshServer.StartAsync();
  57. SshServerPort = _sshServer.GetMappedPublicPort(22);
  58. SshServerHostName = _sshServer.Hostname;
  59. // Socket fails on Linux, reporting inability early. This is the Linux behavior by design.
  60. // https://github.com/dotnet/runtime/issues/47484#issuecomment-769239699
  61. // At this point we have to wait until the ssh server in the container is available
  62. if (Environment.OSVersion.Platform == PlatformID.Unix)
  63. {
  64. await Task.Delay(300);
  65. }
  66. }
  67. public async Task DisposeAsync()
  68. {
  69. if (_sshServer != null)
  70. {
  71. #pragma warning disable S6966 // Awaitable method should be used
  72. //try
  73. //{
  74. // File.WriteAllBytes(@"C:\tmp\auth.log", await _sshServer.ReadFileAsync("/var/log/auth.log").ConfigureAwait(false));
  75. //}
  76. //catch (Exception ex)
  77. //{
  78. // Console.Error.WriteLine(ex.ToString());
  79. //}
  80. #pragma warning restore S6966 // Awaitable method should be used
  81. await _sshServer.DisposeAsync();
  82. }
  83. if (_sshServerImage != null)
  84. {
  85. await _sshServerImage.DisposeAsync();
  86. }
  87. }
  88. public void Dispose()
  89. {
  90. }
  91. }
  92. }