Skip to content

Commit 140f177

Browse files
authored
Converge implementations of AwaitableProcess and ProcessEx (#26069)
* Converge implementations of AwaitableProcess and ProcessEx * dotnet-watch tests are running in to the same issue as GRPC tests (https://github.com/dotnet/aspnetcore/pull/20341/files). This change carries over some of the patterns from the other type to remedy this issue. * Revive dotnet-watch tests on OSX * Remove build artifacts that were accidentally commited to source.
1 parent 7afaf45 commit 140f177

File tree

5 files changed

+32
-45
lines changed

5 files changed

+32
-45
lines changed

src/Tools/dotnet-watch/test/AwaitableProcess.cs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,24 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
1515
{
1616
public class AwaitableProcess : IDisposable
1717
{
18+
private readonly object _testOutputLock = new object();
19+
1820
private Process _process;
1921
private readonly ProcessSpec _spec;
2022
private readonly List<string> _lines;
2123
private BufferBlock<string> _source;
2224
private ITestOutputHelper _logger;
2325
private TaskCompletionSource<int> _exited;
2426
private bool _started;
27+
private bool _disposed;
2528

2629
public AwaitableProcess(ProcessSpec spec, ITestOutputHelper logger)
2730
{
2831
_spec = spec;
2932
_logger = logger;
3033
_source = new BufferBlock<string>();
3134
_lines = new List<string>();
32-
_exited = new TaskCompletionSource<int>();
35+
_exited = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
3336
}
3437

3538
public IEnumerable<string> Output => _lines;
@@ -72,25 +75,25 @@ public void Start()
7275
_process.ErrorDataReceived += OnData;
7376
_process.Exited += OnExit;
7477

75-
_logger.WriteLine($"{DateTime.Now}: starting process: '{_process.StartInfo.FileName} {_process.StartInfo.Arguments}'");
78+
WriteTestOutput($"{DateTime.Now}: starting process: '{_process.StartInfo.FileName} {_process.StartInfo.Arguments}'");
7679
_process.Start();
7780
_started = true;
7881
_process.BeginErrorReadLine();
7982
_process.BeginOutputReadLine();
80-
_logger.WriteLine($"{DateTime.Now}: process started: '{_process.StartInfo.FileName} {_process.StartInfo.Arguments}'");
83+
WriteTestOutput($"{DateTime.Now}: process started: '{_process.StartInfo.FileName} {_process.StartInfo.Arguments}'");
8184
}
8285

8386
public async Task<string> GetOutputLineAsync(string message, TimeSpan timeout)
8487
{
85-
_logger.WriteLine($"Waiting for output line [msg == '{message}']. Will wait for {timeout.TotalSeconds} sec.");
88+
WriteTestOutput($"Waiting for output line [msg == '{message}']. Will wait for {timeout.TotalSeconds} sec.");
8689
var cts = new CancellationTokenSource();
8790
cts.CancelAfter(timeout);
8891
return await GetOutputLineAsync($"[msg == '{message}']", m => string.Equals(m, message, StringComparison.Ordinal), cts.Token);
8992
}
9093

9194
public async Task<string> GetOutputLineStartsWithAsync(string message, TimeSpan timeout)
9295
{
93-
_logger.WriteLine($"Waiting for output line [msg.StartsWith('{message}')]. Will wait for {timeout.TotalSeconds} sec.");
96+
WriteTestOutput($"Waiting for output line [msg.StartsWith('{message}')]. Will wait for {timeout.TotalSeconds} sec.");
9497
var cts = new CancellationTokenSource();
9598
cts.CancelAfter(timeout);
9699
return await GetOutputLineAsync($"[msg.StartsWith('{message}')]", m => m != null && m.StartsWith(message, StringComparison.Ordinal), cts.Token);
@@ -105,7 +108,7 @@ private async Task<string> GetOutputLineAsync(string predicateName, Predicate<st
105108
var next = await _source.ReceiveAsync(cancellationToken);
106109
_lines.Add(next);
107110
var match = predicate(next);
108-
_logger.WriteLine($"{DateTime.Now}: recv: '{next}'. {(match ? "Matches" : "Does not match")} condition '{predicateName}'.");
111+
WriteTestOutput($"{DateTime.Now}: recv: '{next}'. {(match ? "Matches" : "Does not match")} condition '{predicateName}'.");
109112
if (match)
110113
{
111114
return next;
@@ -124,7 +127,7 @@ public async Task<IList<string>> GetAllOutputLinesAsync(CancellationToken cancel
124127
while (await _source.OutputAvailableAsync(cancellationToken))
125128
{
126129
var next = await _source.ReceiveAsync(cancellationToken);
127-
_logger.WriteLine($"{DateTime.Now}: recv: '{next}'");
130+
WriteTestOutput($"{DateTime.Now}: recv: '{next}'");
128131
lines.Add(next);
129132
}
130133
}
@@ -134,30 +137,50 @@ public async Task<IList<string>> GetAllOutputLinesAsync(CancellationToken cancel
134137
private void OnData(object sender, DataReceivedEventArgs args)
135138
{
136139
var line = args.Data ?? string.Empty;
137-
_logger.WriteLine($"{DateTime.Now}: post: '{line}'");
140+
141+
WriteTestOutput($"{DateTime.Now}: post: '{line}'");
138142
_source.Post(line);
139143
}
140144

145+
private void WriteTestOutput(string text)
146+
{
147+
lock (_testOutputLock)
148+
{
149+
if (!_disposed)
150+
{
151+
_logger.WriteLine(text);
152+
}
153+
}
154+
}
155+
141156
private void OnExit(object sender, EventArgs args)
142157
{
143158
// Wait to ensure the process has exited and all output consumed
144159
_process.WaitForExit();
145160
_source.Complete();
146161
_exited.TrySetResult(_process.ExitCode);
147-
_logger.WriteLine($"Process {_process.Id} has exited");
162+
WriteTestOutput($"Process {_process.Id} has exited");
148163
}
149164

150165
public void Dispose()
151166
{
152167
_source.Complete();
153168

169+
lock (_testOutputLock)
170+
{
171+
_disposed = true;
172+
}
173+
154174
if (_process != null)
155175
{
156176
if (_started && !_process.HasExited)
157177
{
158178
_process.KillTree();
159179
}
160180

181+
_process.CancelErrorRead();
182+
_process.CancelOutputRead();
183+
161184
_process.ErrorDataReceived -= OnData;
162185
_process.OutputDataReceived -= OnData;
163186
_process.Exited -= OnExit;

src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/.NETCoreApp,Version=v5.0.AssemblyAttributes.cs

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/KitchenSink.AssemblyInfo.cs

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/Tools/dotnet-watch/test/TestProjects/KitchenSink/.net/objDebug/net5.0/KitchenSink.AssemblyInfoInputs.cache

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/Tools/dotnet-watch/test/dotnet-watch.Tests.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
-->
1313
<UseAspNetCoreSharedRuntime>true</UseAspNetCoreSharedRuntime>
1414
<DoNotApplyWorkaroundsToMicrosoftAspNetCoreApp>true</DoNotApplyWorkaroundsToMicrosoftAspNetCoreApp>
15-
16-
<!-- Skipped due to https://github.com/dotnet/aspnetcore/issues/26061 -->
17-
<SkipTests Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</SkipTests>
1815
</PropertyGroup>
1916

2017
<ItemGroup>

0 commit comments

Comments
 (0)