From e00dbb07e7835fbedc1979ec80b2a17d21cb2017 Mon Sep 17 00:00:00 2001 From: j4587698 Date: Sat, 28 Feb 2026 01:20:55 +0000 Subject: [PATCH 1/5] fix: Serialize ConsoleSize as JSON array [height, width] for Docker API compatibility --- src/Docker.DotNet/ConsoleSizeConverter.cs | 51 +++++++++++++++++++ .../Models/ConsoleSize.Generated.cs | 1 + 2 files changed, 52 insertions(+) create mode 100644 src/Docker.DotNet/ConsoleSizeConverter.cs diff --git a/src/Docker.DotNet/ConsoleSizeConverter.cs b/src/Docker.DotNet/ConsoleSizeConverter.cs new file mode 100644 index 00000000..8d257789 --- /dev/null +++ b/src/Docker.DotNet/ConsoleSizeConverter.cs @@ -0,0 +1,51 @@ +using Docker.DotNet.Models; + +namespace Docker.DotNet; + +/// +/// Serializes as a JSON array [height, width] to match +/// the Docker Engine API's Go type [2]uint. +/// +internal class ConsoleSizeConverter : JsonConverter +{ + public override ConsoleSize Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return null; + } + + if (reader.TokenType != JsonTokenType.StartArray) + { + throw new JsonException("Expected a JSON array for ConsoleSize."); + } + + reader.Read(); + var height = reader.GetUInt64(); + + reader.Read(); + var width = reader.GetUInt64(); + + reader.Read(); // EndArray + + return new ConsoleSize + { + Height = height, + Width = width + }; + } + + public override void Write(Utf8JsonWriter writer, ConsoleSize value, JsonSerializerOptions options) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStartArray(); + writer.WriteNumberValue(value.Height); + writer.WriteNumberValue(value.Width); + writer.WriteEndArray(); + } +} diff --git a/src/Docker.DotNet/Models/ConsoleSize.Generated.cs b/src/Docker.DotNet/Models/ConsoleSize.Generated.cs index bfffea9c..b79d8d62 100644 --- a/src/Docker.DotNet/Models/ConsoleSize.Generated.cs +++ b/src/Docker.DotNet/Models/ConsoleSize.Generated.cs @@ -1,5 +1,6 @@ namespace Docker.DotNet.Models { + [JsonConverter(typeof(ConsoleSizeConverter))] public class ConsoleSize // (client.ConsoleSize) { [JsonPropertyName("Height")] From eb22fd346120e0bf6b30ac23db1ed16dcbc6bdb1 Mon Sep 17 00:00:00 2001 From: j4587698 Date: Sat, 28 Feb 2026 01:26:45 +0000 Subject: [PATCH 2/5] test: Add ConsoleSizeConverter unit tests --- .../ConsoleSizeConverterTests.cs | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs diff --git a/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs b/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs new file mode 100644 index 00000000..d75a0832 --- /dev/null +++ b/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs @@ -0,0 +1,147 @@ +namespace Docker.DotNet.Tests; + +public sealed class ConsoleSizeConverterTests +{ + [Fact] + public void Serialize_ConsoleSize_ProducesJsonArray() + { + // Given + var consoleSize = new ConsoleSize { Height = 24, Width = 80 }; + + // When + var jsonString = JsonSerializer.Instance.Serialize(consoleSize); + + // Then + Assert.Equal("[24,80]", jsonString); + } + + [Fact] + public void Deserialize_JsonArray_ProducesConsoleSize() + { + // Given + var json = "[24,80]"; + + // When + var consoleSize = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); + + // Then + Assert.NotNull(consoleSize); + Assert.Equal(24UL, consoleSize.Height); + Assert.Equal(80UL, consoleSize.Width); + } + + [Fact] + public void SerializeAndDeserialize_RoundTrip_Succeeds() + { + // Given + var original = new ConsoleSize { Height = 50, Width = 200 }; + + // When + var jsonString = JsonSerializer.Instance.Serialize(original); + var deserialized = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(jsonString)); + + // Then + Assert.NotNull(deserialized); + Assert.Equal(original.Height, deserialized.Height); + Assert.Equal(original.Width, deserialized.Width); + } + + [Fact] + public void Serialize_ContainerExecCreateParameters_WithConsoleSize_ProducesArrayFormat() + { + // Given + var parameters = new ContainerExecCreateParameters + { + ConsoleSize = new ConsoleSize { Height = 24, Width = 80 }, + AttachStdin = true, + AttachStdout = true, + TTY = true, + Cmd = new List { "/bin/bash" } + }; + + // When + var jsonString = JsonSerializer.Instance.Serialize(parameters); + + // Then - ConsoleSize should be serialized as [24,80], not {"Height":24,"Width":80} + Assert.Contains("\"ConsoleSize\":[24,80]", jsonString); + Assert.DoesNotContain("\"Height\"", jsonString); + Assert.DoesNotContain("\"Width\"", jsonString); + } + + [Fact] + public void Serialize_ContainerExecCreateParameters_WithoutConsoleSize_OmitsField() + { + // Given + var parameters = new ContainerExecCreateParameters + { + AttachStdin = true, + AttachStdout = true, + TTY = true, + Cmd = new List { "/bin/bash" } + }; + + // When + var jsonString = JsonSerializer.Instance.Serialize(parameters); + + // Then + Assert.DoesNotContain("ConsoleSize", jsonString); + } + + [Fact] + public void Serialize_ContainerExecStartParameters_WithConsoleSize_ProducesArrayFormat() + { + // Given + var parameters = new ContainerExecStartParameters + { + ConsoleSize = new ConsoleSize { Height = 30, Width = 120 } + }; + + // When + var jsonString = JsonSerializer.Instance.Serialize(parameters); + + // Then + Assert.Contains("\"ConsoleSize\":[30,120]", jsonString); + } + + [Fact] + public void Deserialize_ContainerExecCreateParameters_WithArrayConsoleSize_Succeeds() + { + // Given - This is the format Docker API would return + var json = "{\"ConsoleSize\":[24,80],\"AttachStdin\":true,\"Tty\":true,\"Cmd\":[\"/bin/bash\"]}"; + + // When + var parameters = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); + + // Then + Assert.NotNull(parameters); + Assert.NotNull(parameters.ConsoleSize); + Assert.Equal(24UL, parameters.ConsoleSize.Height); + Assert.Equal(80UL, parameters.ConsoleSize.Width); + } + + [Fact] + public void Serialize_LargeConsoleSize_HandlesCorrectly() + { + // Given - Test with larger values that still fit in ulong + var consoleSize = new ConsoleSize { Height = 1000, Width = 2000 }; + + // When + var jsonString = JsonSerializer.Instance.Serialize(consoleSize); + + // Then + Assert.Equal("[1000,2000]", jsonString); + } + + [Fact] + public void Serialize_ZeroConsoleSize_HandlesCorrectly() + { + // Given + var consoleSize = new ConsoleSize { Height = 0, Width = 0 }; + + // When + var jsonString = JsonSerializer.Instance.Serialize(consoleSize); + + // Then + Assert.Equal("[0,0]", jsonString); + } +} From c8390f14c73dd96c8beb8af383453931f25690ef Mon Sep 17 00:00:00 2001 From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com> Date: Wed, 25 Mar 2026 11:59:31 +0100 Subject: [PATCH 3/5] fix: Update specgen config --- src/Docker.DotNet/ConsoleSizeConverter.cs | 8 +- .../Models/ConsoleSize.Generated.cs | 1 - ...ContainerExecCreateParameters.Generated.cs | 1 + .../ContainerExecStartParameters.Generated.cs | 1 + .../Models/HostConfig.Generated.cs | 3 +- .../ConsoleSizeConverterTests.cs | 118 ++++++------------ tools/specgen/specgen.go | 27 ++++ 7 files changed, 70 insertions(+), 89 deletions(-) diff --git a/src/Docker.DotNet/ConsoleSizeConverter.cs b/src/Docker.DotNet/ConsoleSizeConverter.cs index 8d257789..384f1c36 100644 --- a/src/Docker.DotNet/ConsoleSizeConverter.cs +++ b/src/Docker.DotNet/ConsoleSizeConverter.cs @@ -6,9 +6,9 @@ namespace Docker.DotNet; /// Serializes as a JSON array [height, width] to match /// the Docker Engine API's Go type [2]uint. /// -internal class ConsoleSizeConverter : JsonConverter +internal class ConsoleSizeConverter : JsonConverter { - public override ConsoleSize Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override ConsoleSize? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.Null) { @@ -26,7 +26,7 @@ public override ConsoleSize Read(ref Utf8JsonReader reader, Type typeToConvert, reader.Read(); var width = reader.GetUInt64(); - reader.Read(); // EndArray + reader.Read(); return new ConsoleSize { @@ -35,7 +35,7 @@ public override ConsoleSize Read(ref Utf8JsonReader reader, Type typeToConvert, }; } - public override void Write(Utf8JsonWriter writer, ConsoleSize value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, ConsoleSize? value, JsonSerializerOptions options) { if (value == null) { diff --git a/src/Docker.DotNet/Models/ConsoleSize.Generated.cs b/src/Docker.DotNet/Models/ConsoleSize.Generated.cs index b79d8d62..bfffea9c 100644 --- a/src/Docker.DotNet/Models/ConsoleSize.Generated.cs +++ b/src/Docker.DotNet/Models/ConsoleSize.Generated.cs @@ -1,6 +1,5 @@ namespace Docker.DotNet.Models { - [JsonConverter(typeof(ConsoleSizeConverter))] public class ConsoleSize // (client.ConsoleSize) { [JsonPropertyName("Height")] diff --git a/src/Docker.DotNet/Models/ContainerExecCreateParameters.Generated.cs b/src/Docker.DotNet/Models/ContainerExecCreateParameters.Generated.cs index 87626973..d2918b36 100644 --- a/src/Docker.DotNet/Models/ContainerExecCreateParameters.Generated.cs +++ b/src/Docker.DotNet/Models/ContainerExecCreateParameters.Generated.cs @@ -12,6 +12,7 @@ public class ContainerExecCreateParameters // (main.ContainerExecCreateParameter public bool TTY { get; set; } [JsonPropertyName("ConsoleSize")] + [JsonConverter(typeof(ConsoleSizeConverter))] public ConsoleSize ConsoleSize { get; set; } [JsonPropertyName("AttachStdin")] diff --git a/src/Docker.DotNet/Models/ContainerExecStartParameters.Generated.cs b/src/Docker.DotNet/Models/ContainerExecStartParameters.Generated.cs index fb123489..cb76cac8 100644 --- a/src/Docker.DotNet/Models/ContainerExecStartParameters.Generated.cs +++ b/src/Docker.DotNet/Models/ContainerExecStartParameters.Generated.cs @@ -9,6 +9,7 @@ public class ContainerExecStartParameters // (main.ContainerExecStartParameters) public bool TTY { get; set; } [JsonPropertyName("ConsoleSize")] + [JsonConverter(typeof(ConsoleSizeConverter))] public ConsoleSize ConsoleSize { get; set; } } } diff --git a/src/Docker.DotNet/Models/HostConfig.Generated.cs b/src/Docker.DotNet/Models/HostConfig.Generated.cs index a294e70c..3632a0b3 100644 --- a/src/Docker.DotNet/Models/HostConfig.Generated.cs +++ b/src/Docker.DotNet/Models/HostConfig.Generated.cs @@ -70,7 +70,8 @@ public HostConfig(Resources Resources) public IList VolumesFrom { get; set; } [JsonPropertyName("ConsoleSize")] - public ulong[] ConsoleSize { get; set; } + [JsonConverter(typeof(ConsoleSizeConverter))] + public ConsoleSize ConsoleSize { get; set; } [JsonPropertyName("Annotations")] public IDictionary Annotations { get; set; } diff --git a/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs b/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs index d75a0832..cdf14140 100644 --- a/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs +++ b/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs @@ -2,146 +2,98 @@ namespace Docker.DotNet.Tests; public sealed class ConsoleSizeConverterTests { - [Fact] - public void Serialize_ConsoleSize_ProducesJsonArray() - { - // Given - var consoleSize = new ConsoleSize { Height = 24, Width = 80 }; - - // When - var jsonString = JsonSerializer.Instance.Serialize(consoleSize); - - // Then - Assert.Equal("[24,80]", jsonString); - } - - [Fact] - public void Deserialize_JsonArray_ProducesConsoleSize() - { - // Given - var json = "[24,80]"; - - // When - var consoleSize = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); - - // Then - Assert.NotNull(consoleSize); - Assert.Equal(24UL, consoleSize.Height); - Assert.Equal(80UL, consoleSize.Width); - } + private const ulong Height = 24; + private const ulong Width = 80; [Fact] - public void SerializeAndDeserialize_RoundTrip_Succeeds() + public void Serialize_ConsoleSize_ProducesJsonObject() { - // Given - var original = new ConsoleSize { Height = 50, Width = 200 }; + var consoleSize = new ConsoleSize { Height = Height, Width = Width }; - // When - var jsonString = JsonSerializer.Instance.Serialize(original); - var deserialized = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(jsonString)); + var jsonString = JsonSerializer.Instance.Serialize(consoleSize); - // Then - Assert.NotNull(deserialized); - Assert.Equal(original.Height, deserialized.Height); - Assert.Equal(original.Width, deserialized.Width); + Assert.Equal("{\"Height\":24,\"Width\":80}", jsonString); } [Fact] public void Serialize_ContainerExecCreateParameters_WithConsoleSize_ProducesArrayFormat() { - // Given var parameters = new ContainerExecCreateParameters { - ConsoleSize = new ConsoleSize { Height = 24, Width = 80 }, + ConsoleSize = new ConsoleSize { Height = Height, Width = Width }, AttachStdin = true, AttachStdout = true, TTY = true, Cmd = new List { "/bin/bash" } }; - // When var jsonString = JsonSerializer.Instance.Serialize(parameters); - // Then - ConsoleSize should be serialized as [24,80], not {"Height":24,"Width":80} Assert.Contains("\"ConsoleSize\":[24,80]", jsonString); - Assert.DoesNotContain("\"Height\"", jsonString); - Assert.DoesNotContain("\"Width\"", jsonString); } [Fact] - public void Serialize_ContainerExecCreateParameters_WithoutConsoleSize_OmitsField() + public void Deserialize_ContainerExecCreateParameters_WithArrayConsoleSize_Succeeds() { - // Given - var parameters = new ContainerExecCreateParameters - { - AttachStdin = true, - AttachStdout = true, - TTY = true, - Cmd = new List { "/bin/bash" } - }; + var json = "{\"ConsoleSize\":[24,80],\"AttachStdin\":true,\"Tty\":true,\"Cmd\":[\"/bin/bash\"]}"; - // When - var jsonString = JsonSerializer.Instance.Serialize(parameters); + var parameters = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); - // Then - Assert.DoesNotContain("ConsoleSize", jsonString); + Assert.NotNull(parameters); + Assert.NotNull(parameters.ConsoleSize); + Assert.Equal(Height, parameters.ConsoleSize.Height); + Assert.Equal(Width, parameters.ConsoleSize.Width); } [Fact] public void Serialize_ContainerExecStartParameters_WithConsoleSize_ProducesArrayFormat() { - // Given var parameters = new ContainerExecStartParameters { - ConsoleSize = new ConsoleSize { Height = 30, Width = 120 } + ConsoleSize = new ConsoleSize { Height = Height, Width = Width } }; - // When var jsonString = JsonSerializer.Instance.Serialize(parameters); - // Then - Assert.Contains("\"ConsoleSize\":[30,120]", jsonString); + Assert.Contains("\"ConsoleSize\":[24,80]", jsonString); } [Fact] - public void Deserialize_ContainerExecCreateParameters_WithArrayConsoleSize_Succeeds() + public void Deserialize_ContainerExecStartParameters_WithArrayConsoleSize_Succeeds() { - // Given - This is the format Docker API would return - var json = "{\"ConsoleSize\":[24,80],\"AttachStdin\":true,\"Tty\":true,\"Cmd\":[\"/bin/bash\"]}"; + var json = "{\"ConsoleSize\":[24,80]}"; - // When - var parameters = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); + var parameters = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); - // Then Assert.NotNull(parameters); Assert.NotNull(parameters.ConsoleSize); - Assert.Equal(24UL, parameters.ConsoleSize.Height); - Assert.Equal(80UL, parameters.ConsoleSize.Width); + Assert.Equal(Height, parameters.ConsoleSize.Height); + Assert.Equal(Width, parameters.ConsoleSize.Width); } [Fact] - public void Serialize_LargeConsoleSize_HandlesCorrectly() + public void Serialize_HostConfig_WithConsoleSize_ProducesArrayFormat() { - // Given - Test with larger values that still fit in ulong - var consoleSize = new ConsoleSize { Height = 1000, Width = 2000 }; + var hostConfig = new HostConfig + { + ConsoleSize = new ConsoleSize { Height = Height, Width = Width } + }; - // When - var jsonString = JsonSerializer.Instance.Serialize(consoleSize); + var jsonString = JsonSerializer.Instance.Serialize(hostConfig); - // Then - Assert.Equal("[1000,2000]", jsonString); + Assert.Contains("\"ConsoleSize\":[24,80]", jsonString); } [Fact] - public void Serialize_ZeroConsoleSize_HandlesCorrectly() + public void Deserialize_HostConfig_WithArrayConsoleSize_Succeeds() { - // Given - var consoleSize = new ConsoleSize { Height = 0, Width = 0 }; + var json = "{\"ConsoleSize\":[24,80]}"; - // When - var jsonString = JsonSerializer.Instance.Serialize(consoleSize); + var hostConfig = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); - // Then - Assert.Equal("[0,0]", jsonString); + Assert.NotNull(hostConfig); + Assert.NotNull(hostConfig.ConsoleSize); + Assert.Equal(Height, hostConfig.ConsoleSize.Height); + Assert.Equal(Width, hostConfig.ConsoleSize.Width); } } diff --git a/tools/specgen/specgen.go b/tools/specgen/specgen.go index 30f269ae..d0c4315e 100644 --- a/tools/specgen/specgen.go +++ b/tools/specgen/specgen.go @@ -55,6 +55,15 @@ var typesToDisambiguate = map[string]*CSModelType{ }, }, }, + typeToKey(reflect.TypeOf(container.HostConfig{})): { + Properties: []CSProperty{ + { + Name: "ConsoleSize", + Type: CSType{"", "ConsoleSize", true}, + Attributes: []CSAttribute{{Type: CSType{"System.Text.Json.Serialization", "JsonConverter", false}, Arguments: []CSArgument{{Value: "typeof(ConsoleSizeConverter)"}}}}, + }, + }, + }, typeToKey(reflect.TypeOf(container.CreateResponse{})): {Name: "CreateContainerResponse"}, typeToKey(reflect.TypeOf(container.HealthConfig{})): { Properties: []CSProperty{ @@ -101,6 +110,24 @@ var typesToDisambiguate = map[string]*CSModelType{ }, }, }, + typeToKey(reflect.TypeOf(ContainerExecCreateParameters{})): { + Properties: []CSProperty{ + { + Name: "ConsoleSize", + Type: CSType{"", "ConsoleSize", true}, + Attributes: []CSAttribute{{Type: CSType{"System.Text.Json.Serialization", "JsonConverter", false}, Arguments: []CSArgument{{Value: "typeof(ConsoleSizeConverter)"}}}}, + }, + }, + }, + typeToKey(reflect.TypeOf(ContainerExecStartParameters{})): { + Properties: []CSProperty{ + { + Name: "ConsoleSize", + Type: CSType{"", "ConsoleSize", true}, + Attributes: []CSAttribute{{Type: CSType{"System.Text.Json.Serialization", "JsonConverter", false}, Arguments: []CSArgument{{Value: "typeof(ConsoleSizeConverter)"}}}}, + }, + }, + }, typeToKey(reflect.TypeOf(volume.AccessMode{})): {Name: "VolumeAccessMode"}, typeToKey(reflect.TypeOf(volume.Info{})): {Name: "VolumeInfo"}, typeToKey(reflect.TypeOf(volume.Secret{})): {Name: "VolumeSecret"}, From 96422e53d06cb87dbef7bf1d22b0e963be5ec6bc Mon Sep 17 00:00:00 2001 From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:26:11 +0100 Subject: [PATCH 4/5] chore: Apply suggestions --- src/Docker.DotNet/ConsoleSizeConverter.cs | 41 +++++++++++----- .../ConsoleSizeConverterTests.cs | 49 ++++++++++--------- .../Docker.DotNet.Tests.csproj | 1 + 3 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/Docker.DotNet/ConsoleSizeConverter.cs b/src/Docker.DotNet/ConsoleSizeConverter.cs index 384f1c36..feae98d3 100644 --- a/src/Docker.DotNet/ConsoleSizeConverter.cs +++ b/src/Docker.DotNet/ConsoleSizeConverter.cs @@ -1,12 +1,6 @@ -using Docker.DotNet.Models; - namespace Docker.DotNet; -/// -/// Serializes as a JSON array [height, width] to match -/// the Docker Engine API's Go type [2]uint. -/// -internal class ConsoleSizeConverter : JsonConverter +internal sealed class ConsoleSizeConverter : JsonConverter { public override ConsoleSize? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { @@ -20,13 +14,19 @@ internal class ConsoleSizeConverter : JsonConverter throw new JsonException("Expected a JSON array for ConsoleSize."); } - reader.Read(); - var height = reader.GetUInt64(); + var height = ReadArrayElement(ref reader, "height"); + + var width = ReadArrayElement(ref reader, "width"); - reader.Read(); - var width = reader.GetUInt64(); + if (!reader.Read()) + { + throw new JsonException("Expected the ConsoleSize array to end after two numeric elements."); + } - reader.Read(); + if (reader.TokenType != JsonTokenType.EndArray) + { + throw new JsonException("Expected the ConsoleSize array to contain exactly two numeric elements."); + } return new ConsoleSize { @@ -35,6 +35,21 @@ internal class ConsoleSizeConverter : JsonConverter }; } + private static ulong ReadArrayElement(ref Utf8JsonReader reader, string elementName) + { + if (!reader.Read()) + { + throw new JsonException($"Expected a numeric '{elementName}' element in the ConsoleSize array."); + } + + if (reader.TokenType != JsonTokenType.Number) + { + throw new JsonException($"Expected the ConsoleSize '{elementName}' element to be a number."); + } + + return reader.GetUInt64(); + } + public override void Write(Utf8JsonWriter writer, ConsoleSize? value, JsonSerializerOptions options) { if (value == null) @@ -48,4 +63,4 @@ public override void Write(Utf8JsonWriter writer, ConsoleSize? value, JsonSerial writer.WriteNumberValue(value.Width); writer.WriteEndArray(); } -} +} \ No newline at end of file diff --git a/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs b/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs index cdf14140..baab391b 100644 --- a/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs +++ b/test/Docker.DotNet.Tests/ConsoleSizeConverterTests.cs @@ -3,10 +3,15 @@ namespace Docker.DotNet.Tests; public sealed class ConsoleSizeConverterTests { private const ulong Height = 24; + private const ulong Width = 80; + private const string ConsoleSizeArrayFragment = "\"ConsoleSize\":[24,80]"; + + private const string ConsoleSizeJson = "{\"ConsoleSize\":[24,80]}"; + [Fact] - public void Serialize_ConsoleSize_ProducesJsonObject() + public void Serialize_StandaloneConsoleSize_ProducesJsonObject() { var consoleSize = new ConsoleSize { Height = Height, Width = Width }; @@ -16,29 +21,22 @@ public void Serialize_ConsoleSize_ProducesJsonObject() } [Fact] - public void Serialize_ContainerExecCreateParameters_WithConsoleSize_ProducesArrayFormat() + public void Serialize_ContainerExecCreateParameters_WithConsoleSizeProperty_ProducesArrayFormat() { var parameters = new ContainerExecCreateParameters { ConsoleSize = new ConsoleSize { Height = Height, Width = Width }, - AttachStdin = true, - AttachStdout = true, - TTY = true, - Cmd = new List { "/bin/bash" } }; var jsonString = JsonSerializer.Instance.Serialize(parameters); - Assert.Contains("\"ConsoleSize\":[24,80]", jsonString); + Assert.Contains(ConsoleSizeArrayFragment, jsonString); } [Fact] public void Deserialize_ContainerExecCreateParameters_WithArrayConsoleSize_Succeeds() { - var json = "{\"ConsoleSize\":[24,80],\"AttachStdin\":true,\"Tty\":true,\"Cmd\":[\"/bin/bash\"]}"; - - var parameters = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); - + var parameters = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(ConsoleSizeJson)); Assert.NotNull(parameters); Assert.NotNull(parameters.ConsoleSize); Assert.Equal(Height, parameters.ConsoleSize.Height); @@ -46,7 +44,7 @@ public void Deserialize_ContainerExecCreateParameters_WithArrayConsoleSize_Succe } [Fact] - public void Serialize_ContainerExecStartParameters_WithConsoleSize_ProducesArrayFormat() + public void Serialize_ContainerExecStartParameters_WithConsoleSizeProperty_ProducesArrayFormat() { var parameters = new ContainerExecStartParameters { @@ -55,16 +53,13 @@ public void Serialize_ContainerExecStartParameters_WithConsoleSize_ProducesArray var jsonString = JsonSerializer.Instance.Serialize(parameters); - Assert.Contains("\"ConsoleSize\":[24,80]", jsonString); + Assert.Contains(ConsoleSizeArrayFragment, jsonString); } [Fact] public void Deserialize_ContainerExecStartParameters_WithArrayConsoleSize_Succeeds() { - var json = "{\"ConsoleSize\":[24,80]}"; - - var parameters = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); - + var parameters = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(ConsoleSizeJson)); Assert.NotNull(parameters); Assert.NotNull(parameters.ConsoleSize); Assert.Equal(Height, parameters.ConsoleSize.Height); @@ -72,7 +67,7 @@ public void Deserialize_ContainerExecStartParameters_WithArrayConsoleSize_Succee } [Fact] - public void Serialize_HostConfig_WithConsoleSize_ProducesArrayFormat() + public void Serialize_HostConfig_WithConsoleSizeProperty_ProducesArrayFormat() { var hostConfig = new HostConfig { @@ -81,19 +76,25 @@ public void Serialize_HostConfig_WithConsoleSize_ProducesArrayFormat() var jsonString = JsonSerializer.Instance.Serialize(hostConfig); - Assert.Contains("\"ConsoleSize\":[24,80]", jsonString); + Assert.Contains(ConsoleSizeArrayFragment, jsonString); } [Fact] public void Deserialize_HostConfig_WithArrayConsoleSize_Succeeds() { - var json = "{\"ConsoleSize\":[24,80]}"; - - var hostConfig = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(json)); - + var hostConfig = JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(ConsoleSizeJson)); Assert.NotNull(hostConfig); Assert.NotNull(hostConfig.ConsoleSize); Assert.Equal(Height, hostConfig.ConsoleSize.Height); Assert.Equal(Width, hostConfig.ConsoleSize.Width); } -} + + [Theory] + [InlineData("{\"ConsoleSize\":[24]}")] + [InlineData("{\"ConsoleSize\":[24,80,1]}")] + [InlineData("{\"ConsoleSize\":[\"24\",80]}")] + public void Deserialize_ContainerExecCreateParameters_WithInvalidArrayConsoleSize_ThrowsJsonException(string jsonString) + { + Assert.Throws(() => JsonSerializer.Instance.Deserialize(Encoding.UTF8.GetBytes(jsonString))); + } +} \ No newline at end of file diff --git a/test/Docker.DotNet.Tests/Docker.DotNet.Tests.csproj b/test/Docker.DotNet.Tests/Docker.DotNet.Tests.csproj index 0c0c14ed..2d80e0e5 100644 --- a/test/Docker.DotNet.Tests/Docker.DotNet.Tests.csproj +++ b/test/Docker.DotNet.Tests/Docker.DotNet.Tests.csproj @@ -27,6 +27,7 @@ + From 01539163f2300e468219305c9a66025187b27aab Mon Sep 17 00:00:00 2001 From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com> Date: Wed, 25 Mar 2026 14:50:05 +0100 Subject: [PATCH 5/5] chore: Remove BOM --- .../Endpoints/DockerSwarmNodeAlreadyParticipatingException.cs | 2 +- .../Endpoints/DockerSwarmNodeNotParticipatingException.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Docker.DotNet/Endpoints/DockerSwarmNodeAlreadyParticipatingException.cs b/src/Docker.DotNet/Endpoints/DockerSwarmNodeAlreadyParticipatingException.cs index 0b6e76d4..417b2754 100644 --- a/src/Docker.DotNet/Endpoints/DockerSwarmNodeAlreadyParticipatingException.cs +++ b/src/Docker.DotNet/Endpoints/DockerSwarmNodeAlreadyParticipatingException.cs @@ -1,4 +1,4 @@ -namespace Docker.DotNet; +namespace Docker.DotNet; public class DockerSwarmNodeAlreadyParticipatingException : DockerApiException { diff --git a/src/Docker.DotNet/Endpoints/DockerSwarmNodeNotParticipatingException.cs b/src/Docker.DotNet/Endpoints/DockerSwarmNodeNotParticipatingException.cs index 678dc60b..ca941579 100644 --- a/src/Docker.DotNet/Endpoints/DockerSwarmNodeNotParticipatingException.cs +++ b/src/Docker.DotNet/Endpoints/DockerSwarmNodeNotParticipatingException.cs @@ -1,4 +1,4 @@ -namespace Docker.DotNet; +namespace Docker.DotNet; public class DockerSwarmNodeNotParticipatingException : DockerApiException {