Skip to content

Commit 871a9cd

Browse files
maaexsevonnexerHofmeisterAn
authored
feat: Extend the "wait until file exists" API to distinguish between the test host and container filesystem (#1009)
Co-authored-by: Max Sevon <max.sevon@nexergroup.com> Co-authored-by: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com>
1 parent 5d5cb2d commit 871a9cd

File tree

6 files changed

+116
-6
lines changed

6 files changed

+116
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace DotNet.Testcontainers.Configurations
2+
{
3+
using JetBrains.Annotations;
4+
5+
/// <summary>
6+
/// Indicates the file system for file operations.
7+
/// </summary>
8+
[PublicAPI]
9+
public enum FileSystem
10+
{
11+
/// <summary>
12+
/// The test host file system.
13+
/// </summary>
14+
Host = 0,
15+
16+
/// <summary>
17+
/// The container file system.
18+
/// </summary>
19+
Container = 1,
20+
}
21+
}

src/Testcontainers/Configurations/WaitStrategies/IWaitForContainerOS.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@ public interface IWaitForContainerOS
5252
/// <summary>
5353
/// Waits until the file exists.
5454
/// </summary>
55-
/// <param name="file">The file to be checked.</param>
55+
/// <param name="filePath">The file path to be checked.</param>
56+
/// <param name="fileSystem">The file system to be checked.</param>
5657
/// <returns>A configured instance of <see cref="IWaitForContainerOS" />.</returns>
5758
[PublicAPI]
58-
IWaitForContainerOS UntilFileExists(string file);
59+
IWaitForContainerOS UntilFileExists(string filePath, FileSystem fileSystem = FileSystem.Host);
5960

6061
/// <summary>
6162
/// Waits until the message is logged.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
namespace DotNet.Testcontainers.Configurations
2+
{
3+
using System.IO;
4+
using System.Threading.Tasks;
5+
using DotNet.Testcontainers.Containers;
6+
7+
internal class UntilFileExistsInContainer : IWaitUntil
8+
{
9+
private readonly string _file;
10+
11+
public UntilFileExistsInContainer(string file)
12+
{
13+
_file = file;
14+
}
15+
16+
public async Task<bool> UntilAsync(IContainer container)
17+
{
18+
try
19+
{
20+
_ = await container.ReadFileAsync(_file)
21+
.ConfigureAwait(false);
22+
23+
return true;
24+
}
25+
catch (FileNotFoundException)
26+
{
27+
return false;
28+
}
29+
}
30+
}
31+
}

src/Testcontainers/Configurations/WaitStrategies/UntilFilesExists.cs src/Testcontainers/Configurations/WaitStrategies/UntilFileExistsOnHost.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ namespace DotNet.Testcontainers.Configurations
44
using System.Threading.Tasks;
55
using DotNet.Testcontainers.Containers;
66

7-
internal class UntilFilesExists : IWaitUntil
7+
internal class UntilFileExistsOnHost : IWaitUntil
88
{
99
private readonly string _file;
1010

11-
public UntilFilesExists(string file)
11+
public UntilFileExistsOnHost(string file)
1212
{
1313
_file = file;
1414
}

src/Testcontainers/Configurations/WaitStrategies/WaitForContainerOS.cs

+9-2
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,16 @@ public virtual IWaitForContainerOS AddCustomWaitStrategy(IWaitUntil waitStrategy
3434
}
3535

3636
/// <inheritdoc />
37-
public virtual IWaitForContainerOS UntilFileExists(string file)
37+
public virtual IWaitForContainerOS UntilFileExists(string filePath, FileSystem fileSystem = FileSystem.Host)
3838
{
39-
return AddCustomWaitStrategy(new UntilFilesExists(file));
39+
switch (fileSystem)
40+
{
41+
case FileSystem.Container:
42+
return AddCustomWaitStrategy(new UntilFileExistsInContainer(filePath));
43+
case FileSystem.Host:
44+
default:
45+
return AddCustomWaitStrategy(new UntilFileExistsOnHost(filePath));
46+
}
4047
}
4148

4249
/// <inheritdoc />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
namespace DotNet.Testcontainers.Tests.Unit
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using DotNet.Testcontainers.Builders;
8+
using DotNet.Testcontainers.Commons;
9+
using DotNet.Testcontainers.Configurations;
10+
using DotNet.Testcontainers.Containers;
11+
using Xunit;
12+
13+
public sealed class WaitUntilFileExistsInContainerTest : IAsyncLifetime, IDisposable
14+
{
15+
private const string ContainerFilePath = "/tmp/hostname";
16+
17+
private readonly CancellationTokenSource _cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));
18+
19+
private readonly IContainer _container = new ContainerBuilder()
20+
.WithImage(CommonImages.Alpine)
21+
.WithEntrypoint("/bin/sh", "-c")
22+
.WithCommand("hostname > " + ContainerFilePath + "; trap : TERM INT; sleep infinity & wait")
23+
.WithWaitStrategy(Wait.ForUnixContainer().UntilFileExists(ContainerFilePath, FileSystem.Container))
24+
.Build();
25+
26+
public Task InitializeAsync()
27+
{
28+
return _container.StartAsync(_cts.Token);
29+
}
30+
31+
public Task DisposeAsync()
32+
{
33+
return _container.DisposeAsync().AsTask();
34+
}
35+
36+
public void Dispose()
37+
{
38+
_cts.Dispose();
39+
}
40+
41+
[Fact]
42+
public async Task ContainerIsRunning()
43+
{
44+
var execResult = await _container.ExecAsync(new List<string> { "test", "-f", ContainerFilePath })
45+
.ConfigureAwait(false);
46+
47+
Assert.Equal(0, execResult.ExitCode);
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)