Skip to content

Commit 932a3eb

Browse files
committed
Fixup
1 parent c559579 commit 932a3eb

File tree

2 files changed

+153
-46
lines changed

2 files changed

+153
-46
lines changed

test/Docker.DotNet.Tests/ISwarmOperationsTests.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
4+
using System.Text;
35
using System.Threading;
46
using System.Threading.Tasks;
57
using Docker.DotNet.Models;
@@ -10,11 +12,18 @@ namespace Docker.DotNet.Tests
1012
[Collection(nameof(TestCollection))]
1113
public class ISwarmOperationsTests
1214
{
15+
private readonly CancellationTokenSource _cts;
16+
1317
private readonly DockerClient _dockerClient;
1418
private readonly string _imageId;
1519

1620
public ISwarmOperationsTests(TestFixture testFixture)
1721
{
22+
// Do not wait forever in case it gets stuck
23+
_cts = CancellationTokenSource.CreateLinkedTokenSource(testFixture.Cts.Token);
24+
_cts.CancelAfter(TimeSpan.FromMinutes(5));
25+
_cts.Token.Register(() => throw new TimeoutException("SwarmOperationTests timeout"));
26+
1827
_dockerClient = testFixture.DockerClient;
1928
_imageId = testFixture.Image.ID;
2029
}
@@ -148,5 +157,103 @@ public async Task GetServices_Succeeds()
148157
await _dockerClient.Swarm.RemoveServiceAsync(secondServiceId, default);
149158
await _dockerClient.Swarm.RemoveServiceAsync(thirdServiceid, default);
150159
}
160+
161+
[Fact]
162+
public async Task GetServiceLogs_Succeeds()
163+
{
164+
var cts = new CancellationTokenSource();
165+
var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, cts.Token);
166+
167+
var serviceName = $"service-withLogs-{Guid.NewGuid().ToString().Substring(1, 10)}";
168+
var serviceId = _dockerClient.Swarm.CreateServiceAsync(new ServiceCreateParameters
169+
{
170+
Service = new ServiceSpec
171+
{
172+
Name = serviceName,
173+
TaskTemplate = new TaskSpec { ContainerSpec = new ContainerSpec { Image = _imageId } }
174+
}
175+
}).Result.ID;
176+
177+
var _stream = await _dockerClient.Swarm.GetServiceLogsAsync(serviceName, false, new ServiceLogsParameters
178+
{
179+
Follow = true,
180+
ShowStdout = true,
181+
ShowStderr = true
182+
});
183+
184+
int maxRetries = 3;
185+
int currentRetry = 0;
186+
TimeSpan delayBetweenRetries = TimeSpan.FromSeconds(5);
187+
List<string> logLines = null;
188+
189+
while (currentRetry < maxRetries && !linkedCts.IsCancellationRequested)
190+
{
191+
logLines = new List<string>();
192+
TimeSpan delay = TimeSpan.FromSeconds(10);
193+
cts.CancelAfter(delay);
194+
195+
bool cancelRequested = false; // Add a flag to indicate cancellation
196+
197+
while (!linkedCts.IsCancellationRequested && !cancelRequested)
198+
{
199+
var line = new List<byte>();
200+
var buffer = new byte[4096];
201+
202+
try
203+
{
204+
while (true)
205+
{
206+
var res = await _stream.ReadOutputAsync(buffer, 0, buffer.Length, linkedCts.Token);
207+
208+
if (res.Count == 0)
209+
{
210+
continue;
211+
}
212+
213+
int newlineIndex = Array.IndexOf(buffer, (byte)'\n', 0, res.Count);
214+
215+
if (newlineIndex != -1)
216+
{
217+
line.AddRange(buffer.Take(newlineIndex));
218+
break;
219+
}
220+
else
221+
{
222+
line.AddRange(buffer.Take(res.Count));
223+
}
224+
}
225+
226+
logLines.Add(Encoding.UTF8.GetString(line.ToArray()));
227+
}
228+
catch (OperationCanceledException)
229+
{
230+
cancelRequested = true; // Set the flag when cancellation is requested
231+
232+
// Reset the CancellationTokenSource for the next attempt
233+
cts = new CancellationTokenSource();
234+
linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, cts.Token);
235+
cts.CancelAfter(delay);
236+
}
237+
}
238+
239+
if (logLines.Any() && logLines.First().Contains("[INF]"))
240+
{
241+
break;
242+
}
243+
else
244+
{
245+
currentRetry++;
246+
if (currentRetry < maxRetries)
247+
{
248+
await Task.Delay(delayBetweenRetries);
249+
}
250+
}
251+
}
252+
253+
Assert.True(logLines.Any());
254+
Assert.Contains("[INF]", logLines.First());
255+
256+
await _dockerClient.Swarm.RemoveServiceAsync(serviceId, default);
257+
}
151258
}
152259
}
Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,46 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using Docker.DotNet.Models;
4-
using Xunit;
5-
6-
namespace Docker.DotNet.Tests
7-
{
8-
public class QueryStringTests
9-
{
10-
[Fact]
11-
public void ServiceListParameters_GenerateIdFilters()
12-
{
13-
var p = new ServicesListParameters { Filters = new ServiceFilter { Id = new string[] { "service-id" } } };
14-
var qs = new QueryString<ServicesListParameters>(p);
15-
16-
Assert.Equal("filters={\"id\":[\"service-id\"]}", Uri.UnescapeDataString(qs.GetQueryString()));
17-
}
18-
19-
[Fact]
20-
public void ServiceListParameters_GenerateCompositeFilters()
21-
{
22-
var p = new ServicesListParameters { Filters = new ServiceFilter { Id = new string[] { "service-id" }, Label = new string[] { "label" } } };
23-
var qs = new QueryString<ServicesListParameters>(p);
24-
25-
Assert.Equal("filters={\"id\":[\"service-id\"],\"label\":[\"label\"]}", Uri.UnescapeDataString(qs.GetQueryString()));
26-
}
27-
28-
[Fact]
29-
public void ServicesListParameters_GenerateNullFilters()
30-
{
31-
var p = new ServicesListParameters { Filters = new ServiceFilter() };
32-
var qs = new QueryString<ServicesListParameters>(p);
33-
34-
Assert.Equal("filters={}", Uri.UnescapeDataString(qs.GetQueryString()));
35-
}
36-
37-
[Fact]
38-
public void ServicesListParameters_GenerateNullModeFilters()
39-
{
40-
var p = new ServicesListParameters { Filters = new ServiceFilter() { Mode = new ServiceCreationMode[] { } } };
41-
var qs = new QueryString<ServicesListParameters>(p);
42-
43-
Assert.Equal("filters={\"mode\":[]}", Uri.UnescapeDataString(qs.GetQueryString()));
44-
}
45-
}
46-
}
1+
using System;
2+
using System.Collections.Generic;
3+
using Docker.DotNet.Models;
4+
using Xunit;
5+
6+
namespace Docker.DotNet.Tests
7+
{
8+
public class QueryStringTests
9+
{
10+
[Fact]
11+
public void ServiceListParameters_GenerateIdFilters()
12+
{
13+
var p = new ServicesListParameters { Filters = new ServiceFilter { Id = new string[] { "service-id" } } };
14+
var qs = new QueryString<ServicesListParameters>(p);
15+
16+
Assert.Equal("filters={\"id\":[\"service-id\"]}", Uri.UnescapeDataString(qs.GetQueryString()));
17+
}
18+
19+
[Fact]
20+
public void ServiceListParameters_GenerateCompositeFilters()
21+
{
22+
var p = new ServicesListParameters { Filters = new ServiceFilter { Id = new string[] { "service-id" }, Label = new string[] { "label" } } };
23+
var qs = new QueryString<ServicesListParameters>(p);
24+
25+
Assert.Equal("filters={\"id\":[\"service-id\"],\"label\":[\"label\"]}", Uri.UnescapeDataString(qs.GetQueryString()));
26+
}
27+
28+
[Fact]
29+
public void ServicesListParameters_GenerateNullFilters()
30+
{
31+
var p = new ServicesListParameters { Filters = new ServiceFilter() };
32+
var qs = new QueryString<ServicesListParameters>(p);
33+
34+
Assert.Equal("filters={}", Uri.UnescapeDataString(qs.GetQueryString()));
35+
}
36+
37+
[Fact]
38+
public void ServicesListParameters_GenerateNullModeFilters()
39+
{
40+
var p = new ServicesListParameters { Filters = new ServiceFilter() { Mode = new ServiceCreationMode[] { } } };
41+
var qs = new QueryString<ServicesListParameters>(p);
42+
43+
Assert.Equal("filters={\"mode\":[]}", Uri.UnescapeDataString(qs.GetQueryString()));
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)