Skip to content

Commit 758773b

Browse files
premunmandel-macaque
authored andcommittedOct 21, 2020
[xharness] Do not mark DeviceLoaders as loaded when loading fails (#9367)
1 parent 4fd3a30 commit 758773b

File tree

4 files changed

+92
-10
lines changed

4 files changed

+92
-10
lines changed
 

‎tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared.Tests/Hardware/DevicesTest.cs

+46-3
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,53 @@ public async Task LoadAsyncProcessSuccess (bool extraData)
113113
Assert.AreEqual (0, devices.ConnectedTV.Count ());
114114
}
115115

116-
private void AssertArgumentValue (MlaunchArgument arg, string expected, string message = null)
116+
[Test]
117+
public async Task FindAndCacheDevicesWithFailingMlaunchTest ()
117118
{
118-
var value = arg.AsCommandLineArgument ().Split (new char [] { '=' }, 2).LastOrDefault ();
119-
Assert.AreEqual (expected, value, message);
119+
string processPath = null;
120+
MlaunchArguments passedArguments = null;
121+
122+
// Moq.SetupSequence doesn't allow custom callbacks so we need to count ourselves
123+
var calls = 0;
124+
125+
// moq It.Is is not working as nicelly as we would like it, we capture data and use asserts
126+
processManager.Setup (p => p.RunAsync (It.IsAny<Process> (), It.IsAny<MlaunchArguments> (), It.IsAny<ILog> (), It.IsAny<TimeSpan?> (), It.IsAny<Dictionary<string, string>> (), It.IsAny<CancellationToken?> (), It.IsAny<bool?> ()))
127+
.Returns<Process, MlaunchArguments, ILog, TimeSpan?, Dictionary<string, string>, CancellationToken?, bool?> ((p, args, log, t, env, token, d) => {
128+
calls++;
129+
130+
if (calls == 1) {
131+
// Mlaunch can sometimes time out and we are testing that a subsequent Load will trigger it again
132+
return Task.FromResult (new ProcessExecutionResult { ExitCode = 137, TimedOut = true });
133+
}
134+
135+
processPath = p.StartInfo.FileName;
136+
passedArguments = args;
137+
138+
// we get the temp file that was passed as the args, and write our sample xml, which will be parsed to get the devices :)
139+
var tempPath = args.Where (a => a is ListDevicesArgument).First ().AsCommandLineArgument ();
140+
tempPath = tempPath.Substring (tempPath.IndexOf ('=') + 1).Replace ("\"", string.Empty);
141+
142+
var name = GetType ().Assembly.GetManifestResourceNames ().Where (a => a.EndsWith ("devices.xml", StringComparison.Ordinal)).FirstOrDefault ();
143+
using (var outputStream = new StreamWriter (tempPath))
144+
using (var sampleStream = new StreamReader (GetType ().Assembly.GetManifestResourceStream (name))) {
145+
string line;
146+
while ((line = sampleStream.ReadLine ()) != null)
147+
outputStream.WriteLine (line);
148+
}
149+
return Task.FromResult (new ProcessExecutionResult { ExitCode = 0, TimedOut = false });
150+
});
151+
152+
Assert.ThrowsAsync<Exception> (async () => await devices.LoadDevices (executionLog.Object));
153+
154+
Assert.IsEmpty (devices.ConnectedDevices);
155+
Assert.AreEqual (1, calls);
156+
await devices.LoadDevices (executionLog.Object);
157+
Assert.AreEqual (2, calls);
158+
Assert.IsNotEmpty (devices.ConnectedDevices);
159+
await devices.LoadDevices (executionLog.Object);
160+
Assert.AreEqual (2, calls);
161+
await devices.LoadDevices (executionLog.Object);
162+
Assert.AreEqual (2, calls);
120163
}
121164
}
122165
}

‎tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared.Tests/Hardware/SimulatorsTest.cs

+34-3
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,41 @@ public async Task FindAsyncDoNotCreateTest (TestTarget target, int expected)
149149
Assert.AreEqual (expected, sims.Count (), $"{target} simulators count");
150150
}
151151

