From 27cef85166530799a6b7ba2aa653a97dc0c89988 Mon Sep 17 00:00:00 2001 From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com> Date: Sun, 18 Sep 2022 02:56:34 +0200 Subject: [PATCH] Fix #518, #522 (#586) * fix(#518): Dispose HttpClient * fix(#522): Remove extra properties from ImageBuildParameters * fix: Disable CreateContainerAsync_TimeoutExpires_Fails (not deterministic), await containerLogsTask at the end of the GetContainerLogs_* tests --- src/Docker.DotNet/DockerClient.cs | 1 + .../Models/ImageBuildParameters.Generated.cs | 21 --- .../IContainerOperationsTests.cs | 153 ++++++------------ tools/specgen/modeldefs.go | 8 - 4 files changed, 50 insertions(+), 133 deletions(-) diff --git a/src/Docker.DotNet/DockerClient.cs b/src/Docker.DotNet/DockerClient.cs index 5004b7d5..852b384c 100644 --- a/src/Docker.DotNet/DockerClient.cs +++ b/src/Docker.DotNet/DockerClient.cs @@ -151,6 +151,7 @@ await sock.ConnectAsync(new Microsoft.Net.Http.Client.UnixDomainSocketEndPoint(p public void Dispose() { Configuration.Dispose(); + _client.Dispose(); } internal Task MakeRequestAsync( diff --git a/src/Docker.DotNet/Models/ImageBuildParameters.Generated.cs b/src/Docker.DotNet/Models/ImageBuildParameters.Generated.cs index 984e929f..de0c4711 100644 --- a/src/Docker.DotNet/Models/ImageBuildParameters.Generated.cs +++ b/src/Docker.DotNet/Models/ImageBuildParameters.Generated.cs @@ -24,21 +24,12 @@ public class ImageBuildParameters // (main.ImageBuildParameters) [QueryStringParameter("forcerm", false, typeof(BoolQueryStringConverter))] public bool? ForceRemove { get; set; } - [QueryStringParameter("pullparent", false, typeof(BoolQueryStringConverter))] - public bool? PullParent { get; set; } - [QueryStringParameter("pull", false)] public string Pull { get; set; } - [QueryStringParameter("isolation", false)] - public string Isolation { get; set; } - [QueryStringParameter("cpusetcpus", false)] public string CPUSetCPUs { get; set; } - [QueryStringParameter("cpusetmems", false)] - public string CPUSetMems { get; set; } - [QueryStringParameter("cpushares", false)] public long? CPUShares { get; set; } @@ -54,9 +45,6 @@ public class ImageBuildParameters // (main.ImageBuildParameters) [QueryStringParameter("memswap", false)] public long? MemorySwap { get; set; } - [QueryStringParameter("cgroupparent", false)] - public string CgroupParent { get; set; } - [QueryStringParameter("networkmode", false)] public string NetworkMode { get; set; } @@ -66,9 +54,6 @@ public class ImageBuildParameters // (main.ImageBuildParameters) [QueryStringParameter("dockerfile", false)] public string Dockerfile { get; set; } - [QueryStringParameter("ulimits", false, typeof(EnumerableQueryStringConverter))] - public IList Ulimits { get; set; } - [QueryStringParameter("buildargs", false, typeof(MapQueryStringConverter))] public IDictionary BuildArgs { get; set; } @@ -81,18 +66,12 @@ public class ImageBuildParameters // (main.ImageBuildParameters) [QueryStringParameter("cachefrom", false, typeof(EnumerableQueryStringConverter))] public IList CacheFrom { get; set; } - [QueryStringParameter("securityopt", false, typeof(EnumerableQueryStringConverter))] - public IList SecurityOpt { get; set; } - [QueryStringParameter("extrahosts", false, typeof(EnumerableQueryStringConverter))] public IList ExtraHosts { get; set; } [QueryStringParameter("target", false)] public string Target { get; set; } - [QueryStringParameter("session", false)] - public string SessionID { get; set; } - [QueryStringParameter("platform", false)] public string Platform { get; set; } diff --git a/test/Docker.DotNet.Tests/IContainerOperationsTests.cs b/test/Docker.DotNet.Tests/IContainerOperationsTests.cs index dd5d9bbe..3da5a876 100644 --- a/test/Docker.DotNet.Tests/IContainerOperationsTests.cs +++ b/test/Docker.DotNet.Tests/IContainerOperationsTests.cs @@ -54,7 +54,7 @@ public async Task CreateContainerAsync_CreatesContainer() } // Timeout causing task to be cancelled - [Theory] + [Theory(Skip = "There is nothing we can do to delay CreateContainerAsync (aka HttpClient.SendAsync) deterministic. We cannot control if it responses successful before the timeout.")] [InlineData(1)] [InlineData(5)] [InlineData(10)] @@ -87,10 +87,9 @@ public async Task CreateContainerAsync_TimeoutExpires_Fails(int millisecondsTime } [Fact] - public async Task GetContainerLogs_Follow_False_TaskIsCompleted() + public async Task GetContainerLogs_Tty_False_Follow_True_TaskIsCompleted() { using var containerLogsCts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); - var logList = new List(); var createContainerResponse = await _dockerClient.Containers.CreateContainerAsync( new CreateContainerParameters() @@ -108,7 +107,7 @@ await _dockerClient.Containers.StartContainerAsync( _cts.Token ); - containerLogsCts.CancelAfter(TimeSpan.FromSeconds(20)); + containerLogsCts.CancelAfter(TimeSpan.FromSeconds(5)); var containerLogsTask = _dockerClient.Containers.GetContainerLogsAsync( createContainerResponse.ID, @@ -120,7 +119,7 @@ await _dockerClient.Containers.StartContainerAsync( Follow = true }, containerLogsCts.Token, - new Progress((m) => { _output.WriteLine(m); logList.Add(m); }) + new Progress(m => _output.WriteLine(m)) ); await _dockerClient.Containers.StopContainerAsync( @@ -136,7 +135,7 @@ await _dockerClient.Containers.StopContainerAsync( [Fact] public async Task GetContainerLogs_Tty_False_Follow_False_ReadsLogs() { - using var containerLogsCts = new CancellationTokenSource(TimeSpan.FromSeconds(50)); + using var containerLogsCts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); var logList = new List(); var createContainerResponse = await _dockerClient.Containers.CreateContainerAsync( @@ -155,7 +154,9 @@ await _dockerClient.Containers.StartContainerAsync( _cts.Token ); - await _dockerClient.Containers.GetContainerLogsAsync( + containerLogsCts.CancelAfter(TimeSpan.FromSeconds(5)); + + var containerLogsTask = _dockerClient.Containers.GetContainerLogsAsync( createContainerResponse.ID, new ContainerLogsParameters { @@ -165,25 +166,25 @@ await _dockerClient.Containers.GetContainerLogsAsync( Follow = false }, containerLogsCts.Token, - new Progress((m) => { logList.Add(m); _output.WriteLine(m); }) + new Progress(m => { logList.Add(m); _output.WriteLine(m); }) ); await _dockerClient.Containers.StopContainerAsync( createContainerResponse.ID, new ContainerStopParameters(), _cts.Token - ); + ); + await containerLogsTask; _output.WriteLine($"Line count: {logList.Count}"); Assert.NotEmpty(logList); } [Fact] - public async Task GetContainerLogs_Tty_False_Follow_True_Requires_Task_To_Be_Cancelled() + public async Task GetContainerLogs_Tty_True_Follow_False_ReadsLogs() { - using var containerLogsCts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token); - + using var containerLogsCts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); var logList = new List(); var createContainerResponse = await _dockerClient.Containers.CreateContainerAsync( @@ -191,7 +192,7 @@ public async Task GetContainerLogs_Tty_False_Follow_True_Requires_Task_To_Be_Can { Image = _imageId, Name = Guid.NewGuid().ToString(), - Tty = false + Tty = true }, _cts.Token ); @@ -204,33 +205,44 @@ await _dockerClient.Containers.StartContainerAsync( containerLogsCts.CancelAfter(TimeSpan.FromSeconds(5)); - // Will be cancelled after CancellationTokenSource interval, would run forever otherwise - await Assert.ThrowsAsync(() => _dockerClient.Containers.GetContainerLogsAsync( + var containerLogsTask = _dockerClient.Containers.GetContainerLogsAsync( createContainerResponse.ID, new ContainerLogsParameters { ShowStderr = true, ShowStdout = true, Timestamps = true, - Follow = true + Follow = false }, containerLogsCts.Token, - new Progress((m) => { _output.WriteLine(JsonConvert.SerializeObject(m)); logList.Add(m); }) - )); + new Progress(m => { _output.WriteLine(m); logList.Add(m); }) + ); + + await Task.Delay(TimeSpan.FromSeconds(5)); + + await _dockerClient.Containers.StopContainerAsync( + createContainerResponse.ID, + new ContainerStopParameters(), + _cts.Token + ); + + await containerLogsTask; + _output.WriteLine($"Line count: {logList.Count}"); + + Assert.NotEmpty(logList); } [Fact] - public async Task GetContainerLogs_Tty_True_Follow_True_Requires_Task_To_Be_Cancelled() + public async Task GetContainerLogs_Tty_False_Follow_True_Requires_Task_To_Be_Cancelled() { using var containerLogsCts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); - var logList = new List(); var createContainerResponse = await _dockerClient.Containers.CreateContainerAsync( new CreateContainerParameters() { Image = _imageId, Name = Guid.NewGuid().ToString(), - Tty = true + Tty = false }, _cts.Token ); @@ -241,9 +253,9 @@ await _dockerClient.Containers.StartContainerAsync( _cts.Token ); - containerLogsCts.CancelAfter(TimeSpan.FromSeconds(10)); + containerLogsCts.CancelAfter(TimeSpan.FromSeconds(5)); - var containerLogsTask = _dockerClient.Containers.GetContainerLogsAsync( + await Assert.ThrowsAsync(() => _dockerClient.Containers.GetContainerLogsAsync( createContainerResponse.ID, new ContainerLogsParameters { @@ -253,17 +265,14 @@ await _dockerClient.Containers.StartContainerAsync( Follow = true }, containerLogsCts.Token, - new Progress((m) => { _output.WriteLine(m); logList.Add(m); }) - ); - - await Assert.ThrowsAsync(() => containerLogsTask); + new Progress(m => _output.WriteLine(m)) + )); } [Fact] - public async Task GetContainerLogs_Tty_True_Follow_True_StreamLogs_TaskIsCancelled() + public async Task GetContainerLogs_Tty_True_Follow_True_Requires_Task_To_Be_Cancelled() { using var containerLogsCts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); - var logList = new List(); var createContainerResponse = await _dockerClient.Containers.CreateContainerAsync( new CreateContainerParameters() @@ -293,53 +302,14 @@ await _dockerClient.Containers.StartContainerAsync( Follow = true }, containerLogsCts.Token, - new Progress((m) => { _output.WriteLine(m); logList.Add(m); }) - ); - - await Task.Delay(TimeSpan.FromSeconds(10)); - - await _dockerClient.Containers.StopContainerAsync( - createContainerResponse.ID, - new ContainerStopParameters - { - WaitBeforeKillSeconds = 0 - }, - _cts.Token - ); - - await _dockerClient.Containers.RemoveContainerAsync( - createContainerResponse.ID, - new ContainerRemoveParameters - { - Force = true - }, - _cts.Token + new Progress(m => _output.WriteLine(m)) ); await Assert.ThrowsAsync(() => containerLogsTask); - - _output.WriteLine(JsonConvert.SerializeObject(new - { - AsyncState = containerLogsTask.AsyncState, - CreationOptions = containerLogsTask.CreationOptions, - Exception = containerLogsTask.Exception, - Id = containerLogsTask.Id, - IsCanceled = containerLogsTask.IsCanceled, - IsCompleted = containerLogsTask.IsCompleted, - IsCompletedSuccessfully = containerLogsTask.IsCompletedSuccessfully, - Status = containerLogsTask.Status - } - )); - - _output.WriteLine($"Line count: {logList.Count}"); - - await Task.Delay(TimeSpan.FromSeconds(1)); - - Assert.NotEmpty(logList); } [Fact] - public async Task GetContainerLogs_Tty_True_ReadsLogs() + public async Task GetContainerLogs_Tty_True_Follow_True_ReadsLogs_TaskIsCancelled() { using var containerLogsCts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); var logList = new List(); @@ -369,47 +339,22 @@ await _dockerClient.Containers.StartContainerAsync( ShowStderr = true, ShowStdout = true, Timestamps = true, - Follow = false + Follow = true }, containerLogsCts.Token, - new Progress((m) => { _output.WriteLine(m); logList.Add(m); }) + new Progress(m => { _output.WriteLine(m); logList.Add(m); }) ); - await Task.Delay(TimeSpan.FromSeconds(10)); + await Task.Delay(TimeSpan.FromSeconds(5)); await _dockerClient.Containers.StopContainerAsync( createContainerResponse.ID, - new ContainerStopParameters - { - WaitBeforeKillSeconds = 0 - }, - _cts.Token - ); - - await _dockerClient.Containers.RemoveContainerAsync( - createContainerResponse.ID, - new ContainerRemoveParameters - { - Force = true - }, + new ContainerStopParameters(), _cts.Token ); - await containerLogsTask; - - _output.WriteLine(JsonConvert.SerializeObject(new - { - AsyncState = containerLogsTask.AsyncState, - CreationOptions = containerLogsTask.CreationOptions, - Exception = containerLogsTask.Exception, - Id = containerLogsTask.Id, - IsCanceled = containerLogsTask.IsCanceled, - IsCompleted = containerLogsTask.IsCompleted, - IsCompletedSuccessfully = containerLogsTask.IsCompletedSuccessfully, - Status = containerLogsTask.Status - } - )); + await Assert.ThrowsAsync(() => containerLogsTask); _output.WriteLine($"Line count: {logList.Count}"); Assert.NotEmpty(logList); @@ -445,7 +390,7 @@ await _dockerClient.Containers.GetContainerStatsAsync( { Stream = false }, - new Progress((m) => { _output.WriteLine(m.ID); containerStatsList.Add(m); }), + new Progress(m => { _output.WriteLine(m.ID); containerStatsList.Add(m); }), tcs.Token ); @@ -492,7 +437,7 @@ await _dockerClient.Containers.GetContainerStatsAsync( { Stream = true }, - new Progress((m) => { containerStatsList.Add(m); _output.WriteLine(JsonConvert.SerializeObject(m)); }), + new Progress(m => { containerStatsList.Add(m); _output.WriteLine(JsonConvert.SerializeObject(m)); }), linkedCts.Token ); } @@ -536,7 +481,7 @@ await _dockerClient.Containers.GetContainerStatsAsync( { Stream = false }, - new Progress((m) => { _output.WriteLine(m.ID); containerStatsList.Add(m); }), + new Progress(m => { _output.WriteLine(m.ID); containerStatsList.Add(m); }), tcs.Token ); @@ -585,7 +530,7 @@ await _dockerClient.Containers.GetContainerStatsAsync( { Stream = true }, - new Progress((m) => { containerStatsList.Add(m); _output.WriteLine(JsonConvert.SerializeObject(m)); }), + new Progress(m => { containerStatsList.Add(m); _output.WriteLine(JsonConvert.SerializeObject(m)); }), linkedTcs.Token ); } diff --git a/tools/specgen/modeldefs.go b/tools/specgen/modeldefs.go index 73ab069a..47f1d8ac 100644 --- a/tools/specgen/modeldefs.go +++ b/tools/specgen/modeldefs.go @@ -5,7 +5,6 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/swarm" - "github.com/docker/go-units" ) // Args map @@ -19,29 +18,22 @@ type ImageBuildParameters struct { NoCache bool `rest:"query"` Remove bool `rest:"query,rm"` ForceRemove bool `rest:"query,forcerm"` - PullParent bool `rest:"query"` Pull string `rest:"query"` - Isolation string `rest:"query"` CPUSetCPUs string `rest:"query"` - CPUSetMems string `rest:"query"` CPUShares int64 `rest:"query"` CPUQuota int64 `rest:"query"` CPUPeriod int64 `rest:"query"` Memory int64 `rest:"query"` MemorySwap int64 `rest:"query,memswap"` - CgroupParent string `rest:"query"` NetworkMode string `rest:"query"` ShmSize int64 `rest:"query"` Dockerfile string `rest:"query"` - Ulimits []*units.Ulimit `rest:"query"` BuildArgs map[string]string `rest:"query"` Labels map[string]string `rest:"query"` Squash bool `rest:"query"` CacheFrom []string `rest:"query"` - SecurityOpt []string `rest:"query"` ExtraHosts []string `rest:"query"` Target string `rest:"query"` - SessionID string `rest:"query,session"` Platform string `rest:"query"` Outputs string `rest:"query"` AuthConfigs map[string]types.AuthConfig `rest:"headers,X-Registry-Config"`