@@ -19,7 +19,7 @@ namespace DotNet.Testcontainers.Containers
1919 [ PublicAPI ]
2020 public class DockerContainer : Resource , IContainer
2121 {
22- private const TestcontainersStates ContainerHasBeenCreatedStates = TestcontainersStates . Created | TestcontainersStates . Running | TestcontainersStates . Exited ;
22+ private const TestcontainersStates ContainerHasBeenCreatedStates = TestcontainersStates . Created | TestcontainersStates . Running | TestcontainersStates . Paused | TestcontainersStates . Exited ;
2323
2424 private const TestcontainersHealthStatus ContainerHasHealthCheck = TestcontainersHealthStatus . Starting | TestcontainersHealthStatus . Healthy | TestcontainersHealthStatus . Unhealthy ;
2525
@@ -48,6 +48,12 @@ public DockerContainer(IContainerConfiguration configuration)
4848 /// <inheritdoc />
4949 public event EventHandler Stopping ;
5050
51+ /// <inheritdoc />
52+ public event EventHandler Pausing ;
53+
54+ /// <inheritdoc />
55+ public event EventHandler Unpausing ;
56+
5157 /// <inheritdoc />
5258 public event EventHandler Created ;
5359
@@ -57,6 +63,12 @@ public DockerContainer(IContainerConfiguration configuration)
5763 /// <inheritdoc />
5864 public event EventHandler Stopped ;
5965
66+ /// <inheritdoc />
67+ public event EventHandler Paused ;
68+
69+ /// <inheritdoc />
70+ public event EventHandler Unpaused ;
71+
6072 /// <inheritdoc />
6173 public DateTime CreatedTime { get ; private set ; }
6274
@@ -66,6 +78,12 @@ public DockerContainer(IContainerConfiguration configuration)
6678 /// <inheritdoc />
6779 public DateTime StoppedTime { get ; private set ; }
6880
81+ /// <inheritdoc />
82+ public DateTime PausedTime { get ; private set ; }
83+
84+ /// <inheritdoc />
85+ public DateTime UnpausedTime { get ; private set ; }
86+
6987 /// <inheritdoc />
7088 public ILogger Logger
7189 {
@@ -294,6 +312,26 @@ await UnsafeStopAsync(ct)
294312 . ConfigureAwait ( false ) ;
295313 }
296314
315+ /// <inheritdoc />
316+ public async Task PauseAsync ( CancellationToken ct = default )
317+ {
318+ using var disposable = await AcquireLockAsync ( ct )
319+ . ConfigureAwait ( false ) ;
320+
321+ await UnsafePauseAsync ( ct )
322+ . ConfigureAwait ( false ) ;
323+ }
324+
325+ /// <inheritdoc />
326+ public async Task UnpauseAsync ( CancellationToken ct = default )
327+ {
328+ using var disposable = await AcquireLockAsync ( ct )
329+ . ConfigureAwait ( false ) ;
330+
331+ await UnsafeUnpauseAsync ( ct )
332+ . ConfigureAwait ( false ) ;
333+ }
334+
297335 /// <inheritdoc />
298336 public Task CopyAsync ( byte [ ] fileContent , string filePath , UnixFileModes fileMode = Unix . FileMode644 , CancellationToken ct = default )
299337 {
@@ -522,6 +560,64 @@ await _client.StopAsync(_container.ID, ct)
522560 Stopped ? . Invoke ( this , EventArgs . Empty ) ;
523561 }
524562
563+ /// <summary>
564+ /// Pauses the container.
565+ /// </summary>
566+ /// <remarks>
567+ /// Only the public members <see cref="PauseAsync" /> and <see cref="UnpauseAsync" /> are thread-safe for now.
568+ /// </remarks>
569+ /// <param name="ct">Cancellation token.</param>
570+ /// <returns>Task that completes when the container has been paused.</returns>
571+ protected virtual async Task UnsafePauseAsync ( CancellationToken ct = default )
572+ {
573+ ThrowIfLockNotAcquired ( ) ;
574+
575+ if ( ! Exists ( ) )
576+ {
577+ return ;
578+ }
579+
580+ Pausing ? . Invoke ( this , EventArgs . Empty ) ;
581+
582+ await _client . PauseAsync ( _container . ID , ct )
583+ . ConfigureAwait ( false ) ;
584+
585+ _container = await _client . Container . ByIdAsync ( _container . ID , ct )
586+ . ConfigureAwait ( false ) ;
587+
588+ PausedTime = DateTime . UtcNow ;
589+ Paused ? . Invoke ( this , EventArgs . Empty ) ;
590+ }
591+
592+ /// <summary>
593+ /// Unpauses the container.
594+ /// </summary>
595+ /// <remarks>
596+ /// Only the public members <see cref="PauseAsync" /> and <see cref="UnpauseAsync" /> are thread-safe for now.
597+ /// </remarks>
598+ /// <param name="ct">Cancellation token.</param>
599+ /// <returns>Task that completes when the container has been unpaused.</returns>
600+ protected virtual async Task UnsafeUnpauseAsync ( CancellationToken ct = default )
601+ {
602+ ThrowIfLockNotAcquired ( ) ;
603+
604+ if ( ! Exists ( ) )
605+ {
606+ return ;
607+ }
608+
609+ Unpausing ? . Invoke ( this , EventArgs . Empty ) ;
610+
611+ await _client . UnpauseAsync ( _container . ID , ct )
612+ . ConfigureAwait ( false ) ;
613+
614+ _container = await _client . Container . ByIdAsync ( _container . ID , ct )
615+ . ConfigureAwait ( false ) ;
616+
617+ UnpausedTime = DateTime . UtcNow ;
618+ Unpaused ? . Invoke ( this , EventArgs . Empty ) ;
619+ }
620+
525621 /// <inheritdoc />
526622 protected override bool Exists ( )
527623 {
0 commit comments