152-
private void AssertArgumentValue (MlaunchArgument arg, string expected, string message = null)
152+
[Test]
153+
public async Task FindAndCacheSimulatorsWithFailingMlaunchTest ()
153154
{
154-
var value = arg.AsCommandLineArgument ().Split (new char [] { '=' }, 2).LastOrDefault ();
155-
Assert.AreEqual (expected, value, message);
155+
// Moq.SetupSequence doesn't allow custom callbacks so we need to count ourselves
156+
var calls = 0;
157+
158+
processManager
159+
.Setup (p => p.RunAsync (It.IsAny<Process>(), It.Is<MlaunchArguments> (args => args.Any (a => a is ListSimulatorsArgument)), It.IsAny<ILog> (), It.IsAny<TimeSpan> (), It.IsAny<Dictionary<string, string>> (), It.IsAny<CancellationToken?> (), It.IsAny<bool?> ()))
160+
.Returns<Process, MlaunchArguments, ILog, TimeSpan, Dictionary<string, string>, CancellationToken?, bool?> ((process, args, log, t, env, token, diagnostics) => {
161+
calls++;
162+
163+
if (calls == 1) {
164+
// Mlaunch can sometimes time out and we are testing that a subsequent Load will trigger it again
165+
return Task.FromResult (new ProcessExecutionResult { ExitCode = 137, TimedOut = true });
166+
}
167+
168+
// We get the temp file that was passed as the args, and write our sample xml, which will be parsed to get the devices
169+
var tempPath = args.Where (a => a is ListSimulatorsArgument).First ().AsCommandLineArgument ();
170+
tempPath = tempPath.Substring (tempPath.IndexOf ('=') + 1).Replace ("\"", string.Empty);
171+
172+
CopySampleData (tempPath);
173+
return Task.FromResult (new ProcessExecutionResult { ExitCode = 0, TimedOut = false });
174+
});
175+
176+
Assert.ThrowsAsync<Exception> (async () => await simulators.LoadDevices (executionLog.Object));
177+
178+
Assert.IsEmpty (simulators.AvailableDevices);
179+
Assert.AreEqual (1, calls);
180+
await simulators.LoadDevices (executionLog.Object);
181+
Assert.AreEqual (2, calls);
182+
Assert.IsNotEmpty (simulators.AvailableDevices);
183+
await simulators.LoadDevices (executionLog.Object);
184+
Assert.AreEqual (2, calls);
185+
await simulators.LoadDevices (executionLog.Object);
186+
Assert.AreEqual (2, calls);
156187
}
157188
}
158189
}

‎tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Hardware/HardwareDeviceLoader.cs

+10-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Diagnostics;
44
using System.IO;
55
using System.Linq;
6+
using System.Threading;
67
using System.Threading.Tasks;
78
using System.Xml;
89
using Microsoft.DotNet.XHarness.iOS.Shared.Collections;
@@ -27,6 +28,7 @@ public interface IHardwareDeviceLoader : IDeviceLoader {
2728
}
2829

2930
public class HardwareDeviceLoader : IHardwareDeviceLoader {
31+
readonly SemaphoreSlim semaphore = new SemaphoreSlim (1);
3032
readonly IProcessManager processManager;
3133
bool loaded;
3234

@@ -46,14 +48,16 @@ public HardwareDeviceLoader (IProcessManager processManager)
4648

4749
public async Task LoadDevices (ILog log, bool includeLocked = false, bool forceRefresh = false, bool listExtraData = false)
4850
{
51+
await semaphore.WaitAsync ();
52+
4953
if (loaded) {
50-
if (!forceRefresh)
54+
if (!forceRefresh) {
55+
semaphore.Release ();
5156
return;
57+
}
5258
connectedDevices.Reset ();
5359
}
5460

55-
loaded = true;
56-
5761
var tmpfile = Path.GetTempFileName ();
5862
try {
5963
using (var process = new Process ()) {
@@ -92,11 +96,14 @@ public async Task LoadDevices (ILog log, bool includeLocked = false, bool forceR
9296
}
9397
connectedDevices.Add (d);
9498
}
99+
100+
loaded = true;
95101
}
96102
} finally {
97103
connectedDevices.SetCompleted ();
98104
File.Delete (tmpfile);
99105
log.Flush ();
106+
semaphore.Release ();
100107
}
101108
}
102109

‎tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Hardware/SimulatorLoader.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ public async Task LoadDevices (ILog log, bool includeLocked = false, bool forceR
4949
available_devices.Reset ();
5050
available_device_pairs.Reset ();
5151
}
52-
loaded = true;
5352

5453
await Task.Run (async () => {
5554
var tmpfile = Path.GetTempFileName ();
@@ -115,6 +114,8 @@ await Task.Run (async () => {
115114
});
116115
}
117116
}
117+
118+
loaded = true;
118119
} finally {
119120
supported_runtimes.SetCompleted ();
120121
supported_device_types.SetCompleted ();

0 commit comments

Comments
 (0)
Please sign in to comment.