[Harness] Remove Harness as a dependency (#8203)
This commit is contained in:
Родитель
dddcba9dc4
Коммит
6209719f51
|
@ -188,10 +188,6 @@ namespace Xharness {
|
|||
|
||||
var args = new MlaunchArguments ();
|
||||
|
||||
if (!string.IsNullOrEmpty (harness.XcodeRoot)) {
|
||||
args.Add (new SdkRootArgument (harness.XcodeRoot));
|
||||
}
|
||||
|
||||
for (int i = -1; i < harness.Verbosity; i++)
|
||||
args.Add (new VerbosityArgument ());
|
||||
|
||||
|
@ -205,7 +201,7 @@ namespace Xharness {
|
|||
var totalSize = Directory.GetFiles (AppInformation.AppPath, "*", SearchOption.AllDirectories).Select ((v) => new FileInfo (v).Length).Sum ();
|
||||
MainLog.WriteLine ($"Installing '{AppInformation.AppPath}' to '{companionDeviceName ?? deviceName}'. Size: {totalSize} bytes = {totalSize / 1024.0 / 1024.0:N2} MB");
|
||||
|
||||
return await ProcessManager.ExecuteCommandAsync (harness.MlaunchPath, args, MainLog, TimeSpan.FromHours (1), cancellation_token: cancellation_token);
|
||||
return await ProcessManager.ExecuteCommandAsync (args, MainLog, TimeSpan.FromHours (1), cancellation_token: cancellation_token);
|
||||
}
|
||||
|
||||
public async Task<ProcessExecutionResult> UninstallAsync ()
|
||||
|
@ -217,17 +213,13 @@ namespace Xharness {
|
|||
|
||||
var args = new MlaunchArguments ();
|
||||
|
||||
if (!string.IsNullOrEmpty (harness.XcodeRoot)) {
|
||||
args.Add (new SdkRootArgument (harness.XcodeRoot));
|
||||
}
|
||||
|
||||
for (int i = -1; i < harness.Verbosity; i++)
|
||||
args.Add (new VerbosityArgument ());
|
||||
|
||||
args.Add (new UninstallAppFromDeviceArgument (AppInformation.BundleIdentifier));
|
||||
args.Add (new DeviceNameArgument (companionDeviceName ?? deviceName));
|
||||
|
||||
return await ProcessManager.ExecuteCommandAsync (harness.MlaunchPath, args, MainLog, TimeSpan.FromMinutes (1));
|
||||
return await ProcessManager.ExecuteCommandAsync (args, MainLog, TimeSpan.FromMinutes (1));
|
||||
}
|
||||
|
||||
public TimeSpan GetNewTimeout () => TimeSpan.FromMinutes (harness.Timeout * timeoutMultiplier);
|
||||
|
@ -241,10 +233,6 @@ namespace Xharness {
|
|||
|
||||
var args = new MlaunchArguments ();
|
||||
|
||||
if (!string.IsNullOrEmpty (harness.XcodeRoot)) {
|
||||
args.Add (new SdkRootArgument (harness.XcodeRoot));
|
||||
}
|
||||
|
||||
for (int i = -1; i < harness.Verbosity; i++)
|
||||
args.Add (new VerbosityArgument ());
|
||||
|
||||
|
@ -387,7 +375,7 @@ namespace Xharness {
|
|||
MainLog.WriteLine ("Starting test run");
|
||||
|
||||
await testReporter.CollectSimulatorResult (
|
||||
ProcessManager.ExecuteCommandAsync (harness.MlaunchPath, args, run_log, testReporter.Timeout, cancellation_token: testReporter.CancellationToken));
|
||||
ProcessManager.ExecuteCommandAsync (args, run_log, testReporter.Timeout, cancellation_token: testReporter.CancellationToken));
|
||||
|
||||
// cleanup after us
|
||||
if (EnsureCleanSimulatorState)
|
||||
|
@ -419,7 +407,7 @@ namespace Xharness {
|
|||
// We need to check for MT1111 (which means that mlaunch won't wait for the app to exit).
|
||||
var runLog = Log.CreateAggregatedLog (testReporter.CallbackLog, MainLog);
|
||||
testReporter.TimeoutWatch.Start ();
|
||||
await testReporter.CollectDeviceResult (ProcessManager.ExecuteCommandAsync (harness.MlaunchPath, args, runLog, testReporter.Timeout, cancellation_token: testReporter.CancellationToken));
|
||||
await testReporter.CollectDeviceResult (ProcessManager.ExecuteCommandAsync (args, runLog, testReporter.Timeout, cancellation_token: testReporter.CancellationToken));
|
||||
} finally {
|
||||
deviceLogCapturer.StopCapture ();
|
||||
deviceSystemLog.Dispose ();
|
||||
|
|
|
@ -5,6 +5,5 @@ using Xharness.Logging;
|
|||
namespace Xharness.Collections{
|
||||
public interface ILoadAsync {
|
||||
Task LoadAsync (ILog log, bool include_locked, bool force);
|
||||
IHarness Harness { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,18 +17,14 @@ namespace Xharness
|
|||
|
||||
public class CrashSnapshotReporterFactory : ICrashSnapshotReporterFactory {
|
||||
readonly IProcessManager processManager;
|
||||
readonly string xcodeRoot;
|
||||
readonly string mlaunchPath;
|
||||
|
||||
public CrashSnapshotReporterFactory (IProcessManager processManager, string xcodeRoot, string mlaunchPath)
|
||||
public CrashSnapshotReporterFactory (IProcessManager processManager)
|
||||
{
|
||||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
this.xcodeRoot = xcodeRoot ?? throw new ArgumentNullException (nameof (xcodeRoot));
|
||||
this.mlaunchPath = mlaunchPath ?? throw new ArgumentNullException (nameof (mlaunchPath));
|
||||
}
|
||||
|
||||
public ICrashSnapshotReporter Create (ILog log, ILogs logs, bool isDevice, string deviceName) =>
|
||||
new CrashSnapshotReporter (processManager, log, logs, xcodeRoot, mlaunchPath, isDevice, deviceName);
|
||||
new CrashSnapshotReporter (processManager, log, logs, isDevice, deviceName);
|
||||
}
|
||||
|
||||
public interface ICrashSnapshotReporter {
|
||||
|
@ -40,8 +36,6 @@ namespace Xharness
|
|||
readonly IProcessManager processManager;
|
||||
readonly ILog log;
|
||||
readonly ILogs logs;
|
||||
readonly string xcodeRoot;
|
||||
readonly string mlaunchPath;
|
||||
readonly bool isDevice;
|
||||
readonly string deviceName;
|
||||
readonly Func<string> tempFileProvider;
|
||||
|
@ -52,8 +46,6 @@ namespace Xharness
|
|||
public CrashSnapshotReporter (IProcessManager processManager,
|
||||
ILog log,
|
||||
ILogs logs,
|
||||
string xcodeRoot,
|
||||
string mlaunchPath,
|
||||
bool isDevice,
|
||||
string deviceName,
|
||||
Func<string> tempFileProvider = null)
|
||||
|
@ -61,15 +53,13 @@ namespace Xharness
|
|||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
this.log = log ?? throw new ArgumentNullException (nameof (log));
|
||||
this.logs = logs ?? throw new ArgumentNullException (nameof (logs));
|
||||
this.xcodeRoot = xcodeRoot ?? throw new ArgumentNullException (nameof (xcodeRoot));
|
||||
this.mlaunchPath = mlaunchPath ?? throw new ArgumentNullException (nameof (mlaunchPath));
|
||||
this.isDevice = isDevice;
|
||||
this.deviceName = deviceName;
|
||||
this.tempFileProvider = tempFileProvider ?? Path.GetTempFileName;
|
||||
|
||||
symbolicateCrashPath = Path.Combine (xcodeRoot, "Contents", "SharedFrameworks", "DTDeviceKitBase.framework", "Versions", "A", "Resources", "symbolicatecrash");
|
||||
symbolicateCrashPath = Path.Combine (processManager.XcodeRoot, "Contents", "SharedFrameworks", "DTDeviceKitBase.framework", "Versions", "A", "Resources", "symbolicatecrash");
|
||||
if (!File.Exists (symbolicateCrashPath))
|
||||
symbolicateCrashPath = Path.Combine (xcodeRoot, "Contents", "SharedFrameworks", "DVTFoundation.framework", "Versions", "A", "Resources", "symbolicatecrash");
|
||||
symbolicateCrashPath = Path.Combine (processManager.XcodeRoot, "Contents", "SharedFrameworks", "DVTFoundation.framework", "Versions", "A", "Resources", "symbolicatecrash");
|
||||
if (!File.Exists (symbolicateCrashPath))
|
||||
symbolicateCrashPath = null;
|
||||
}
|
||||
|
@ -135,14 +125,13 @@ namespace Xharness
|
|||
var crashReportFile = logs.Create (name, $"Crash report: {name}", timestamp: false);
|
||||
var args = new MlaunchArguments (
|
||||
new DownloadCrashReportArgument (crashFile),
|
||||
new DownloadCrashReportToArgument (crashReportFile.FullPath),
|
||||
new SdkRootArgument (xcodeRoot));
|
||||
new DownloadCrashReportToArgument (crashReportFile.FullPath));
|
||||
|
||||
if (!string.IsNullOrEmpty (deviceName)) {
|
||||
args.Add (new DeviceNameArgument(deviceName));
|
||||
}
|
||||
|
||||
var result = await processManager.ExecuteCommandAsync (mlaunchPath, args, log, TimeSpan.FromMinutes (1));
|
||||
var result = await processManager.ExecuteCommandAsync (args, log, TimeSpan.FromMinutes (1));
|
||||
|
||||
if (result.Succeeded) {
|
||||
log.WriteLine ("Downloaded crash report {0} to {1}", crashFile, crashReportFile.FullPath);
|
||||
|
@ -162,7 +151,7 @@ namespace Xharness
|
|||
|
||||
var name = Path.GetFileName (report.FullPath);
|
||||
var symbolicated = logs.Create (Path.ChangeExtension (name, ".symbolicated.log"), $"Symbolicated crash report: {name}", timestamp: false);
|
||||
var environment = new Dictionary<string, string> { { "DEVELOPER_DIR", Path.Combine (xcodeRoot, "Contents", "Developer") } };
|
||||
var environment = new Dictionary<string, string> { { "DEVELOPER_DIR", Path.Combine (processManager.XcodeRoot, "Contents", "Developer") } };
|
||||
var result = await processManager.ExecuteCommandAsync (symbolicateCrashPath, new [] { report.FullPath }, symbolicated, TimeSpan.FromMinutes (1), environment);
|
||||
if (result.Succeeded) {
|
||||
log.WriteLine ("Symbolicated {0} successfully.", report.FullPath);
|
||||
|
@ -184,15 +173,13 @@ namespace Xharness
|
|||
} else {
|
||||
var tempFile = tempFileProvider ();
|
||||
try {
|
||||
var args = new MlaunchArguments (
|
||||
new ListCrashReportsArgument (tempFile),
|
||||
new SdkRootArgument (xcodeRoot));
|
||||
var args = new MlaunchArguments (new ListCrashReportsArgument (tempFile));
|
||||
|
||||
if (!string.IsNullOrEmpty (deviceName)) {
|
||||
args.Add (new DeviceNameArgument(deviceName));
|
||||
}
|
||||
|
||||
var result = await processManager.ExecuteCommandAsync (mlaunchPath, args, log, TimeSpan.FromMinutes (1));
|
||||
var result = await processManager.ExecuteCommandAsync (args, log, TimeSpan.FromMinutes (1));
|
||||
if (result.Succeeded)
|
||||
crashes.UnionWith (File.ReadAllLines (tempFile));
|
||||
} finally {
|
||||
|
|
|
@ -14,19 +14,15 @@ namespace Xharness
|
|||
|
||||
public class DeviceLogCapturerFactory : IDeviceLogCapturerFactory {
|
||||
readonly IProcessManager processManager;
|
||||
readonly string xcodeRoot;
|
||||
readonly string mlaunchPath;
|
||||
|
||||
public DeviceLogCapturerFactory (IProcessManager processManager, string xcodeRoot, string mlaunchPath)
|
||||
public DeviceLogCapturerFactory (IProcessManager processManager)
|
||||
{
|
||||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
this.xcodeRoot = xcodeRoot ?? throw new ArgumentNullException (nameof (xcodeRoot));
|
||||
this.mlaunchPath = mlaunchPath ?? throw new ArgumentNullException (nameof (mlaunchPath));
|
||||
}
|
||||
|
||||
public IDeviceLogCapturer Create (ILog mainLog, ILog deviceLog, string deviceName)
|
||||
{
|
||||
return new DeviceLogCapturer (processManager, mainLog, deviceLog, deviceName, xcodeRoot, mlaunchPath);
|
||||
return new DeviceLogCapturer (processManager, mainLog, deviceLog, deviceName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,17 +36,13 @@ namespace Xharness
|
|||
readonly ILog mainLog;
|
||||
readonly ILog deviceLog;
|
||||
readonly string deviceName;
|
||||
readonly string xcodeRoot;
|
||||
readonly string mlaunchPath;
|
||||
|
||||
public DeviceLogCapturer (IProcessManager processManager, ILog mainLog, ILog deviceLog, string deviceName, string xcodeRoot, string mlaunchPath)
|
||||
public DeviceLogCapturer (IProcessManager processManager, ILog mainLog, ILog deviceLog, string deviceName)
|
||||
{
|
||||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
this.mainLog = mainLog ?? throw new ArgumentNullException (nameof (mainLog));
|
||||
this.deviceLog = deviceLog ?? throw new ArgumentNullException (nameof (deviceLog));
|
||||
this.deviceName = deviceName ?? throw new ArgumentNullException (nameof (deviceName));
|
||||
this.xcodeRoot = xcodeRoot ?? throw new ArgumentNullException (nameof (xcodeRoot));
|
||||
this.mlaunchPath = mlaunchPath ?? throw new ArgumentNullException (nameof (mlaunchPath));
|
||||
}
|
||||
|
||||
Process process;
|
||||
|
@ -60,17 +52,17 @@ namespace Xharness
|
|||
{
|
||||
streamEnds = new CountdownEvent (2);
|
||||
|
||||
var sb = new List<string> {
|
||||
var args = new List<string> {
|
||||
"--logdev",
|
||||
"--sdkroot",
|
||||
xcodeRoot,
|
||||
processManager.XcodeRoot,
|
||||
"--devname",
|
||||
deviceName
|
||||
};
|
||||
|
||||
process = new Process ();
|
||||
process.StartInfo.FileName = mlaunchPath;
|
||||
process.StartInfo.Arguments = StringUtils.FormatArguments (sb);
|
||||
process.StartInfo.FileName = processManager.MlaunchPath;
|
||||
process.StartInfo.Arguments = StringUtils.FormatArguments (args);
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.RedirectStandardError = true;
|
||||
|
|
|
@ -17,15 +17,17 @@ namespace Xharness.Execution {
|
|||
|
||||
// interface that helps to manage the different processes in the app.
|
||||
public interface IProcessManager {
|
||||
string XcodeRoot { get; }
|
||||
string MlaunchPath { get; }
|
||||
Version XcodeVersion { get; }
|
||||
|
||||
Task<ProcessExecutionResult> ExecuteCommandAsync (string filename, IList<string> args, ILog log, TimeSpan timeout, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null);
|
||||
Task<ProcessExecutionResult> ExecuteCommandAsync (string filename, MlaunchArguments args, ILog log, TimeSpan timeout, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null);
|
||||
Task<ProcessExecutionResult> RunAsync (Process process, ILog log, CancellationToken? cancellationToken = null, bool? diagnostics = null);
|
||||
Task<ProcessExecutionResult> ExecuteCommandAsync (MlaunchArguments args, ILog log, TimeSpan timeout, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null);
|
||||
Task<ProcessExecutionResult> ExecuteXcodeCommandAsync (string executable, IList<string> args, ILog log, TimeSpan timeout);
|
||||
Task<ProcessExecutionResult> RunAsync (Process process, ILog log, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null, bool? diagnostics = null);
|
||||
Task<ProcessExecutionResult> RunAsync (Process process, MlaunchArguments args, ILog log, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null, bool? diagnostics = null);
|
||||
Task<ProcessExecutionResult> RunAsync (Process process, ILog log, ILog stdoutLog, ILog stderrLog, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null, bool? diagnostics = null);
|
||||
Task<bool> WaitForExitAsync (Process process, TimeSpan? timeout = null);
|
||||
Task KillTreeAsync (Process process, ILog log, bool? diagnostics = true);
|
||||
Task KillTreeAsync (int pid, ILog log, bool? diagnostics = true);
|
||||
void GetChildrenPS (ILog log, List<int> list, int pid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,84 +7,101 @@ using System.Runtime.InteropServices;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Xharness.Execution.Mlaunch;
|
||||
using Xharness.Logging;
|
||||
using Xharness.Utilities;
|
||||
|
||||
namespace Xharness.Execution {
|
||||
public class ProcessManager : IProcessManager {
|
||||
public ProcessManager ()
|
||||
public string XcodeRoot { get; }
|
||||
public string MlaunchPath { get; }
|
||||
|
||||
Version xcode_version;
|
||||
public Version XcodeVersion {
|
||||
get {
|
||||
if (xcode_version == null) {
|
||||
var doc = new XmlDocument ();
|
||||
doc.Load (Path.Combine (XcodeRoot, "Contents", "version.plist"));
|
||||
xcode_version = Version.Parse (doc.SelectSingleNode ("//key[text() = 'CFBundleShortVersionString']/following-sibling::string").InnerText);
|
||||
}
|
||||
return xcode_version;
|
||||
}
|
||||
}
|
||||
|
||||
public ProcessManager (string xcodeRoot, string mlaunchPath)
|
||||
{
|
||||
XcodeRoot = xcodeRoot ?? throw new ArgumentNullException (nameof (xcodeRoot));
|
||||
MlaunchPath = mlaunchPath ?? throw new ArgumentNullException (nameof (mlaunchPath));
|
||||
}
|
||||
|
||||
public async Task<ProcessExecutionResult> ExecuteCommandAsync (string filename,
|
||||
IList<string> args,
|
||||
ILog log,
|
||||
TimeSpan timeout,
|
||||
Dictionary<string, string> environment_variables = null,
|
||||
CancellationToken? cancellation_token = null)
|
||||
Dictionary<string, string> environmentVariables = null,
|
||||
CancellationToken? cancellationToken = null)
|
||||
{
|
||||
using (var p = new Process ()) {
|
||||
p.StartInfo.FileName = filename;
|
||||
using var p = new Process ();
|
||||
p.StartInfo.FileName = filename ?? throw new ArgumentNullException (nameof (filename));
|
||||
p.StartInfo.Arguments = StringUtils.FormatArguments (args);
|
||||
return await RunAsync (p, log, timeout, environment_variables, cancellation_token);
|
||||
}
|
||||
return await RunAsync (p, log, timeout, environmentVariables, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<ProcessExecutionResult> ExecuteCommandAsync (string filename,
|
||||
MlaunchArguments args,
|
||||
public async Task<ProcessExecutionResult> ExecuteCommandAsync (MlaunchArguments args,
|
||||
ILog log,
|
||||
TimeSpan timeout,
|
||||
Dictionary<string, string> environment_variables = null,
|
||||
CancellationToken? cancellation_token = null)
|
||||
Dictionary<string, string> environmentVariables = null,
|
||||
CancellationToken? cancellationToken = null)
|
||||
{
|
||||
using (var p = new Process ()) {
|
||||
p.StartInfo.FileName = filename;
|
||||
p.StartInfo.Arguments = args.AsCommandLine ();
|
||||
return await RunAsync (p, log, timeout, environment_variables, cancellation_token);
|
||||
using var p = new Process ();
|
||||
return await RunAsync (p, args, log, timeout, environmentVariables, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<ProcessExecutionResult> ExecuteXcodeCommandAsync (string executable, IList<string> args, ILog log, TimeSpan timeout)
|
||||
{
|
||||
string filename = Path.Combine (XcodeRoot, "Contents", "Developer", "usr", "bin", executable);
|
||||
return ExecuteCommandAsync (filename, args, log, timeout: timeout);
|
||||
}
|
||||
|
||||
[DllImport ("/usr/lib/libc.dylib")]
|
||||
internal static extern int kill (int pid, int sig);
|
||||
|
||||
public static Task<bool> PollForExitAsync (int pid, TimeSpan timeout)
|
||||
public Task<ProcessExecutionResult> RunAsync (Process process,
|
||||
ILog log,
|
||||
TimeSpan? timeout = null,
|
||||
Dictionary<string, string> environment_variables = null,
|
||||
CancellationToken? cancellationToken = null,
|
||||
bool? diagnostics = null)
|
||||
{
|
||||
var rv = new TaskCompletionSource<bool> ();
|
||||
var watch = new Stopwatch ();
|
||||
watch.Start ();
|
||||
Task.Run (async () => {
|
||||
while (watch.ElapsedMilliseconds < timeout.TotalMilliseconds) {
|
||||
if (kill (pid, 0) != 0) {
|
||||
// pid is not valid anymore, program exited
|
||||
rv.SetResult (true);
|
||||
return;
|
||||
}
|
||||
await Task.Delay (TimeSpan.FromMilliseconds (100));
|
||||
return RunAsync (process, log, log, log, timeout, environment_variables, cancellationToken, diagnostics);
|
||||
}
|
||||
|
||||
rv.SetResult (false);
|
||||
});
|
||||
return rv.Task;
|
||||
}
|
||||
|
||||
public async Task<ProcessExecutionResult> RunAsync (Process process, ILog log, CancellationToken? cancellation_token = null, bool? diagnostics = null)
|
||||
public Task<ProcessExecutionResult> RunAsync (Process process,
|
||||
MlaunchArguments args,
|
||||
ILog log,
|
||||
TimeSpan? timeout = null,
|
||||
Dictionary<string, string> environmentVariables = null,
|
||||
CancellationToken? cancellationToken = null,
|
||||
bool? diagnostics = null)
|
||||
{
|
||||
return await RunAsync (process, log, log, log, cancellation_token: cancellation_token, diagnostics: diagnostics);
|
||||
}
|
||||
if (!args.Any (a => a is SdkRootArgument))
|
||||
args.Prepend (new SdkRootArgument (XcodeRoot));
|
||||
|
||||
public Task<ProcessExecutionResult> RunAsync (Process process, ILog log, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null, bool? diagnostics = null)
|
||||
{
|
||||
return RunAsync (process, log, log, log, timeout, environment_variables, cancellation_token, diagnostics);
|
||||
}
|
||||
|
||||
public Task<ProcessExecutionResult> RunAsync (Process process, MlaunchArguments args, ILog log, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null, bool? diagnostics = null)
|
||||
{
|
||||
process.StartInfo.FileName = MlaunchPath;
|
||||
process.StartInfo.Arguments = args.AsCommandLine ();
|
||||
return RunAsync (process, log, timeout, environment_variables, cancellation_token, diagnostics);
|
||||
|
||||
return RunAsync (process, log, timeout, environmentVariables, cancellationToken, diagnostics);
|
||||
}
|
||||
|
||||
public async Task<ProcessExecutionResult> RunAsync (Process process, ILog log, ILog StdoutStream, ILog StderrStream, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null, bool? diagnostics = null)
|
||||
public async Task<ProcessExecutionResult> RunAsync (Process process,
|
||||
ILog log,
|
||||
ILog stdout,
|
||||
ILog stderr,
|
||||
TimeSpan? timeout = null,
|
||||
Dictionary<string, string> environment_variables = null,
|
||||
CancellationToken? cancellationToken = null,
|
||||
bool? diagnostics = null)
|
||||
{
|
||||
var stdout_completion = new TaskCompletionSource<bool> ();
|
||||
var stderr_completion = new TaskCompletionSource<bool> ();
|
||||
|
@ -105,9 +122,9 @@ namespace Xharness.Execution {
|
|||
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
|
||||
{
|
||||
if (e.Data != null) {
|
||||
lock (StdoutStream) {
|
||||
StdoutStream.WriteLine (e.Data);
|
||||
StdoutStream.Flush ();
|
||||
lock (stdout) {
|
||||
stdout.WriteLine (e.Data);
|
||||
stdout.Flush ();
|
||||
}
|
||||
} else {
|
||||
stdout_completion.TrySetResult (true);
|
||||
|
@ -117,9 +134,9 @@ namespace Xharness.Execution {
|
|||
process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
|
||||
{
|
||||
if (e.Data != null) {
|
||||
lock (StderrStream) {
|
||||
StderrStream.WriteLine (e.Data);
|
||||
StderrStream.Flush ();
|
||||
lock (stderr) {
|
||||
stderr.WriteLine (e.Data);
|
||||
stderr.Flush ();
|
||||
}
|
||||
} else {
|
||||
stderr_completion.TrySetResult (true);
|
||||
|
@ -148,7 +165,7 @@ namespace Xharness.Execution {
|
|||
process.BeginErrorReadLine ();
|
||||
process.BeginOutputReadLine ();
|
||||
|
||||
cancellation_token?.Register (() => {
|
||||
cancellationToken?.Register (() => {
|
||||
var hasExited = false;
|
||||
try {
|
||||
hasExited = process.HasExited;
|
||||
|
@ -159,7 +176,7 @@ namespace Xharness.Execution {
|
|||
// processes behind).
|
||||
}
|
||||
if (!hasExited) {
|
||||
StderrStream.WriteLine ($"Execution of {pid} was cancelled.");
|
||||
stderr.WriteLine ($"Execution of {pid} was cancelled.");
|
||||
kill (pid, 9);
|
||||
}
|
||||
});
|
||||
|
@ -168,7 +185,7 @@ namespace Xharness.Execution {
|
|||
if (!await WaitForExitAsync (process, timeout.Value)) {
|
||||
await KillTreeAsync (process, log, diagnostics ?? true);
|
||||
rv.TimedOut = true;
|
||||
lock (StderrStream)
|
||||
lock (stderr)
|
||||
log.WriteLine ($"{pid} Execution timed out after {timeout.Value.TotalSeconds} seconds and the process was killed.");
|
||||
}
|
||||
}
|
||||
|
@ -184,38 +201,6 @@ namespace Xharness.Execution {
|
|||
return rv;
|
||||
}
|
||||
|
||||
public async Task<bool> WaitForExitAsync (Process process, TimeSpan? timeout = null)
|
||||
{
|
||||
if (process.HasExited)
|
||||
return true;
|
||||
|
||||
var tcs = new TaskCompletionSource<bool> ();
|
||||
|
||||
void ProcessExited (object sender, EventArgs ea)
|
||||
{
|
||||
process.Exited -= ProcessExited;
|
||||
tcs.TrySetResult (true);
|
||||
}
|
||||
|
||||
process.Exited += ProcessExited;
|
||||
process.EnableRaisingEvents = true;
|
||||
|
||||
// Check if process exited again, in case it exited after we checked
|
||||
// the last time, but before we attached the event handler.
|
||||
if (process.HasExited) {
|
||||
process.Exited -= ProcessExited;
|
||||
tcs.TrySetResult (true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (timeout.HasValue) {
|
||||
return await tcs.Task.TimeoutAfter (timeout.Value);
|
||||
} else {
|
||||
await tcs.Task;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public Task KillTreeAsync (Process process, ILog log, bool? diagnostics = true)
|
||||
{
|
||||
return KillTreeAsync (process.Id, log, diagnostics);
|
||||
|
@ -223,8 +208,8 @@ namespace Xharness.Execution {
|
|||
|
||||
public async Task KillTreeAsync (int pid, ILog log, bool? diagnostics = true)
|
||||
{
|
||||
var pids = new List<int> ();
|
||||
GetChildrenPS (log, pids, pid);
|
||||
var pids = GetChildrenPS (log, pid);
|
||||
|
||||
if (diagnostics == true) {
|
||||
log.WriteLine ($"Pids to kill: {string.Join (", ", pids.Select ((v) => v.ToString ()).ToArray ())}");
|
||||
using (var ps = new Process ()) {
|
||||
|
@ -271,9 +256,41 @@ namespace Xharness.Execution {
|
|||
kill (pids [i], 9);
|
||||
}
|
||||
|
||||
public void GetChildrenPS (ILog log, List<int> list, int pid)
|
||||
static async Task<bool> WaitForExitAsync (Process process, TimeSpan? timeout = null)
|
||||
{
|
||||
string stdout;
|
||||
if (process.HasExited)
|
||||
return true;
|
||||
|
||||
var tcs = new TaskCompletionSource<bool> ();
|
||||
|
||||
void ProcessExited (object sender, EventArgs ea)
|
||||
{
|
||||
process.Exited -= ProcessExited;
|
||||
tcs.TrySetResult (true);
|
||||
}
|
||||
|
||||
process.Exited += ProcessExited;
|
||||
process.EnableRaisingEvents = true;
|
||||
|
||||
// Check if process exited again, in case it exited after we checked
|
||||
// the last time, but before we attached the event handler.
|
||||
if (process.HasExited) {
|
||||
process.Exited -= ProcessExited;
|
||||
tcs.TrySetResult (true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (timeout.HasValue) {
|
||||
return await tcs.Task.TimeoutAfter (timeout.Value);
|
||||
} else {
|
||||
await tcs.Task;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static List<int> GetChildrenPS (ILog log, int pid)
|
||||
{
|
||||
var list = new List<int> ();
|
||||
|
||||
using (Process ps = new Process ()) {
|
||||
ps.StartInfo.FileName = "ps";
|
||||
|
@ -281,20 +298,21 @@ namespace Xharness.Execution {
|
|||
ps.StartInfo.UseShellExecute = false;
|
||||
ps.StartInfo.RedirectStandardOutput = true;
|
||||
ps.Start ();
|
||||
stdout = ps.StandardOutput.ReadToEnd ();
|
||||
|
||||
string stdout = ps.StandardOutput.ReadToEnd ();
|
||||
|
||||
if (!ps.WaitForExit (1000)) {
|
||||
log.WriteLine ("ps didn't finish in a reasonable amount of time (1 second).");
|
||||
return;
|
||||
return list;
|
||||
}
|
||||
|
||||
if (ps.ExitCode != 0)
|
||||
return;
|
||||
return list;
|
||||
|
||||
stdout = stdout.Trim ();
|
||||
|
||||
if (string.IsNullOrEmpty (stdout))
|
||||
return;
|
||||
return list;
|
||||
|
||||
var dict = new Dictionary<int, List<int>> ();
|
||||
foreach (string line in stdout.Split (new char [] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)) {
|
||||
|
@ -305,12 +323,11 @@ namespace Xharness.Execution {
|
|||
|
||||
var parent = l.Substring (0, space);
|
||||
var process = l.Substring (space + 1);
|
||||
int parent_id, process_id;
|
||||
|
||||
if (int.TryParse (parent, out parent_id) && int.TryParse (process, out process_id)) {
|
||||
List<int> children;
|
||||
if (!dict.TryGetValue (parent_id, out children))
|
||||
if (int.TryParse (parent, out var parent_id) && int.TryParse (process, out var process_id)) {
|
||||
if (!dict.TryGetValue (parent_id, out var children))
|
||||
dict [parent_id] = children = new List<int> ();
|
||||
|
||||
children.Add (process_id);
|
||||
}
|
||||
}
|
||||
|
@ -319,15 +336,16 @@ namespace Xharness.Execution {
|
|||
queue.Enqueue (pid);
|
||||
|
||||
do {
|
||||
List<int> children;
|
||||
var parent_id = queue.Dequeue ();
|
||||
list.Add (parent_id);
|
||||
if (dict.TryGetValue (parent_id, out children)) {
|
||||
if (dict.TryGetValue (parent_id, out var children)) {
|
||||
foreach (var child in children)
|
||||
queue.Enqueue (child);
|
||||
}
|
||||
} while (queue.Count > 0);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@ using System.Linq;
|
|||
using System.Net;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
using Xamarin;
|
||||
using Xharness.Execution;
|
||||
using Xharness.Logging;
|
||||
|
||||
|
@ -15,7 +13,6 @@ namespace Xharness
|
|||
{
|
||||
public static class GitHub
|
||||
{
|
||||
static IProcessManager ProcessManager { get; set; } = new ProcessManager ();
|
||||
static WebClient CreateClient ()
|
||||
{
|
||||
var client = new WebClient ();
|
||||
|
@ -56,11 +53,11 @@ namespace Xharness
|
|||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetModifiedFiles (Harness harness, int pull_request)
|
||||
public static IEnumerable<string> GetModifiedFiles (IProcessManager processManager, Harness harness, int pull_request)
|
||||
{
|
||||
var path = Path.Combine (harness.LogDirectory, "pr" + pull_request + "-files.log");
|
||||
if (!File.Exists (path)) {
|
||||
var rv = GetModifiedFilesLocally (harness, pull_request);
|
||||
var rv = GetModifiedFilesLocally (processManager, harness, pull_request);
|
||||
if (rv == null || rv.Count () == 0) {
|
||||
rv = GetModifiedFilesRemotely (harness, pull_request);
|
||||
if (rv == null)
|
||||
|
@ -141,7 +138,7 @@ namespace Xharness
|
|||
return File.ReadAllLines (path);
|
||||
}
|
||||
|
||||
static IEnumerable<string> GetModifiedFilesLocally (Harness harness, int pull_request)
|
||||
static IEnumerable<string> GetModifiedFilesLocally (IProcessManager processManager, Harness harness, int pull_request)
|
||||
{
|
||||
var base_commit = $"origin/pr/{pull_request}/merge^";
|
||||
var head_commit = $"origin/pr/{pull_request}/merge";
|
||||
|
@ -155,7 +152,7 @@ namespace Xharness
|
|||
git.StartInfo.FileName = "git";
|
||||
git.StartInfo.Arguments = $"diff-tree --no-commit-id --name-only -r {base_commit}..{head_commit}";
|
||||
var output = new MemoryLog ();
|
||||
var rv = ProcessManager.RunAsync (git, harness.HarnessLog, output, output).Result;
|
||||
var rv = processManager.RunAsync (git, harness.HarnessLog, stdoutLog: output, stderrLog: output).Result;
|
||||
if (rv.Succeeded)
|
||||
return output.ToString ().Split (new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Xml;
|
||||
using Xharness.Collections;
|
||||
using Xharness.Execution;
|
||||
|
@ -18,24 +19,20 @@ namespace Xharness.Hardware {
|
|||
}
|
||||
|
||||
public class DeviceLoaderFactory : IDeviceLoaderFactory {
|
||||
readonly IHarness harness;
|
||||
readonly IProcessManager processManager;
|
||||
|
||||
public DeviceLoaderFactory (IHarness harness, IProcessManager processManager)
|
||||
public DeviceLoaderFactory (IProcessManager processManager)
|
||||
{
|
||||
this.harness = harness ?? throw new ArgumentNullException (nameof (harness));
|
||||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
}
|
||||
|
||||
public IDeviceLoader CreateLoader () => new Devices (harness, processManager);
|
||||
public IDeviceLoader CreateLoader () => new Devices (processManager);
|
||||
}
|
||||
|
||||
public class Devices : IDeviceLoader {
|
||||
readonly IProcessManager processManager;
|
||||
bool loaded;
|
||||
|
||||
public IHarness Harness { get; set; }
|
||||
|
||||
BlockingEnumerableCollection<IHardwareDevice> connected_devices = new BlockingEnumerableCollection<IHardwareDevice> ();
|
||||
|
||||
public IEnumerable<IHardwareDevice> ConnectedDevices => connected_devices;
|
||||
|
@ -51,9 +48,8 @@ namespace Xharness.Hardware {
|
|||
}
|
||||
}
|
||||
|
||||
public Devices (IHarness harness, IProcessManager processManager)
|
||||
public Devices (IProcessManager processManager)
|
||||
{
|
||||
Harness = harness ?? throw new ArgumentNullException (nameof (harness));
|
||||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
}
|
||||
|
||||
|
@ -76,18 +72,19 @@ namespace Xharness.Hardware {
|
|||
var tmpfile = Path.GetTempFileName ();
|
||||
try {
|
||||
using (var process = new Process ()) {
|
||||
process.StartInfo.FileName = Harness.MlaunchPath;
|
||||
var arguments = new MlaunchArguments (
|
||||
new SdkRootArgument (Harness.XcodeRoot),
|
||||
new ListDevicesArgument (tmpfile),
|
||||
new XmlOutputFormatArgument ());
|
||||
|
||||
if (extra_data)
|
||||
arguments.Add (new ListExtraDataArgument ());
|
||||
|
||||
var task = processManager.ExecuteCommandAsync (arguments, log, timeout: TimeSpan.FromSeconds (120));
|
||||
log.WriteLine ("Launching {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
|
||||
var rv = await processManager.RunAsync (process, arguments, log, timeout: TimeSpan.FromSeconds (120));
|
||||
if (!rv.Succeeded)
|
||||
|
||||
var result = await task;
|
||||
|
||||
if (!result.Succeeded)
|
||||
throw new Exception ("Failed to list devices.");
|
||||
log.WriteLine ("Result:");
|
||||
log.WriteLine (File.ReadAllText (tmpfile));
|
||||
|
|
|
@ -33,7 +33,6 @@ namespace Xharness.Hardware {
|
|||
}
|
||||
|
||||
public interface ISimulatorDevice : IDevice {
|
||||
ITCCDatabase TCCDatabase { get; set; }
|
||||
string SimRuntime { get; set; }
|
||||
string SimDeviceType { get; set; }
|
||||
string DataPath { get; set; }
|
||||
|
|
|
@ -9,10 +9,8 @@ using Xharness.Logging;
|
|||
namespace Xharness.Hardware {
|
||||
|
||||
public class SimulatorDevice : ISimulatorDevice {
|
||||
readonly IHarness harness;
|
||||
readonly IProcessManager processManager;
|
||||
|
||||
public ITCCDatabase TCCDatabase { get; set; } = new TCCDatabase ();
|
||||
readonly ITCCDatabase tCCDatabase;
|
||||
|
||||
public string UDID { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
@ -23,10 +21,10 @@ namespace Xharness.Hardware {
|
|||
public string SystemLog => Path.Combine (LogPath, "system.log");
|
||||
|
||||
|
||||
public SimulatorDevice (IHarness harness, IProcessManager processManager)
|
||||
public SimulatorDevice (IProcessManager processManager, ITCCDatabase tccDatabase)
|
||||
{
|
||||
this.harness = harness ?? throw new ArgumentNullException (nameof (harness));
|
||||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
this.tCCDatabase = tccDatabase ?? throw new ArgumentNullException (nameof (tccDatabase));
|
||||
}
|
||||
|
||||
public bool IsWatchSimulator => SimRuntime.StartsWith ("com.apple.CoreSimulator.SimRuntime.watchOS", StringComparison.Ordinal);
|
||||
|
@ -43,17 +41,17 @@ namespace Xharness.Hardware {
|
|||
{
|
||||
// here we don't care if execution fails.
|
||||
// erase the simulator (make sure the device isn't running first)
|
||||
await harness.ExecuteXcodeCommandAsync ("simctl", new [] { "shutdown", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
await harness.ExecuteXcodeCommandAsync ("simctl", new [] { "erase", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
await processManager.ExecuteXcodeCommandAsync ("simctl", new [] { "shutdown", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
await processManager.ExecuteXcodeCommandAsync ("simctl", new [] { "erase", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
|
||||
// boot & shutdown to make sure it actually works
|
||||
await harness.ExecuteXcodeCommandAsync ("simctl", new [] { "boot", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
await harness.ExecuteXcodeCommandAsync ("simctl", new [] { "shutdown", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
await processManager.ExecuteXcodeCommandAsync ("simctl", new [] { "boot", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
await processManager.ExecuteXcodeCommandAsync ("simctl", new [] { "shutdown", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
}
|
||||
|
||||
public async Task ShutdownAsync (ILog log)
|
||||
{
|
||||
await harness.ExecuteXcodeCommandAsync ("simctl", new [] { "shutdown", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
await processManager.ExecuteXcodeCommandAsync ("simctl", new [] { "shutdown", UDID }, log, TimeSpan.FromMinutes (1));
|
||||
}
|
||||
|
||||
public async Task KillEverythingAsync (ILog log)
|
||||
|
@ -86,12 +84,12 @@ namespace Xharness.Hardware {
|
|||
{
|
||||
string simulator_app;
|
||||
|
||||
if (IsWatchSimulator && harness.XcodeVersion.Major < 9) {
|
||||
simulator_app = Path.Combine (harness.XcodeRoot, "Contents", "Developer", "Applications", "Simulator (Watch).app");
|
||||
if (IsWatchSimulator && processManager.XcodeVersion.Major < 9) {
|
||||
simulator_app = Path.Combine (processManager.XcodeRoot, "Contents", "Developer", "Applications", "Simulator (Watch).app");
|
||||
} else {
|
||||
simulator_app = Path.Combine (harness.XcodeRoot, "Contents", "Developer", "Applications", "Simulator.app");
|
||||
simulator_app = Path.Combine (processManager.XcodeRoot, "Contents", "Developer", "Applications", "Simulator.app");
|
||||
if (!Directory.Exists (simulator_app))
|
||||
simulator_app = Path.Combine (harness.XcodeRoot, "Contents", "Developer", "Applications", "iOS Simulator.app");
|
||||
simulator_app = Path.Combine (processManager.XcodeRoot, "Contents", "Developer", "Applications", "iOS Simulator.app");
|
||||
}
|
||||
|
||||
await processManager.ExecuteCommandAsync ("open", new [] { "-a", simulator_app, "--args", "-CurrentDeviceUDID", UDID }, log, TimeSpan.FromSeconds (15));
|
||||
|
@ -121,7 +119,7 @@ namespace Xharness.Hardware {
|
|||
}
|
||||
|
||||
if (File.Exists (TCC_db)) {
|
||||
await TCCDatabase.AgreeToPromptsAsync (SimRuntime, TCC_db, log, bundle_identifiers);
|
||||
await tCCDatabase.AgreeToPromptsAsync (SimRuntime, TCC_db, log, bundle_identifiers);
|
||||
} else {
|
||||
log.WriteLine ("No TCC.db found for the simulator {0} (SimRuntime={1} and SimDeviceType={1})", UDID, SimRuntime, SimDeviceType);
|
||||
}
|
||||
|
|
|
@ -22,16 +22,14 @@ namespace Xharness.Hardware {
|
|||
}
|
||||
|
||||
public class SimulatorsLoaderFactory : ISimulatorsLoaderFactory {
|
||||
readonly IHarness harness;
|
||||
readonly IProcessManager processManager;
|
||||
|
||||
public SimulatorsLoaderFactory (IHarness harness, IProcessManager processManager)
|
||||
public SimulatorsLoaderFactory (IProcessManager processManager)
|
||||
{
|
||||
this.harness = harness ?? throw new ArgumentNullException (nameof (harness));
|
||||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
}
|
||||
|
||||
public ISimulatorsLoader CreateLoader () => new Simulators (harness, processManager);
|
||||
public ISimulatorsLoader CreateLoader () => new Simulators (processManager);
|
||||
}
|
||||
|
||||
public class Simulators : ISimulatorsLoader {
|
||||
|
@ -44,16 +42,13 @@ namespace Xharness.Hardware {
|
|||
|
||||
bool loaded;
|
||||
|
||||
public IHarness Harness { get; set; }
|
||||
|
||||
public IEnumerable<SimRuntime> SupportedRuntimes => supported_runtimes;
|
||||
public IEnumerable<SimDeviceType> SupportedDeviceTypes => supported_device_types;
|
||||
public IEnumerable<SimulatorDevice> AvailableDevices => available_devices;
|
||||
public IEnumerable<SimDevicePair> AvailableDevicePairs => available_device_pairs;
|
||||
|
||||
public Simulators (IHarness harness, IProcessManager processManager)
|
||||
public Simulators (IProcessManager processManager)
|
||||
{
|
||||
Harness = harness ?? throw new ArgumentNullException (nameof (harness));
|
||||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
}
|
||||
|
||||
|
@ -76,18 +71,18 @@ namespace Xharness.Hardware {
|
|||
var tmpfile = Path.GetTempFileName ();
|
||||
try {
|
||||
using (var process = new Process ()) {
|
||||
process.StartInfo.FileName = Harness.MlaunchPath;
|
||||
var arguments = new MlaunchArguments (
|
||||
new SdkRootArgument(Harness.XcodeRoot),
|
||||
new ListSimulatorsArgument(tmpfile),
|
||||
new XmlOutputFormatArgument());
|
||||
|
||||
process.StartInfo.Arguments = arguments.AsCommandLine ();
|
||||
var task = processManager.ExecuteCommandAsync (arguments, log, timeout: TimeSpan.FromSeconds (30));
|
||||
log.WriteLine ("Launching {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
|
||||
var rv = await processManager.RunAsync (process, arguments, log, timeout: TimeSpan.FromSeconds (30));
|
||||
|
||||
if (!rv.Succeeded)
|
||||
var result = await task;
|
||||
|
||||
if (!result.Succeeded)
|
||||
throw new Exception ("Failed to list simulators.");
|
||||
|
||||
log.WriteLine ("Result:");
|
||||
log.WriteLine (File.ReadAllText (tmpfile));
|
||||
var simulator_data = new XmlDocument ();
|
||||
|
@ -112,7 +107,7 @@ namespace Xharness.Hardware {
|
|||
}
|
||||
|
||||
foreach (XmlNode sim in simulator_data.SelectNodes ("/MTouch/Simulator/AvailableDevices/SimDevice")) {
|
||||
available_devices.Add (new SimulatorDevice (Harness, processManager) {
|
||||
available_devices.Add (new SimulatorDevice (processManager, new TCCDatabase (processManager)) {
|
||||
Name = sim.Attributes ["Name"].Value,
|
||||
UDID = sim.Attributes ["UDID"].Value,
|
||||
SimRuntime = sim.SelectSingleNode ("SimRuntime").InnerText,
|
||||
|
@ -168,7 +163,7 @@ namespace Xharness.Hardware {
|
|||
return devices;
|
||||
}
|
||||
|
||||
var rv = await Harness.ExecuteXcodeCommandAsync ("simctl", new [] { "create", CreateName (devicetype, runtime), devicetype, runtime }, log, TimeSpan.FromMinutes (1));
|
||||
var rv = await processManager.ExecuteXcodeCommandAsync ("simctl", new [] { "create", CreateName (devicetype, runtime), devicetype, runtime }, log, TimeSpan.FromMinutes (1));
|
||||
if (!rv.Succeeded) {
|
||||
log.WriteLine ($"Could not create device for runtime={runtime} and device type={devicetype}.");
|
||||
return null;
|
||||
|
@ -207,8 +202,7 @@ namespace Xharness.Hardware {
|
|||
log.Write (value);
|
||||
capturedLog.Append (value);
|
||||
});
|
||||
|
||||
var rv = await Harness.ExecuteXcodeCommandAsync ("simctl", new [] { "pair", device.UDID, companion_device.UDID }, pairLog, TimeSpan.FromMinutes (1));
|
||||
var rv = await processManager.ExecuteXcodeCommandAsync ("simctl", new [] { "pair", device.UDID, companion_device.UDID }, pairLog, TimeSpan.FromMinutes (1));
|
||||
if (!rv.Succeeded) {
|
||||
if (!create_device) {
|
||||
var try_creating_device = false;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Xharness.Execution;
|
||||
using Xharness.Logging;
|
||||
|
@ -9,7 +8,6 @@ using Xharness.Logging;
|
|||
namespace Xharness.Hardware {
|
||||
|
||||
public interface ITCCDatabase {
|
||||
IProcessManager ProcessManager { get; set; }
|
||||
Task AgreeToPromptsAsync (string simRuntime, string dataPath, ILog log, params string [] bundle_identifiers);
|
||||
int GetTCCFormat (string simRuntime);
|
||||
}
|
||||
|
@ -19,7 +17,12 @@ namespace Xharness.Hardware {
|
|||
static readonly string tvOSSimRuntimePrefix = "com.apple.CoreSimulator.SimRuntime.tvOS-";
|
||||
static readonly string watchOSRuntimePrefix = "com.apple.CoreSimulator.SimRuntime.watchOS-";
|
||||
|
||||
public IProcessManager ProcessManager { get; set; } = new ProcessManager ();
|
||||
readonly IProcessManager processManager;
|
||||
|
||||
public TCCDatabase (IProcessManager processManager)
|
||||
{
|
||||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
}
|
||||
|
||||
public int GetTCCFormat (string simRuntime) {
|
||||
|
||||
|
@ -109,7 +112,7 @@ namespace Xharness.Hardware {
|
|||
}
|
||||
}
|
||||
args.Add (sql.ToString ());
|
||||
var rv = await ProcessManager.ExecuteCommandAsync ("sqlite3", args, log, TimeSpan.FromSeconds (5));
|
||||
var rv = await processManager.ExecuteCommandAsync ("sqlite3", args, log, TimeSpan.FromSeconds (5));
|
||||
if (!rv.Succeeded) {
|
||||
failure = true;
|
||||
break;
|
||||
|
@ -124,7 +127,7 @@ namespace Xharness.Hardware {
|
|||
}
|
||||
|
||||
log.WriteLine ("Current TCC database contents:");
|
||||
await ProcessManager.ExecuteCommandAsync ("sqlite3", new [] { TCCDb, ".dump" }, log, TimeSpan.FromSeconds (5));
|
||||
await processManager.ExecuteCommandAsync ("sqlite3", new [] { TCCDb, ".dump" }, log, TimeSpan.FromSeconds (5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Xharness.BCLTestImporter;
|
||||
using Xharness.Logging;
|
||||
|
@ -51,66 +50,30 @@ namespace Xharness
|
|||
|
||||
public interface IHarness {
|
||||
HarnessAction Action { get; }
|
||||
bool DisableWatchOSOnWrench { get; }
|
||||
string DOTNET { get; }
|
||||
bool DryRun { get; }
|
||||
bool ENABLE_XAMARIN { get; }
|
||||
Dictionary<string, string> EnvironmentVariables { get; }
|
||||
ILog HarnessLog { get; set; }
|
||||
string GetStandardErrorTty ();
|
||||
bool InCI { get; }
|
||||
bool INCLUDE_IOS { get; }
|
||||
bool INCLUDE_MAC { get; }
|
||||
bool INCLUDE_TVOS { get; }
|
||||
bool INCLUDE_WATCH { get; }
|
||||
bool? IncludeSystemPermissionTests { get; set; }
|
||||
string IOS_DESTDIR { get; }
|
||||
List<iOSTestProject> IOSTestProjects { get; }
|
||||
string JENKINS_RESULTS_DIRECTORY { get; }
|
||||
string JenkinsConfiguration { get; }
|
||||
HashSet<string> Labels { get; }
|
||||
double LaunchTimeout { get; }
|
||||
string LogDirectory { get; }
|
||||
string MAC_DESTDIR { get; }
|
||||
List<MacTestProject> MacTestProjects { get; }
|
||||
string MarkdownSummaryPath { get; }
|
||||
string MlaunchPath { get; }
|
||||
string MONO_IOS_SDK_DESTDIR { get; }
|
||||
string MONO_MAC_SDK_DESTDIR { get; }
|
||||
string MONO_PATH { get; }
|
||||
string PeriodicCommand { get; }
|
||||
string PeriodicCommandArguments { get; }
|
||||
TimeSpan PeriodicCommandInterval { get; }
|
||||
IProcessManager ProcessManager { get; }
|
||||
double Timeout { get; }
|
||||
string TodayContainerTemplate { get; }
|
||||
string TodayExtensionTemplate { get; }
|
||||
bool UseGroupedApps { get; }
|
||||
int Verbosity { get; }
|
||||
string WatchOSAppTemplate { get; }
|
||||
string WatchOSContainerTemplate { get; }
|
||||
string WatchOSExtensionTemplate { get; }
|
||||
string XcodeRoot { get; }
|
||||
Version XcodeVersion { get; }
|
||||
XmlResultJargon XmlJargon { get; }
|
||||
Task<ProcessExecutionResult> ExecuteXcodeCommandAsync (string executable, IList<string> args, ILog log, TimeSpan timeout);
|
||||
|
||||
bool GetIncludeSystemPermissionTests (TestPlatform platform, bool device);
|
||||
string GetStandardErrorTty ();
|
||||
void Log (int min_level, string message, params object [] args);
|
||||
void Log (string message);
|
||||
void Log (string message, params object [] args);
|
||||
void Save (StringWriter doc, string path);
|
||||
}
|
||||
|
||||
public class Harness : IHarness {
|
||||
readonly TestTarget target;
|
||||
readonly string buildConfiguration = "Debug";
|
||||
|
||||
IProcessManager processManager;
|
||||
|
||||
public HarnessAction Action { get; }
|
||||
public int Verbosity { get; }
|
||||
public ILog HarnessLog { get; set; }
|
||||
public HashSet<string> Labels { get; }
|
||||
public XmlResultJargon XmlJargon { get; }
|
||||
public IProcessManager ProcessManager { get; }
|
||||
public IResultParser ResultParser { get; }
|
||||
|
||||
// This is the maccore/tests directory.
|
||||
|
@ -150,6 +113,8 @@ namespace Xharness
|
|||
}
|
||||
}
|
||||
|
||||
string MlaunchPath => Path.Combine (IOS_DESTDIR, "Library", "Frameworks", "Xamarin.iOS.framework", "Versions", "Current", "bin", "mlaunch");
|
||||
|
||||
public List<iOSTestProject> IOSTestProjects { get; }
|
||||
public List<MacTestProject> MacTestProjects { get; } = new List<MacTestProject> ();
|
||||
|
||||
|
@ -164,19 +129,19 @@ namespace Xharness
|
|||
public string TodayContainerTemplate { get; private set; }
|
||||
public string TodayExtensionTemplate { get; private set; }
|
||||
public string BCLTodayExtensionTemplate { get; private set; }
|
||||
public string MONO_PATH { get; private set; } // Use same name as in Makefiles, so that a grep finds it.
|
||||
public string TVOS_MONO_PATH { get; private set; } // Use same name as in Makefiles, so that a grep finds it.
|
||||
public bool INCLUDE_IOS { get; private set; }
|
||||
public bool INCLUDE_TVOS { get; private set; }
|
||||
public bool INCLUDE_WATCH { get; private set; }
|
||||
public bool INCLUDE_MAC { get; private set; }
|
||||
public string JENKINS_RESULTS_DIRECTORY { get; private set; } // Use same name as in Makefiles, so that a grep finds it.
|
||||
public string MAC_DESTDIR { get; private set; }
|
||||
public string IOS_DESTDIR { get; private set; }
|
||||
public string MONO_IOS_SDK_DESTDIR { get; private set; }
|
||||
public string MONO_MAC_SDK_DESTDIR { get; private set; }
|
||||
public bool ENABLE_XAMARIN { get; private set; }
|
||||
public string DOTNET { get; private set; }
|
||||
public string MONO_PATH { get; } // Use same name as in Makefiles, so that a grep finds it.
|
||||
public string TVOS_MONO_PATH { get; } // Use same name as in Makefiles, so that a grep finds it.
|
||||
public bool INCLUDE_IOS { get; }
|
||||
public bool INCLUDE_TVOS { get; }
|
||||
public bool INCLUDE_WATCH { get; }
|
||||
public bool INCLUDE_MAC { get; }
|
||||
public string JENKINS_RESULTS_DIRECTORY { get; } // Use same name as in Makefiles, so that a grep finds it.
|
||||
public string MAC_DESTDIR { get; }
|
||||
public string IOS_DESTDIR { get; }
|
||||
public string MONO_IOS_SDK_DESTDIR { get; }
|
||||
public string MONO_MAC_SDK_DESTDIR { get; }
|
||||
public bool ENABLE_XAMARIN { get; }
|
||||
public string DOTNET { get; }
|
||||
|
||||
// Run
|
||||
|
||||
|
@ -196,9 +161,8 @@ namespace Xharness
|
|||
|
||||
public string GetStandardErrorTty () => Helpers.GetTerminalName (2);
|
||||
|
||||
public Harness (IProcessManager processManager, IResultParser resultParser, HarnessAction action, HarnessConfiguration configuration)
|
||||
public Harness (IResultParser resultParser, HarnessAction action, HarnessConfiguration configuration)
|
||||
{
|
||||
ProcessManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
ResultParser = resultParser ?? throw new ArgumentNullException (nameof (resultParser));
|
||||
Action = action;
|
||||
|
||||
|
@ -217,7 +181,6 @@ namespace Xharness
|
|||
PeriodicCommand = configuration.PeriodicCommand;
|
||||
PeriodicCommandArguments = configuration.PeriodicCommandArguments;
|
||||
PeriodicCommandInterval = configuration.PeriodicCommandInterval;
|
||||
SdkRoot = configuration.SdkRoot;
|
||||
target = configuration.Target;
|
||||
Timeout = configuration.TimeoutInMinutes;
|
||||
useSystemXamarinIOSMac = configuration.UseSystemXamarinIOSMac;
|
||||
|
@ -233,6 +196,29 @@ namespace Xharness
|
|||
EnvironmentVariables = new Dictionary<string, string> (configuration.EnvironmentVariables);
|
||||
|
||||
LaunchTimeout = InCI ? 3 : 120;
|
||||
|
||||
var config = ParseConfigFiles ();
|
||||
var src_root = Path.GetDirectoryName (Path.GetFullPath (RootDirectory));
|
||||
|
||||
MONO_PATH = Path.GetFullPath (Path.Combine (src_root, "external", "mono"));
|
||||
TVOS_MONO_PATH = MONO_PATH;
|
||||
INCLUDE_IOS = config.ContainsKey ("INCLUDE_IOS") && !string.IsNullOrEmpty (config ["INCLUDE_IOS"]);
|
||||
INCLUDE_TVOS = config.ContainsKey ("INCLUDE_TVOS") && !string.IsNullOrEmpty (config ["INCLUDE_TVOS"]);
|
||||
JENKINS_RESULTS_DIRECTORY = config ["JENKINS_RESULTS_DIRECTORY"];
|
||||
INCLUDE_WATCH = config.ContainsKey ("INCLUDE_WATCH") && !string.IsNullOrEmpty (config ["INCLUDE_WATCH"]);
|
||||
INCLUDE_MAC = config.ContainsKey ("INCLUDE_MAC") && !string.IsNullOrEmpty (config ["INCLUDE_MAC"]);
|
||||
MAC_DESTDIR = config ["MAC_DESTDIR"];
|
||||
|
||||
IOS_DESTDIR = config ["IOS_DESTDIR"];
|
||||
MONO_IOS_SDK_DESTDIR = config ["MONO_IOS_SDK_DESTDIR"];
|
||||
MONO_MAC_SDK_DESTDIR = config ["MONO_MAC_SDK_DESTDIR"];
|
||||
ENABLE_XAMARIN = config.ContainsKey ("ENABLE_XAMARIN") && !string.IsNullOrEmpty (config ["ENABLE_XAMARIN"]);
|
||||
DOTNET = config ["DOTNET"];
|
||||
|
||||
if (string.IsNullOrEmpty (SdkRoot))
|
||||
SdkRoot = config ["XCODE_DEVELOPER_ROOT"] ?? configuration.SdkRoot;
|
||||
|
||||
processManager = new ProcessManager (XcodeRoot, MlaunchPath);
|
||||
}
|
||||
|
||||
public bool GetIncludeSystemPermissionTests (TestPlatform platform, bool device)
|
||||
|
@ -277,45 +263,6 @@ namespace Xharness
|
|||
} while (true);
|
||||
}
|
||||
|
||||
Version xcode_version;
|
||||
public Version XcodeVersion {
|
||||
get {
|
||||
if (xcode_version == null) {
|
||||
var doc = new XmlDocument ();
|
||||
doc.Load (Path.Combine (XcodeRoot, "Contents", "version.plist"));
|
||||
xcode_version = Version.Parse (doc.SelectSingleNode ("//key[text() = 'CFBundleShortVersionString']/following-sibling::string").InnerText);
|
||||
}
|
||||
return xcode_version;
|
||||
}
|
||||
}
|
||||
|
||||
public string MlaunchPath {
|
||||
get {
|
||||
return Path.Combine (IOS_DESTDIR, "Library", "Frameworks", "Xamarin.iOS.framework", "Versions", "Current", "bin", "mlaunch");
|
||||
}
|
||||
}
|
||||
|
||||
void LoadConfig ()
|
||||
{
|
||||
ParseConfigFiles ();
|
||||
var src_root = Path.GetDirectoryName (Path.GetFullPath (RootDirectory));
|
||||
MONO_PATH = Path.GetFullPath (Path.Combine (src_root, "external", "mono"));
|
||||
TVOS_MONO_PATH = MONO_PATH;
|
||||
INCLUDE_IOS = make_config.ContainsKey ("INCLUDE_IOS") && !string.IsNullOrEmpty (make_config ["INCLUDE_IOS"]);
|
||||
INCLUDE_TVOS = make_config.ContainsKey ("INCLUDE_TVOS") && !string.IsNullOrEmpty (make_config ["INCLUDE_TVOS"]);
|
||||
JENKINS_RESULTS_DIRECTORY = make_config ["JENKINS_RESULTS_DIRECTORY"];
|
||||
INCLUDE_WATCH = make_config.ContainsKey ("INCLUDE_WATCH") && !string.IsNullOrEmpty (make_config ["INCLUDE_WATCH"]);
|
||||
INCLUDE_MAC = make_config.ContainsKey ("INCLUDE_MAC") && !string.IsNullOrEmpty (make_config ["INCLUDE_MAC"]);
|
||||
MAC_DESTDIR = make_config ["MAC_DESTDIR"];
|
||||
IOS_DESTDIR = make_config ["IOS_DESTDIR"];
|
||||
if (string.IsNullOrEmpty (SdkRoot))
|
||||
SdkRoot = make_config ["XCODE_DEVELOPER_ROOT"];
|
||||
MONO_IOS_SDK_DESTDIR = make_config ["MONO_IOS_SDK_DESTDIR"];
|
||||
MONO_MAC_SDK_DESTDIR = make_config ["MONO_MAC_SDK_DESTDIR"];
|
||||
ENABLE_XAMARIN = make_config.ContainsKey ("ENABLE_XAMARIN") && !string.IsNullOrEmpty (make_config ["ENABLE_XAMARIN"]);
|
||||
DOTNET = make_config ["DOTNET"];
|
||||
}
|
||||
|
||||
int AutoConfigureMac (bool generate_projects)
|
||||
{
|
||||
int rv = 0;
|
||||
|
@ -480,7 +427,7 @@ namespace Xharness
|
|||
BCLTodayExtensionTemplate = Path.GetFullPath (Path.Combine (RootDirectory, "bcl-test", "templates", "today"));
|
||||
}
|
||||
|
||||
Dictionary<string, string> make_config = new Dictionary<string, string> ();
|
||||
// Dictionary<string, string> make_config = new Dictionary<string, string> ();
|
||||
IEnumerable<string> FindConfigFiles (string name)
|
||||
{
|
||||
var dir = Path.GetFullPath (RootDirectory);
|
||||
|
@ -492,20 +439,24 @@ namespace Xharness
|
|||
}
|
||||
}
|
||||
|
||||
void ParseConfigFiles ()
|
||||
Dictionary<string, string> ParseConfigFiles ()
|
||||
{
|
||||
ParseConfigFiles (FindConfigFiles (useSystemXamarinIOSMac ? "test-system.config" : "test.config"));
|
||||
ParseConfigFiles (FindConfigFiles ("Make.config.local"));
|
||||
ParseConfigFiles (FindConfigFiles ("Make.config"));
|
||||
var configuration = new Dictionary<string, string> ();
|
||||
foreach (var file in GetConfigFiles ()) {
|
||||
ParseConfigFile (file, configuration);
|
||||
}
|
||||
|
||||
void ParseConfigFiles (IEnumerable<string> files)
|
||||
{
|
||||
foreach (var file in files)
|
||||
ParseConfigFile (file);
|
||||
return configuration;
|
||||
}
|
||||
|
||||
void ParseConfigFile (string file)
|
||||
IEnumerable <string> GetConfigFiles ()
|
||||
{
|
||||
return FindConfigFiles (useSystemXamarinIOSMac ? "test-system.config" : "test.config")
|
||||
.Concat (FindConfigFiles ("Make.config"))
|
||||
.Concat (FindConfigFiles ("Make.config.local"));
|
||||
}
|
||||
|
||||
void ParseConfigFile (string file, Dictionary<string, string> configuration)
|
||||
{
|
||||
if (string.IsNullOrEmpty (file))
|
||||
return;
|
||||
|
@ -514,9 +465,10 @@ namespace Xharness
|
|||
var eq = line.IndexOf ('=');
|
||||
if (eq == -1)
|
||||
continue;
|
||||
|
||||
var key = line.Substring (0, eq);
|
||||
if (!make_config.ContainsKey (key))
|
||||
make_config [key] = line.Substring (eq + 1);
|
||||
if (!configuration.ContainsKey (key))
|
||||
configuration [key] = line.Substring (eq + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,22 +556,7 @@ namespace Xharness
|
|||
HarnessLog = new ConsoleLog ();
|
||||
|
||||
foreach (var project in IOSTestProjects) {
|
||||
var runner = new AppRunner (ProcessManager,
|
||||
new AppBundleInformationParser (),
|
||||
new SimulatorsLoaderFactory (this, ProcessManager),
|
||||
new SimpleListenerFactory (),
|
||||
new DeviceLoaderFactory (this, ProcessManager),
|
||||
new CrashSnapshotReporterFactory (ProcessManager, XcodeRoot, MlaunchPath),
|
||||
new CaptureLogFactory (),
|
||||
new DeviceLogCapturerFactory (ProcessManager, XcodeRoot, MlaunchPath),
|
||||
new TestReporterFactory (),
|
||||
target,
|
||||
this,
|
||||
HarnessLog,
|
||||
new Logs (LogDirectory),
|
||||
project.Path,
|
||||
buildConfiguration);
|
||||
|
||||
var runner = CreateAppRunner (project);
|
||||
using (var install_log = new AppInstallMonitorLog (runner.MainLog)) {
|
||||
var rv = runner.InstallAsync (install_log.CancellationToken).Result;
|
||||
if (!rv.Succeeded)
|
||||
|
@ -635,22 +572,7 @@ namespace Xharness
|
|||
HarnessLog = new ConsoleLog ();
|
||||
|
||||
foreach (var project in IOSTestProjects) {
|
||||
var runner = new AppRunner (ProcessManager,
|
||||
new AppBundleInformationParser (),
|
||||
new SimulatorsLoaderFactory (this, ProcessManager),
|
||||
new SimpleListenerFactory (),
|
||||
new DeviceLoaderFactory (this, ProcessManager),
|
||||
new CrashSnapshotReporterFactory (ProcessManager, XcodeRoot, MlaunchPath),
|
||||
new CaptureLogFactory (),
|
||||
new DeviceLogCapturerFactory (ProcessManager, XcodeRoot, MlaunchPath),
|
||||
new TestReporterFactory (),
|
||||
target,
|
||||
this,
|
||||
HarnessLog,
|
||||
new Logs (LogDirectory),
|
||||
project.Path,
|
||||
buildConfiguration);
|
||||
|
||||
var runner = CreateAppRunner (project);
|
||||
var rv = runner.UninstallAsync ().Result;
|
||||
if (!rv.Succeeded)
|
||||
return rv.ExitCode;
|
||||
|
@ -664,22 +586,7 @@ namespace Xharness
|
|||
HarnessLog = new ConsoleLog ();
|
||||
|
||||
foreach (var project in IOSTestProjects) {
|
||||
var runner = new AppRunner (ProcessManager,
|
||||
new AppBundleInformationParser (),
|
||||
new SimulatorsLoaderFactory (this, ProcessManager),
|
||||
new SimpleListenerFactory (),
|
||||
new DeviceLoaderFactory (this, ProcessManager),
|
||||
new CrashSnapshotReporterFactory (ProcessManager, XcodeRoot, MlaunchPath),
|
||||
new CaptureLogFactory (),
|
||||
new DeviceLogCapturerFactory (ProcessManager, XcodeRoot, MlaunchPath),
|
||||
new TestReporterFactory (),
|
||||
target,
|
||||
this,
|
||||
HarnessLog,
|
||||
new Logs (LogDirectory),
|
||||
project.Path,
|
||||
buildConfiguration);
|
||||
|
||||
var runner = CreateAppRunner (project);
|
||||
var rv = runner.RunAsync ().Result;
|
||||
if (rv != 0)
|
||||
return rv;
|
||||
|
@ -729,7 +636,6 @@ namespace Xharness
|
|||
|
||||
public int Execute ()
|
||||
{
|
||||
LoadConfig ();
|
||||
switch (Action) {
|
||||
case HarnessAction.Configure:
|
||||
return Configure ();
|
||||
|
@ -753,7 +659,7 @@ namespace Xharness
|
|||
AutoConfigureMac (false);
|
||||
}
|
||||
|
||||
var jenkins = new Jenkins.Jenkins (this, ProcessManager, ResultParser);
|
||||
var jenkins = new Jenkins.Jenkins (this, processManager, ResultParser);
|
||||
return jenkins.Run ();
|
||||
}
|
||||
|
||||
|
@ -807,9 +713,23 @@ namespace Xharness
|
|||
}
|
||||
}
|
||||
|
||||
public Task<ProcessExecutionResult> ExecuteXcodeCommandAsync (string executable, IList<string> args, ILog log, TimeSpan timeout)
|
||||
private AppRunner CreateAppRunner (TestProject project)
|
||||
{
|
||||
return ProcessManager.ExecuteCommandAsync (Path.Combine (XcodeRoot, "Contents", "Developer", "usr", "bin", executable), args, log, timeout: timeout);
|
||||
return new AppRunner (processManager,
|
||||
new AppBundleInformationParser (),
|
||||
new SimulatorsLoaderFactory (processManager),
|
||||
new SimpleListenerFactory (),
|
||||
new DeviceLoaderFactory (processManager),
|
||||
new CrashSnapshotReporterFactory (processManager),
|
||||
new CaptureLogFactory (),
|
||||
new DeviceLogCapturerFactory (processManager),
|
||||
new TestReporterFactory (),
|
||||
target,
|
||||
this,
|
||||
HarnessLog,
|
||||
new Logs (LogDirectory),
|
||||
project.Path,
|
||||
buildConfiguration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@ namespace Xharness {
|
|||
// common interface that contains the basic info needed by the test result to be able to parse the results and
|
||||
// log all the required data.
|
||||
public interface IAppRunner {
|
||||
IProcessManager ProcessManager { get; }
|
||||
AppBundleInformation AppInformation { get; }
|
||||
BuildToolTask BuildTask { get; }
|
||||
TimeSpan GetNewTimeout ();
|
||||
double LaunchTimeout { get; }
|
||||
IProcessManager ProcessManager { get; }
|
||||
ILogs Logs { get; }
|
||||
ILog MainLog { get; }
|
||||
RunMode RunMode { get; }
|
||||
|
|
|
@ -103,15 +103,15 @@ namespace Xharness.Jenkins
|
|||
this.processManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
this.resultParser = resultParser ?? throw new ArgumentNullException (nameof (resultParser));
|
||||
Harness = harness ?? throw new ArgumentNullException (nameof (harness));
|
||||
simulators = new Simulators (harness, processManager);
|
||||
devices = new Devices (harness, processManager);
|
||||
simulators = new Simulators (processManager);
|
||||
devices = new Devices (processManager);
|
||||
}
|
||||
|
||||
Task LoadAsync (ref ILog log, ILoadAsync loadable, string name)
|
||||
{
|
||||
loadable.Harness = Harness;
|
||||
if (log == null)
|
||||
log = Logs.Create ($"{name}-list-{Helpers.Timestamp}.log", $"{name} Listing");
|
||||
|
||||
log.Description = $"{name} Listing (in progress)";
|
||||
|
||||
var capturedLog = log;
|
||||
|
@ -481,7 +481,7 @@ namespace Xharness.Jenkins
|
|||
clone.Xml.Save (clone.Path);
|
||||
});
|
||||
|
||||
var build = new MSBuildTask {
|
||||
var build = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
TestProject = clone,
|
||||
ProjectConfiguration = configuration,
|
||||
|
@ -530,7 +530,7 @@ namespace Xharness.Jenkins
|
|||
configurations = new string [] { "Debug" };
|
||||
foreach (var config in configurations) {
|
||||
foreach (var pair in ps) {
|
||||
var derived = new MSBuildTask () {
|
||||
var derived = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
ProjectConfiguration = config,
|
||||
ProjectPlatform = "iPhoneSimulator",
|
||||
|
@ -584,7 +584,7 @@ namespace Xharness.Jenkins
|
|||
|
||||
projectTasks.Clear ();
|
||||
if (!project.SkipiOSVariation) {
|
||||
var build64 = new MSBuildTask {
|
||||
var build64 = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
ProjectConfiguration = "Debug64",
|
||||
ProjectPlatform = "iPhone",
|
||||
|
@ -594,7 +594,7 @@ namespace Xharness.Jenkins
|
|||
build64.CloneTestProject (project);
|
||||
projectTasks.Add (new RunDeviceTask (devices, build64, processManager, devices.Connected64BitIOS.Where (d => d.IsSupported (project))) { Ignored = !IncludeiOS64 });
|
||||
|
||||
var build32 = new MSBuildTask {
|
||||
var build32 = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
ProjectConfiguration = project.Name != "dont link" ? "Debug32" : "Release32",
|
||||
ProjectPlatform = "iPhone",
|
||||
|
@ -605,7 +605,7 @@ namespace Xharness.Jenkins
|
|||
projectTasks.Add (new RunDeviceTask (devices, build32, processManager, devices.Connected32BitIOS.Where (d => d.IsSupported (project))) { Ignored = !IncludeiOS32 });
|
||||
|
||||
var todayProject = project.AsTodayExtensionProject ();
|
||||
var buildToday = new MSBuildTask {
|
||||
var buildToday = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
ProjectConfiguration = "Debug64",
|
||||
ProjectPlatform = "iPhone",
|
||||
|
@ -618,7 +618,7 @@ namespace Xharness.Jenkins
|
|||
|
||||
if (!project.SkiptvOSVariation) {
|
||||
var tvOSProject = project.AsTvOSProject ();
|
||||
var buildTV = new MSBuildTask {
|
||||
var buildTV = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
ProjectConfiguration = "Debug",
|
||||
ProjectPlatform = "iPhone",
|
||||
|
@ -632,7 +632,7 @@ namespace Xharness.Jenkins
|
|||
if (!project.SkipwatchOSVariation) {
|
||||
var watchOSProject = project.AsWatchOSProject ();
|
||||
if (!project.SkipwatchOS32Variation) {
|
||||
var buildWatch32 = new MSBuildTask {
|
||||
var buildWatch32 = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
ProjectConfiguration = "Debug32",
|
||||
ProjectPlatform = "iPhone",
|
||||
|
@ -644,7 +644,7 @@ namespace Xharness.Jenkins
|
|||
}
|
||||
|
||||
if (!project.SkipwatchOSARM64_32Variation) {
|
||||
var buildWatch64_32 = new MSBuildTask {
|
||||
var buildWatch64_32 = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
ProjectConfiguration = "Release64_32", // We don't support Debug for ARM64_32 yet.
|
||||
ProjectPlatform = "iPhone",
|
||||
|
@ -720,7 +720,7 @@ namespace Xharness.Jenkins
|
|||
|
||||
void SelectTestsByModifiedFiles (int pull_request)
|
||||
{
|
||||
var files = GitHub.GetModifiedFiles (Harness, pull_request);
|
||||
var files = GitHub.GetModifiedFiles (processManager, Harness, pull_request);
|
||||
|
||||
MainLog.WriteLine ("Found {0} modified file(s) in the pull request #{1}.", files.Count (), pull_request);
|
||||
foreach (var f in files)
|
||||
|
@ -938,9 +938,9 @@ namespace Xharness.Jenkins
|
|||
|
||||
//Tasks.AddRange (await CreateRunSimulatorTasksAsync ());
|
||||
|
||||
var crashReportSnapshotFactory = new CrashSnapshotReporterFactory (processManager, Harness.XcodeRoot, Harness.MlaunchPath);
|
||||
var crashReportSnapshotFactory = new CrashSnapshotReporterFactory (processManager);
|
||||
|
||||
var buildiOSMSBuild_net461 = new MSBuildTask ()
|
||||
var buildiOSMSBuild_net461 = new MSBuildTask (processManager)
|
||||
{
|
||||
Jenkins = this,
|
||||
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "..", "msbuild", "tests", "Xamarin.iOS.Tasks.Tests", "Xamarin.iOS.Tasks.Tests.csproj"))),
|
||||
|
@ -965,7 +965,7 @@ namespace Xharness.Jenkins
|
|||
};
|
||||
Tasks.Add (nunitExecutioniOSMSBuild_net461);
|
||||
|
||||
var buildiOSMSBuild_netstandard2 = new MSBuildTask () {
|
||||
var buildiOSMSBuild_netstandard2 = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "..", "msbuild", "tests", "Xamarin.iOS.Tasks.Tests", "Xamarin.iOS.Tasks.Tests.csproj"))),
|
||||
SpecifyPlatform = false,
|
||||
|
@ -988,7 +988,7 @@ namespace Xharness.Jenkins
|
|||
};
|
||||
Tasks.Add (nunitExecutioniOSMSBuild_netstandard2);
|
||||
|
||||
var buildInstallSources = new MSBuildTask ()
|
||||
var buildInstallSources = new MSBuildTask (processManager)
|
||||
{
|
||||
Jenkins = this,
|
||||
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "..", "tools", "install-source", "InstallSourcesTests", "InstallSourcesTests.csproj"))),
|
||||
|
@ -1039,7 +1039,7 @@ namespace Xharness.Jenkins
|
|||
throw new NotImplementedException (project.TargetFrameworkFlavors.ToString ());
|
||||
}
|
||||
foreach (var config in configurations) {
|
||||
MSBuildTask build = new MSBuildTask ();
|
||||
MSBuildTask build = new MSBuildTask (processManager);
|
||||
build.Platform = platform;
|
||||
build.CloneTestProject (project);
|
||||
build.Jenkins = this;
|
||||
|
@ -1082,7 +1082,7 @@ namespace Xharness.Jenkins
|
|||
}
|
||||
}
|
||||
|
||||
var buildMTouch = new MakeTask ()
|
||||
var buildMTouch = new MakeTask (processManager)
|
||||
{
|
||||
Jenkins = this,
|
||||
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "mtouch", "mtouch.sln"))),
|
||||
|
@ -1104,7 +1104,7 @@ namespace Xharness.Jenkins
|
|||
};
|
||||
Tasks.Add (nunitExecutionMTouch);
|
||||
|
||||
var buildGenerator = new MakeTask {
|
||||
var buildGenerator = new MakeTask (processManager) {
|
||||
Jenkins = this,
|
||||
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "..", "src", "generator.sln"))),
|
||||
SpecifyPlatform = false,
|
||||
|
@ -1124,7 +1124,7 @@ namespace Xharness.Jenkins
|
|||
};
|
||||
Tasks.Add (runGenerator);
|
||||
|
||||
var buildDotNetGenerator = new DotNetBuildTask {
|
||||
var buildDotNetGenerator = new DotNetBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "bgen", "bgen-tests.csproj"))),
|
||||
SpecifyPlatform = false,
|
||||
|
@ -1140,7 +1140,7 @@ namespace Xharness.Jenkins
|
|||
};
|
||||
Tasks.Add (runDotNetGenerator);
|
||||
|
||||
var run_mmp = new MakeTask
|
||||
var run_mmp = new MakeTask (processManager)
|
||||
{
|
||||
Jenkins = this,
|
||||
Platform = TestPlatform.Mac,
|
||||
|
@ -1159,7 +1159,7 @@ namespace Xharness.Jenkins
|
|||
run_mmp.Environment.Add ("BUILD_REVISION", "jenkins"); // This will print "@MonkeyWrench: AddFile: <log path>" lines, which we can use to get the log filenames.
|
||||
Tasks.Add (run_mmp);
|
||||
|
||||
var runMacBindingProject = new MakeTask
|
||||
var runMacBindingProject = new MakeTask (processManager)
|
||||
{
|
||||
Jenkins = this,
|
||||
Platform = TestPlatform.Mac,
|
||||
|
@ -1171,7 +1171,7 @@ namespace Xharness.Jenkins
|
|||
};
|
||||
Tasks.Add (runMacBindingProject);
|
||||
|
||||
var buildXtroTests = new MakeTask {
|
||||
var buildXtroTests = new MakeTask (processManager) {
|
||||
Jenkins = this,
|
||||
Platform = TestPlatform.All,
|
||||
TestName = "Xtro",
|
||||
|
@ -1189,7 +1189,7 @@ namespace Xharness.Jenkins
|
|||
};
|
||||
Tasks.Add (runXtroReporter);
|
||||
|
||||
var buildCecilTests = new MakeTask {
|
||||
var buildCecilTests = new MakeTask (processManager) {
|
||||
Jenkins = this,
|
||||
Platform = TestPlatform.All,
|
||||
TestName = "Cecil",
|
||||
|
@ -1209,7 +1209,7 @@ namespace Xharness.Jenkins
|
|||
};
|
||||
Tasks.Add (runCecilTests);
|
||||
|
||||
var runDocsTests = new MakeTask {
|
||||
var runDocsTests = new MakeTask (processManager) {
|
||||
Jenkins = this,
|
||||
Platform = TestPlatform.All,
|
||||
TestName = "Documentation",
|
||||
|
@ -1220,7 +1220,7 @@ namespace Xharness.Jenkins
|
|||
};
|
||||
Tasks.Add (runDocsTests);
|
||||
|
||||
var buildSampleTests = new MSBuildTask {
|
||||
var buildSampleTests = new MSBuildTask (processManager) {
|
||||
Jenkins = this,
|
||||
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "sampletester", "sampletester.sln"))),
|
||||
SpecifyPlatform = false,
|
||||
|
@ -1253,7 +1253,7 @@ namespace Xharness.Jenkins
|
|||
using (var process = new Process ()) {
|
||||
process.StartInfo.FileName = Harness.PeriodicCommand;
|
||||
process.StartInfo.Arguments = Harness.PeriodicCommandArguments;
|
||||
var rv = await Harness.ProcessManager.RunAsync (process, periodic_loc, timeout: Harness.PeriodicCommandInterval);
|
||||
var rv = await processManager.RunAsync (process, periodic_loc, timeout: Harness.PeriodicCommandInterval);
|
||||
if (!rv.Succeeded)
|
||||
periodic_loc.WriteLine ($"Periodic command failed with exit code {rv.ExitCode} (Timed out: {rv.TimedOut})");
|
||||
}
|
||||
|
@ -1293,7 +1293,7 @@ namespace Xharness.Jenkins
|
|||
|
||||
// We can populate and build test-libraries in parallel.
|
||||
var populate = Task.Run (async () => {
|
||||
var simulator = new SimulatorDevice (Harness, processManager);
|
||||
var simulator = new SimulatorDevice (processManager, new TCCDatabase (processManager));
|
||||
await simulator.KillEverythingAsync (MainLog);
|
||||
await PopulateTasksAsync ();
|
||||
populating = false;
|
||||
|
@ -1328,7 +1328,7 @@ namespace Xharness.Jenkins
|
|||
var sb = new StringBuilder ();
|
||||
var callback_log = new CallbackLog ((v) => sb.Append (v));
|
||||
var log = Log.CreateAggregatedLog (callback_log, MainLog);
|
||||
return Harness.ProcessManager.ExecuteCommandAsync ("make", new [] { "all", $"-j{Environment.ProcessorCount}", "-C", Path.Combine (Harness.RootDirectory, "test-libraries") }, log, TimeSpan.FromMinutes (10)).ContinueWith ((v) => {
|
||||
return processManager.ExecuteCommandAsync ("make", new [] { "all", $"-j{Environment.ProcessorCount}", "-C", Path.Combine (Harness.RootDirectory, "test-libraries") }, log, TimeSpan.FromMinutes (10)).ContinueWith ((v) => {
|
||||
var per = v.Result;
|
||||
if (!per.Succeeded) {
|
||||
// Only show the log if something went wrong.
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Xharness.Execution;
|
||||
using Xharness.Logging;
|
||||
using Xharness.Utilities;
|
||||
|
||||
|
@ -13,6 +14,10 @@ namespace Xharness.Jenkins.TestTasks
|
|||
{
|
||||
public string SolutionPath;
|
||||
|
||||
protected BuildProjectTask (IProcessManager processManager) : base (processManager)
|
||||
{
|
||||
}
|
||||
|
||||
public bool RestoreNugets {
|
||||
get {
|
||||
return TestProject.RestoreNugetsInProject || !string.IsNullOrEmpty (SolutionPath);
|
||||
|
|
|
@ -6,9 +6,15 @@ namespace Xharness.Jenkins.TestTasks
|
|||
{
|
||||
public abstract class BuildToolTask : TestTask
|
||||
{
|
||||
protected readonly IProcessManager ProcessManager;
|
||||
|
||||
public bool SpecifyPlatform = true;
|
||||
public bool SpecifyConfiguration = true;
|
||||
public IProcessManager ProcessManager { get; set; } = new ProcessManager ();
|
||||
|
||||
protected BuildToolTask (IProcessManager processManager)
|
||||
{
|
||||
ProcessManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
|
||||
}
|
||||
|
||||
public override string Mode {
|
||||
get { return Platform.ToString (); }
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Xharness.Execution;
|
||||
|
||||
namespace Xharness.Jenkins.TestTasks {
|
||||
class DotNetBuildTask : MSBuildTask {
|
||||
|
||||
public DotNetBuildTask ()
|
||||
public DotNetBuildTask (IProcessManager processManager) : base (processManager)
|
||||
{
|
||||
SetDotNetEnvironmentVariables (Environment);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Xharness.Execution;
|
||||
using Xharness.Logging;
|
||||
using Xharness.Utilities;
|
||||
|
||||
|
@ -31,6 +32,10 @@ namespace Xharness.Jenkins.TestTasks
|
|||
}
|
||||
}
|
||||
|
||||
public MSBuildTask (IProcessManager processManager) : base (processManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync ()
|
||||
{
|
||||
using (var resource = await NotifyAndAcquireDesktopResourceAsync ()) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Xharness.Execution;
|
||||
using Xharness.Logging;
|
||||
|
||||
namespace Xharness.Jenkins.TestTasks
|
||||
|
@ -11,6 +12,10 @@ namespace Xharness.Jenkins.TestTasks
|
|||
public string WorkingDirectory;
|
||||
public TimeSpan Timeout = TimeSpan.FromMinutes (5);
|
||||
|
||||
public MakeTask (IProcessManager processManager) : base (processManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync ()
|
||||
{
|
||||
using (var resource = await NotifyAndAcquireDesktopResourceAsync ()) {
|
||||
|
|
|
@ -11,9 +11,9 @@ namespace Xharness.Jenkins.TestTasks
|
|||
{
|
||||
class RunDeviceTask : RunXITask<IHardwareDevice>
|
||||
{
|
||||
readonly IProcessManager processManager = new ProcessManager ();
|
||||
readonly IResultParser resultParser = new XmlResultParser ();
|
||||
readonly IDeviceLoader devices;
|
||||
|
||||
AppInstallMonitorLog install_log;
|
||||
|
||||
public override string ProgressMessage {
|
||||
|
@ -81,14 +81,14 @@ namespace Xharness.Jenkins.TestTasks
|
|||
CompanionDevice = devices.FindCompanionDevice (Jenkins.DeviceLoadLog, Device);
|
||||
Jenkins.MainLog.WriteLine ("Acquired device '{0}' for '{1}'", Device.Name, ProjectFile);
|
||||
|
||||
runner = new AppRunner (processManager,
|
||||
runner = new AppRunner (ProcessManager,
|
||||
new AppBundleInformationParser (),
|
||||
new SimulatorsLoaderFactory (Harness, processManager),
|
||||
new SimulatorsLoaderFactory (ProcessManager),
|
||||
new SimpleListenerFactory (),
|
||||
new DeviceLoaderFactory (Harness, processManager),
|
||||
new CrashSnapshotReporterFactory (ProcessManager, Harness.XcodeRoot, Harness.MlaunchPath),
|
||||
new DeviceLoaderFactory (ProcessManager),
|
||||
new CrashSnapshotReporterFactory (ProcessManager),
|
||||
new CaptureLogFactory (),
|
||||
new DeviceLogCapturerFactory (processManager, Harness.XcodeRoot, Harness.MlaunchPath),
|
||||
new DeviceLogCapturerFactory (ProcessManager),
|
||||
new TestReporterFactory (),
|
||||
AppRunnerTarget,
|
||||
Harness,
|
||||
|
@ -148,14 +148,14 @@ namespace Xharness.Jenkins.TestTasks
|
|||
// nor will it close & reopen the today app (but launching the main app
|
||||
// will do both of these things, preparing the device for launching the today extension).
|
||||
|
||||
AppRunner todayRunner = new AppRunner (processManager,
|
||||
AppRunner todayRunner = new AppRunner (ProcessManager,
|
||||
new AppBundleInformationParser (),
|
||||
new SimulatorsLoaderFactory (Harness, processManager),
|
||||
new SimulatorsLoaderFactory (ProcessManager),
|
||||
new SimpleListenerFactory (),
|
||||
new DeviceLoaderFactory (Harness, processManager),
|
||||
new CrashSnapshotReporterFactory (ProcessManager, Harness.XcodeRoot, Harness.MlaunchPath),
|
||||
new DeviceLoaderFactory (ProcessManager),
|
||||
new CrashSnapshotReporterFactory (ProcessManager),
|
||||
new CaptureLogFactory (),
|
||||
new DeviceLogCapturerFactory (processManager, Harness.XcodeRoot, Harness.MlaunchPath),
|
||||
new DeviceLogCapturerFactory (ProcessManager),
|
||||
new TestReporterFactory (),
|
||||
AppRunnerTarget,
|
||||
Harness,
|
||||
|
|
|
@ -13,7 +13,6 @@ namespace Xharness.Jenkins.TestTasks
|
|||
{
|
||||
class RunSimulatorTask : RunXITask<ISimulatorDevice>
|
||||
{
|
||||
readonly IProcessManager processManager = new ProcessManager ();
|
||||
readonly ISimulatorsLoader simulators;
|
||||
public IAcquiredResource AcquiredResource;
|
||||
|
||||
|
@ -77,14 +76,14 @@ namespace Xharness.Jenkins.TestTasks
|
|||
await FindSimulatorAsync ();
|
||||
|
||||
var clean_state = false;//Platform == TestPlatform.watchOS;
|
||||
runner = new AppRunner (processManager,
|
||||
runner = new AppRunner (ProcessManager,
|
||||
new AppBundleInformationParser (),
|
||||
new SimulatorsLoaderFactory (Harness, processManager),
|
||||
new SimulatorsLoaderFactory (ProcessManager),
|
||||
new SimpleListenerFactory (),
|
||||
new DeviceLoaderFactory (Harness, processManager),
|
||||
new CrashSnapshotReporterFactory (ProcessManager, Harness.XcodeRoot, Harness.MlaunchPath),
|
||||
new DeviceLoaderFactory (ProcessManager),
|
||||
new CrashSnapshotReporterFactory (ProcessManager),
|
||||
new CaptureLogFactory (),
|
||||
new DeviceLogCapturerFactory (processManager, Harness.XcodeRoot, Harness.MlaunchPath),
|
||||
new DeviceLogCapturerFactory (ProcessManager),
|
||||
new TestReporterFactory (),
|
||||
AppRunnerTarget,
|
||||
Harness,
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace Xharness {
|
|||
// XS sets this, which breaks pretty much everything if it doesn't match what was passed to --sdkroot.
|
||||
Environment.SetEnvironmentVariable ("XCODE_DEVELOPER_DIR_PATH", null);
|
||||
|
||||
var harness = new Harness (new ProcessManager(), new XmlResultParser (), action, configuration);
|
||||
var harness = new Harness (new XmlResultParser (), action, configuration);
|
||||
|
||||
return harness.Execute ();
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace Xharness.Tests.Execution.Tests {
|
|||
stdoutLog = new LogFile ("my stdout log", stdoutLogPath);
|
||||
stderrLog = new LogFile ("my stderr log", stderrLogPath);
|
||||
dummyProcess = Path.Combine (Path.GetDirectoryName (GetType ().Assembly.Location), "DummyTestProcess.exe");
|
||||
manager = new ProcessManager ();
|
||||
manager = new ProcessManager ("/path/to/xcode", "/path/to/mlaunch");
|
||||
testProcess = new Process ();
|
||||
testProcess.StartInfo.FileName = "mono";
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ namespace Xharness.Tests.Execution.Tests {
|
|||
{
|
||||
var source = new CancellationTokenSource ();
|
||||
testProcess.StartInfo.Arguments = $"{dummyProcess} --exit-code={resultCode} --timeout={timeoutCount} --stdout=\"{stdoutMessage}\" --stderr=\"{stderrMessage}\"";
|
||||
var result = await manager.RunAsync (testProcess, executionLog, source.Token);
|
||||
var result = await manager.RunAsync (testProcess, executionLog, executionLog, executionLog, cancellationToken: source.Token);
|
||||
if (!timeout)
|
||||
Assert.AreEqual (resultCode, result.ExitCode, "exit code");
|
||||
Assert.AreEqual (success, result.Succeeded, "success");
|
||||
|
|
|
@ -20,16 +20,14 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
Devices devices;
|
||||
string mlaunchPath;
|
||||
string sdkPath;
|
||||
Mock<IHarness> harness;
|
||||
Mock<IProcessManager> processManager;
|
||||
Mock<ILog> executionLog;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp ()
|
||||
{
|
||||
harness = new Mock<IHarness> ();
|
||||
processManager = new Mock<IProcessManager> ();
|
||||
devices = new Devices (harness.Object, processManager.Object);
|
||||
devices = new Devices (processManager.Object);
|
||||
executionLog = new Mock<ILog> ();
|
||||
mlaunchPath = "/usr/bin/mlaunch"; // any will be ok, is mocked
|
||||
sdkPath = "/Applications/Xcode.app";
|
||||
|
@ -38,7 +36,6 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
[TearDown]
|
||||
public void TearDown ()
|
||||
{
|
||||
harness = null;
|
||||
processManager = null;
|
||||
executionLog = null;
|
||||
devices = null;
|
||||
|
@ -50,10 +47,7 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
{
|
||||
string processPath = null;
|
||||
MlaunchArguments passedArguments = null;
|
||||
// set the expectations of the mocks to get an error when
|
||||
// executing the process
|
||||
harness.Setup (h => h.MlaunchPath).Returns (mlaunchPath);
|
||||
harness.Setup (h => h.XcodeRoot).Returns (sdkPath);
|
||||
|
||||
// moq It.Is is not working as nicelly as we would like it, we capture data and use asserts
|
||||
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?> ()))
|
||||
.Returns<Process, MlaunchArguments, ILog, TimeSpan?, Dictionary< string, string>, CancellationToken?, bool?> ((p, args, log, t, env, token, d) => {
|
||||
|
@ -87,10 +81,7 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
{
|
||||
string processPath = null;
|
||||
MlaunchArguments passedArguments = null;
|
||||
// set the expectations of the mocks to get an error when
|
||||
// executing the process
|
||||
harness.Setup (h => h.MlaunchPath).Returns (mlaunchPath);
|
||||
harness.Setup (h => h.XcodeRoot).Returns (sdkPath);
|
||||
|
||||
// moq It.Is is not working as nicelly as we would like it, we capture data and use asserts
|
||||
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?> ()))
|
||||
.Returns<Process, MlaunchArguments, ILog, TimeSpan?, Dictionary<string, string>, CancellationToken?, bool?> ((p, args, log, t, env, token, d) => {
|
||||
|
|
|
@ -14,7 +14,6 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
|
||||
Mock<ILog> executionLog;
|
||||
Mock<IProcessManager> processManager;
|
||||
Mock<IHarness> harness;
|
||||
SimulatorDevice simulator;
|
||||
|
||||
[SetUp]
|
||||
|
@ -22,8 +21,7 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
{
|
||||
executionLog = new Mock<ILog> ();
|
||||
processManager = new Mock<IProcessManager> ();
|
||||
harness = new Mock<IHarness> ();
|
||||
simulator = new SimulatorDevice (harness.Object, processManager.Object) {
|
||||
simulator = new SimulatorDevice (processManager.Object, new TCCDatabase (processManager.Object)) {
|
||||
UDID = Guid.NewGuid ().ToString ()
|
||||
};
|
||||
}
|
||||
|
@ -57,10 +55,10 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
{
|
||||
// just call and verify the correct args are pass
|
||||
await simulator.EraseAsync (executionLog.Object);
|
||||
harness.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "shutdown").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
harness.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "erase").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
harness.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "boot").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
harness.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "shutdown").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
processManager.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "shutdown").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
processManager.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "erase").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
processManager.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "boot").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
processManager.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "shutdown").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
|
||||
}
|
||||
|
||||
|
@ -69,7 +67,7 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
{
|
||||
await simulator.ShutdownAsync (executionLog.Object);
|
||||
// just call and verify the correct args are pass
|
||||
harness.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "shutdown").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
processManager.Verify (h => h.ExecuteXcodeCommandAsync (It.Is<string> (s => s == "simctl"), It.Is<string []> (args => args.Where (a => a == simulator.UDID || a == "shutdown").Count () == 2), It.IsAny<ILog> (), It.IsAny<TimeSpan> ()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -81,7 +79,7 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
return args.Where (a => toKill.Contains (a)).Count () == toKill.Count;
|
||||
};
|
||||
|
||||
var simulator = new SimulatorDevice (Mock.Of<IHarness> (), processManager.Object);
|
||||
var simulator = new SimulatorDevice (processManager.Object, new TCCDatabase (processManager.Object));
|
||||
await simulator.KillEverythingAsync (executionLog.Object);
|
||||
|
||||
// verify that all the diff process have been killed making sure args are correct
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
|
||||
string mlaunchPath;
|
||||
string sdkPath;
|
||||
Mock<IHarness> harness;
|
||||
Mock<ILog> executionLog;
|
||||
Mock<IProcessManager> processManager;
|
||||
Simulators simulators;
|
||||
|
@ -29,10 +28,9 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
{
|
||||
mlaunchPath = "/usr/bin/mlaunch"; // any will be ok, is mocked
|
||||
sdkPath = "/Applications/Xcode.app";
|
||||
harness = new Mock<IHarness> ();
|
||||
executionLog = new Mock<ILog> ();
|
||||
processManager = new Mock<IProcessManager> ();
|
||||
simulators = new Simulators (harness.Object, processManager.Object);
|
||||
simulators = new Simulators (processManager.Object);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
|
@ -49,10 +47,7 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
{
|
||||
string processPath = null;
|
||||
MlaunchArguments passedArguments = null;
|
||||
// set the expectations of the mocks to get an error when
|
||||
// executing the process
|
||||
harness.Setup (h => h.MlaunchPath).Returns (mlaunchPath);
|
||||
harness.Setup (h => h.XcodeRoot).Returns (sdkPath);
|
||||
|
||||
// moq It.Is is not working as nicelly as we would like it, we capture data and use asserts
|
||||
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?> ()))
|
||||
.Returns<Process, MlaunchArguments, ILog, TimeSpan?, Dictionary<string, string>, CancellationToken?, bool?> ((p, args, log, t, env, token, d) => {
|
||||
|
@ -97,10 +92,7 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
{
|
||||
string processPath = null;
|
||||
MlaunchArguments passedArguments = null;
|
||||
// set the expectations of the mocks to get an error when
|
||||
// executing the process
|
||||
harness.Setup (h => h.MlaunchPath).Returns (mlaunchPath);
|
||||
harness.Setup (h => h.XcodeRoot).Returns (sdkPath);
|
||||
|
||||
// moq It.Is is not working as nicelly as we would like it, we capture data and use asserts
|
||||
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?> ()))
|
||||
.Returns<Process, MlaunchArguments, ILog, TimeSpan?, Dictionary<string, string>, CancellationToken?, bool?> ((p, args, log, t, env, token, d) => {
|
||||
|
@ -141,12 +133,9 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
{
|
||||
string processPath = null;
|
||||
MlaunchArguments passedArguments = null;
|
||||
// set the expectations of the mocks to get an error when
|
||||
// executing the process
|
||||
harness.Setup (h => h.MlaunchPath).Returns (mlaunchPath);
|
||||
harness.Setup (h => h.XcodeRoot).Returns (sdkPath);
|
||||
harness
|
||||
.Setup (h => h.ExecuteXcodeCommandAsync ("simctl", It.Is<string []> (args => args [0] == "create"), executionLog.Object, TimeSpan.FromMinutes (1)))
|
||||
|
||||
processManager
|
||||
.Setup (h => h.ExecuteXcodeCommandAsync ("simctl", It.Is<string []> (args => args[0] == "create"), executionLog.Object, TimeSpan.FromMinutes (1)))
|
||||
.ReturnsAsync (new ProcessExecutionResult () { ExitCode = 0 });
|
||||
|
||||
// moq It.Is is not working as nicelly as we would like it, we capture data and use asserts
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -25,9 +24,7 @@ namespace Xharness.Tests.Hardware.Tests {
|
|||
public void SetUp ()
|
||||
{
|
||||
processManager = new Mock<IProcessManager> ();
|
||||
database = new TCCDatabase {
|
||||
ProcessManager = processManager.Object,
|
||||
};
|
||||
database = new TCCDatabase (processManager.Object);
|
||||
executionLog = new Mock<ILog> ();
|
||||
simRuntime = "com.apple.CoreSimulator.SimRuntime.iOS-12-1";
|
||||
dataPath = "/path/to/my/data";
|
||||
|
|
|
@ -218,9 +218,7 @@ namespace Xharness.Tests {
|
|||
[Test]
|
||||
public async Task InstallOnDeviceTest ()
|
||||
{
|
||||
var harness = Mock.Of<IHarness> (x => x.XcodeRoot == "/path/to/xcode"
|
||||
&& x.MlaunchPath == "/path/to/mlaunch"
|
||||
&& x.Verbosity == 2);
|
||||
var harness = Mock.Of<IHarness> (x => x.Verbosity == 2);
|
||||
|
||||
var processResult = new ProcessExecutionResult () { ExitCode = 1, TimedOut = false };
|
||||
processManager.SetReturnsDefault (Task.FromResult (processResult));
|
||||
|
@ -250,13 +248,10 @@ namespace Xharness.Tests {
|
|||
// Verify
|
||||
Assert.AreEqual (1, result.ExitCode);
|
||||
|
||||
var expectedArgs = $"--sdkroot /path/to/xcode -v -v -v " +
|
||||
$"--installdev {StringUtils.FormatArguments (appPath)} " +
|
||||
$"--devname \"Test iPad\"";
|
||||
var expectedArgs = $"-v -v -v --installdev {StringUtils.FormatArguments (appPath)} --devname \"Test iPad\"";
|
||||
|
||||
processManager.Verify (x => x.ExecuteCommandAsync (
|
||||
"/path/to/mlaunch",
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine () == expectedArgs),
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine() == expectedArgs),
|
||||
mainLog.Object,
|
||||
TimeSpan.FromHours (1),
|
||||
null,
|
||||
|
@ -266,9 +261,7 @@ namespace Xharness.Tests {
|
|||
[Test]
|
||||
public async Task UninstallFromDeviceTest ()
|
||||
{
|
||||
var harness = Mock.Of<IHarness> (x => x.XcodeRoot == "/path/to/xcode"
|
||||
&& x.MlaunchPath == "/path/to/mlaunch"
|
||||
&& x.Verbosity == 1);
|
||||
var harness = Mock.Of<IHarness> (x => x.Verbosity == 1);
|
||||
|
||||
var processResult = new ProcessExecutionResult () { ExitCode = 3, TimedOut = false };
|
||||
processManager.SetReturnsDefault (Task.FromResult (processResult));
|
||||
|
@ -297,13 +290,10 @@ namespace Xharness.Tests {
|
|||
// Verify
|
||||
Assert.AreEqual (3, result.ExitCode);
|
||||
|
||||
var expectedArgs = $"--sdkroot /path/to/xcode -v -v " +
|
||||
$"--uninstalldevbundleid {StringUtils.FormatArguments (appName)} " +
|
||||
$"--devname \"Test iPad\"";
|
||||
var expectedArgs = $"-v -v --uninstalldevbundleid {StringUtils.FormatArguments (appName)} --devname \"Test iPad\"";
|
||||
|
||||
processManager.Verify (x => x.ExecuteCommandAsync (
|
||||
"/path/to/mlaunch",
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine () == expectedArgs),
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine() == expectedArgs),
|
||||
mainLog.Object,
|
||||
TimeSpan.FromMinutes (1),
|
||||
null,
|
||||
|
@ -461,8 +451,7 @@ namespace Xharness.Tests {
|
|||
|
||||
processManager
|
||||
.Setup (x => x.ExecuteCommandAsync (
|
||||
mlaunchPath,
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine () == expectedArgs),
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine() == expectedArgs),
|
||||
mainLog.Object,
|
||||
TimeSpan.FromMinutes (harness.Timeout * 2),
|
||||
null,
|
||||
|
@ -612,7 +601,7 @@ namespace Xharness.Tests {
|
|||
ips.Append (ipAddresses [i].ToString ());
|
||||
}
|
||||
|
||||
var expectedArgs = $"--sdkroot {StringUtils.FormatArguments (xcodePath)} -v -v -argument=-connection-mode -argument=none " +
|
||||
var expectedArgs = $"-v -v -argument=-connection-mode -argument=none " +
|
||||
$"-argument=-app-arg:-autostart -setenv=NUNIT_AUTOSTART=true -argument=-app-arg:-autoexit " +
|
||||
$"-setenv=NUNIT_AUTOEXIT=true -argument=-app-arg:-enablenetwork -setenv=NUNIT_ENABLE_NETWORK=true " +
|
||||
$"-setenv=DISABLE_SYSTEM_PERMISSION_TESTS=1 -argument=-app-arg:-hostname:{ips} -setenv=NUNIT_HOSTNAME={ips} " +
|
||||
|
@ -622,7 +611,6 @@ namespace Xharness.Tests {
|
|||
|
||||
processManager
|
||||
.Setup (x => x.ExecuteCommandAsync (
|
||||
mlaunchPath,
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine () == expectedArgs),
|
||||
It.IsAny<ILog> (),
|
||||
TimeSpan.FromMinutes (harness.Timeout * 2),
|
||||
|
@ -633,18 +621,18 @@ namespace Xharness.Tests {
|
|||
var xmlResultFile = Path.ChangeExtension (testResultFilePath, "xml");
|
||||
var testReporterFactory = new Mock<ITestReporterFactory> ();
|
||||
var testReporter = new Mock<ITestReporter> ();
|
||||
testReporterFactory.Setup (f => f.Create (
|
||||
testReporterFactory
|
||||
.Setup (f => f.Create (
|
||||
It.IsAny<IAppRunner> (),
|
||||
It.IsAny<string> (),
|
||||
"Test iPad",
|
||||
It.IsAny<ISimpleListener> (),
|
||||
It.IsAny<ILog> (),
|
||||
It.IsAny<ICrashSnapshotReporter> (),
|
||||
It.IsAny<IResultParser> ())).Returns (testReporter.Object);
|
||||
mainLog.Object,
|
||||
snapshotReporter.Object,
|
||||
It.IsAny<IResultParser> ()))
|
||||
.Returns (testReporter.Object);
|
||||
testReporter.Setup (r => r.Timeout).Returns (TimeSpan.FromMinutes (harness.Timeout * 2));
|
||||
testReporter.Setup (r => r.TimeoutWatch).Returns (new System.Diagnostics.Stopwatch ());
|
||||
testReporter.Setup (r => r.ParseResult ()).Returns (() => {
|
||||
return Task.FromResult<(TestExecutingResult, string)> ((TestExecutingResult.Succeeded, null));
|
||||
});
|
||||
testReporter.Setup (r => r.ParseResult ()).Returns (() => Task.FromResult<(TestExecutingResult, string)> ((TestExecutingResult.Succeeded, null)));
|
||||
testReporter.Setup (r => r.Success).Returns (true);
|
||||
|
||||
// Act
|
||||
|
@ -728,7 +716,7 @@ namespace Xharness.Tests {
|
|||
ips.Append (ipAddresses [i].ToString ());
|
||||
}
|
||||
|
||||
var expectedArgs = $"--sdkroot {StringUtils.FormatArguments (xcodePath)} -v -v -argument=-connection-mode -argument=none " +
|
||||
var expectedArgs = $"-v -v -argument=-connection-mode -argument=none " +
|
||||
$"-argument=-app-arg:-autostart -setenv=NUNIT_AUTOSTART=true -argument=-app-arg:-autoexit " +
|
||||
$"-setenv=NUNIT_AUTOEXIT=true -argument=-app-arg:-enablenetwork -setenv=NUNIT_ENABLE_NETWORK=true " +
|
||||
$"-setenv=DISABLE_SYSTEM_PERMISSION_TESTS=1 -argument=-app-arg:-hostname:{ips} -setenv=NUNIT_HOSTNAME={ips} " +
|
||||
|
@ -738,7 +726,6 @@ namespace Xharness.Tests {
|
|||
|
||||
processManager
|
||||
.Setup (x => x.ExecuteCommandAsync (
|
||||
mlaunchPath,
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine () == expectedArgs),
|
||||
It.IsAny<ILog> (),
|
||||
TimeSpan.FromMinutes (harness.Timeout * 2),
|
||||
|
@ -749,13 +736,15 @@ namespace Xharness.Tests {
|
|||
var xmlResultFile = Path.ChangeExtension (testResultFilePath, "xml");
|
||||
var testReporterFactory = new Mock<ITestReporterFactory> ();
|
||||
var testReporter = new Mock<ITestReporter> ();
|
||||
testReporterFactory.Setup (f => f.Create (
|
||||
testReporterFactory
|
||||
.Setup (f => f.Create (
|
||||
It.IsAny<IAppRunner> (),
|
||||
It.IsAny<string> (),
|
||||
"Test iPad",
|
||||
It.IsAny<ISimpleListener> (),
|
||||
It.IsAny<ILog> (),
|
||||
It.IsAny<ICrashSnapshotReporter> (),
|
||||
It.IsAny<IResultParser> ())).Returns (testReporter.Object);
|
||||
mainLog.Object,
|
||||
snapshotReporter.Object,
|
||||
It.IsAny<IResultParser> ()))
|
||||
.Returns (testReporter.Object);
|
||||
testReporter.Setup (r => r.Timeout).Returns (TimeSpan.FromMinutes (harness.Timeout * 2));
|
||||
testReporter.Setup (r => r.TimeoutWatch).Returns (new System.Diagnostics.Stopwatch ());
|
||||
testReporter.Setup (r => r.ParseResult ()).Returns (() => {
|
||||
|
@ -802,11 +791,8 @@ namespace Xharness.Tests {
|
|||
IHarness GetMockedHarness ()
|
||||
{
|
||||
return Mock.Of<IHarness> (x => x.Action == HarnessAction.Run
|
||||
&& x.XcodeRoot == xcodePath
|
||||
&& x.MlaunchPath == mlaunchPath
|
||||
&& x.Verbosity == 1
|
||||
&& x.HarnessLog == mainLog.Object
|
||||
&& x.LogDirectory == logs.Object.Directory
|
||||
&& x.InCI == false
|
||||
&& x.EnvironmentVariables == new Dictionary<string, string> () {
|
||||
{ "env1", "value1" },
|
||||
|
|
|
@ -12,8 +12,8 @@ using Xharness.Utilities;
|
|||
|
||||
namespace Xharness.Tests {
|
||||
[TestFixture]
|
||||
public class CrashSnapshotReporterTests {
|
||||
readonly string mlaunchPath = "./mlaunch";
|
||||
public class CrashReportSnapshotTests {
|
||||
|
||||
string tempXcodeRoot;
|
||||
string symbolicatePath;
|
||||
|
||||
|
@ -31,6 +31,9 @@ namespace Xharness.Tests {
|
|||
tempXcodeRoot = Path.Combine (Path.GetTempPath (), Guid.NewGuid ().ToString ());
|
||||
symbolicatePath = Path.Combine (tempXcodeRoot, "Contents", "SharedFrameworks", "DTDeviceKitBase.framework", "Versions", "A", "Resources");
|
||||
|
||||
processManager.SetupGet (x => x.XcodeRoot).Returns (tempXcodeRoot);
|
||||
processManager.SetupGet (x => x.MlaunchPath).Returns ("/var/bin/mlaunch");
|
||||
|
||||
// Create fake place for device logs
|
||||
Directory.CreateDirectory (tempXcodeRoot);
|
||||
|
||||
|
@ -71,8 +74,6 @@ namespace Xharness.Tests {
|
|||
var snapshotReport = new CrashSnapshotReporter (processManager.Object,
|
||||
log.Object,
|
||||
logs.Object,
|
||||
tempXcodeRoot,
|
||||
mlaunchPath,
|
||||
true,
|
||||
deviceName,
|
||||
() => tempFilePath);
|
||||
|
@ -91,10 +92,9 @@ namespace Xharness.Tests {
|
|||
// List of crash reports is retrieved
|
||||
processManager.Verify (
|
||||
x => x.ExecuteCommandAsync (
|
||||
mlaunchPath,
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine () ==
|
||||
StringUtils.FormatArguments ($"--list-crash-reports={tempFilePath}") + " " +
|
||||
$"--sdkroot {StringUtils.FormatArguments (tempXcodeRoot)} " +
|
||||
StringUtils.FormatArguments (
|
||||
$"--list-crash-reports={tempFilePath}") + " " +
|
||||
$"--devname {StringUtils.FormatArguments (deviceName)}"),
|
||||
log.Object,
|
||||
TimeSpan.FromMinutes (1),
|
||||
|
@ -105,11 +105,10 @@ namespace Xharness.Tests {
|
|||
// Device crash log is downloaded
|
||||
processManager.Verify (
|
||||
x => x.ExecuteCommandAsync (
|
||||
mlaunchPath,
|
||||
It.Is<MlaunchArguments> (args => args.AsCommandLine () ==
|
||||
StringUtils.FormatArguments ($"--download-crash-report={deviceName}") + " " +
|
||||
StringUtils.FormatArguments (
|
||||
$"--download-crash-report={deviceName}") + " " +
|
||||
StringUtils.FormatArguments ($"--download-crash-report-to={crashLogPath}") + " " +
|
||||
$"--sdkroot {StringUtils.FormatArguments (tempXcodeRoot)} " +
|
||||
$"--devname {StringUtils.FormatArguments (deviceName)}"),
|
||||
log.Object,
|
||||
TimeSpan.FromMinutes (1),
|
||||
|
|
Загрузка…
Ссылка в новой задаче