Skip to content

Commit

Permalink
[Harness] Create IBuildToolTask and use it in the RunTestTask. (#8375)
Browse files Browse the repository at this point in the history
In order to de-couple the RunTestTask from Jenkins, create an interface
to be implemented, which is pass to use as a member (Composition
pattern). In order to do that, do not expose Jenkins as a property of
the interface because it is required just by the base constructor.

Moving the the use an interface meant a lot of small changes that
should have no real effect (the compiler should have caught any possible
issues).
  • Loading branch information
mandel-macaque authored Apr 14, 2020
1 parent 511124f commit dbc89f0
Show file tree
Hide file tree
Showing 16 changed files with 156 additions and 50 deletions.
5 changes: 3 additions & 2 deletions tests/xharness/AppRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.DotNet.XHarness.iOS.Shared;
using Microsoft.DotNet.XHarness.iOS.Shared.Listeners;
using Microsoft.DotNet.XHarness.iOS.Shared.Hardware;
using Xharness.TestTasks;

namespace Xharness {

Expand All @@ -31,7 +32,7 @@ class AppRunner {
readonly TestTarget target;
readonly IHarness harness;
readonly double timeoutMultiplier;
readonly BuildToolTask buildTask;
readonly IBuildToolTask buildTask;

string deviceName;
string companionDeviceName;
Expand Down Expand Up @@ -77,7 +78,7 @@ public AppRunner (IProcessManager processManager,
bool ensureCleanSimulatorState = false,
double timeoutMultiplier = 1,
string variation = null,
BuildToolTask buildTask = null)
IBuildToolTask buildTask = null)
{
if (appBundleInformationParser is null)
throw new ArgumentNullException (nameof (appBundleInformationParser));
Expand Down
88 changes: 67 additions & 21 deletions tests/xharness/Jenkins/Jenkins.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,12 @@ IEnumerable<RunSimulatorTask> CreateRunSimulatorTaskAsync (MSBuildTask buildTask

for (int i = 0; i < targets.Length; i++) {
var sims = simulators.SelectDevices (targets [i], SimulatorLoadLog, false);
runtasks.Add (new RunSimulatorTask (simulators, buildTask, processManager, sims) {
runtasks.Add (new RunSimulatorTask (
jenkins: this,
simulators: simulators,
buildTask: buildTask,
processManager: processManager,
candidates: sims) {
Platform = platforms [i],
Ignored = ignored[i] || buildTask.Ignored
});
Expand Down Expand Up @@ -549,7 +554,12 @@ async Task<IEnumerable<AppleTestTask>> CreateRunSimulatorTasksAsync ()
}

var testVariations = CreateTestVariations (runSimulatorTasks, (buildTask, test, candidates) =>
new RunSimulatorTask (simulators, buildTask, processManager, candidates?.Cast<SimulatorDevice> () ?? test.Candidates)).ToList ();
new RunSimulatorTask (
jenkins: this,
simulators: simulators,
buildTask: buildTask,
processManager: processManager,
candidates: candidates?.Cast<SimulatorDevice> () ?? test.Candidates)).ToList ();

foreach (var tv in testVariations) {
if (!tv.Ignored)
Expand Down Expand Up @@ -587,7 +597,12 @@ Task<IEnumerable<AppleTestTask>> CreateRunDeviceTasksAsync ()
TestName = project.Name,
};
build64.CloneTestProject (project);
projectTasks.Add (new RunDeviceTask (devices, build64, processManager, devices.Connected64BitIOS.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludeiOS64 });
projectTasks.Add (new RunDeviceTask (
jenkins: this,
devices: devices,
buildTask: build64,
processManager: processManager,
candidates: devices.Connected64BitIOS.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludeiOS64 });

var build32 = new MSBuildTask (jenkins: this, testProject: project, processManager: processManager) {
ProjectConfiguration = project.Name != "dont link" ? "Debug32" : "Release32",
Expand All @@ -596,7 +611,12 @@ Task<IEnumerable<AppleTestTask>> CreateRunDeviceTasksAsync ()
TestName = project.Name,
};
build32.CloneTestProject (project);
projectTasks.Add (new RunDeviceTask (devices, build32, processManager, devices.Connected32BitIOS.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludeiOS32 });
projectTasks.Add (new RunDeviceTask (
jenkins: this,
devices: devices,
buildTask: build32,
processManager: processManager,
candidates: devices.Connected32BitIOS.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludeiOS32 });

var todayProject = project.AsTodayExtensionProject ();
var buildToday = new MSBuildTask (jenkins: this, testProject: todayProject, processManager: processManager) {
Expand All @@ -606,7 +626,12 @@ Task<IEnumerable<AppleTestTask>> CreateRunDeviceTasksAsync ()
TestName = project.Name,
};
buildToday.CloneTestProject (todayProject);
projectTasks.Add (new RunDeviceTask (devices, buildToday, processManager, devices.Connected64BitIOS.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludeiOSExtensions, BuildOnly = ForceExtensionBuildOnly });
projectTasks.Add (new RunDeviceTask (
jenkins: this,
devices: devices,
buildTask: buildToday,
processManager: processManager,
candidates: devices.Connected64BitIOS.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludeiOSExtensions, BuildOnly = ForceExtensionBuildOnly });
}

if (!project.SkiptvOSVariation) {
Expand All @@ -618,7 +643,12 @@ Task<IEnumerable<AppleTestTask>> CreateRunDeviceTasksAsync ()
TestName = project.Name,
};
buildTV.CloneTestProject (tvOSProject);
projectTasks.Add (new RunDeviceTask (devices, buildTV, processManager, devices.ConnectedTV.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludetvOS });
projectTasks.Add (new RunDeviceTask (
jenkins: this,
devices: devices,
buildTask: buildTV,
processManager: processManager,
candidates: devices.ConnectedTV.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludetvOS });
}

if (!project.SkipwatchOSVariation) {
Expand All @@ -631,7 +661,12 @@ Task<IEnumerable<AppleTestTask>> CreateRunDeviceTasksAsync ()
TestName = project.Name,
};
buildWatch32.CloneTestProject (watchOSProject);
projectTasks.Add (new RunDeviceTask (devices, buildWatch32, processManager, devices.ConnectedWatch) { Ignored = !IncludewatchOS });
projectTasks.Add (new RunDeviceTask (
jenkins: this,
devices: devices,
buildTask: buildWatch32,
processManager: processManager,
candidates: devices.ConnectedWatch) { Ignored = !IncludewatchOS });
}

if (!project.SkipwatchOSARM64_32Variation) {
Expand All @@ -642,7 +677,12 @@ Task<IEnumerable<AppleTestTask>> CreateRunDeviceTasksAsync ()
TestName = project.Name,
};
buildWatch64_32.CloneTestProject (watchOSProject);
projectTasks.Add (new RunDeviceTask (devices, buildWatch64_32, processManager, devices.ConnectedWatch32_64.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludewatchOS });
projectTasks.Add (new RunDeviceTask (
jenkins: this,
devices: devices,
buildTask: buildWatch64_32,
processManager: processManager,
candidates: devices.ConnectedWatch32_64.Where (d => project.IsSupported (d.DevicePlatform, d.ProductVersion))) { Ignored = !IncludewatchOS });
}
}
foreach (var task in projectTasks) {
Expand All @@ -653,7 +693,13 @@ Task<IEnumerable<AppleTestTask>> CreateRunDeviceTasksAsync ()
rv.AddRange (projectTasks);
}

return Task.FromResult<IEnumerable<AppleTestTask>> (CreateTestVariations (rv, (buildTask, test, candidates) => new RunDeviceTask (devices, buildTask, processManager, candidates?.Cast<IHardwareDevice> () ?? test.Candidates)));
return Task.FromResult<IEnumerable<AppleTestTask>> (CreateTestVariations (rv, (buildTask, test, candidates)
=> new RunDeviceTask (
jenkins: this,
devices: devices,
buildTask: buildTask,
processManager: processManager,
candidates: candidates?.Cast<IHardwareDevice> () ?? test.Candidates)));
}

static string AddSuffixToPath (string path, string suffix)
Expand Down Expand Up @@ -942,7 +988,7 @@ Task PopulateTasksAsync ()
SolutionPath = Path.GetFullPath (Path.Combine (Harness.RootDirectory, "..", "msbuild", "Xamarin.MacDev.Tasks.sln")),
SupportsParallelExecution = false,
};
var nunitExecutioniOSMSBuild_net461 = new NUnitExecuteTask (buildiOSMSBuild_net461, processManager)
var nunitExecutioniOSMSBuild_net461 = new NUnitExecuteTask (this, buildiOSMSBuild_net461, processManager)
{
TestLibrary = Path.Combine (Harness.RootDirectory, "..", "msbuild", "tests", "Xamarin.iOS.Tasks.Tests", "bin", "Debug-net461", "net461", "Xamarin.iOS.Tasks.Tests.dll"),
TestProject = net461Project,
Expand All @@ -965,7 +1011,7 @@ Task PopulateTasksAsync ()
SolutionPath = Path.GetFullPath (Path.Combine (Harness.RootDirectory, "..", "msbuild", "Xamarin.MacDev.Tasks.sln")),
SupportsParallelExecution = false,
};
var nunitExecutioniOSMSBuild_netstandard2 = new NUnitExecuteTask (buildiOSMSBuild_netstandard2, processManager) {
var nunitExecutioniOSMSBuild_netstandard2 = new NUnitExecuteTask (this, buildiOSMSBuild_netstandard2, processManager) {
TestLibrary = Path.Combine (Harness.RootDirectory, "..", "msbuild", "tests", "Xamarin.iOS.Tasks.Tests", "bin", "Debug-netstandard2.0", "net461", "Xamarin.iOS.Tasks.Tests.dll"),
TestProject = netstandard2Project,
ProjectConfiguration = "Debug-netstandard2.0",
Expand All @@ -986,7 +1032,7 @@ Task PopulateTasksAsync ()
Platform = TestPlatform.iOS,
};
buildInstallSources.SolutionPath = Path.GetFullPath (Path.Combine (Harness.RootDirectory, "..", "tools", "install-source", "install-source.sln")); // this is required for nuget restore to be executed
var nunitExecutionInstallSource = new NUnitExecuteTask (buildInstallSources, processManager)
var nunitExecutionInstallSource = new NUnitExecuteTask (this, buildInstallSources, processManager)
{
TestLibrary = Path.Combine (Harness.RootDirectory, "..", "tools", "install-source", "InstallSourcesTests", "bin", "Release", "InstallSourcesTests.dll"),
TestProject = installSourcesProject,
Expand Down Expand Up @@ -1042,7 +1088,7 @@ Task PopulateTasksAsync ()
var ignored_main = ignored;
if (project.IsNUnitProject) {
var dll = Path.Combine (Path.GetDirectoryName (build.TestProject.Path), project.Xml.GetOutputAssemblyPath (build.ProjectPlatform, build.ProjectConfiguration).Replace ('\\', '/'));
exec = new NUnitExecuteTask (build, processManager) {
exec = new NUnitExecuteTask (this, build, processManager) {
Ignored = ignored_main,
TestLibrary = dll,
TestProject = project,
Expand All @@ -1053,14 +1099,14 @@ Task PopulateTasksAsync ()
};
execs = new [] { exec };
} else {
exec = new MacExecuteTask (build, processManager, crashReportSnapshotFactory) {
exec = new MacExecuteTask (this, build, processManager, crashReportSnapshotFactory) {
Ignored = ignored_main,
BCLTest = project.IsBclTest,
TestName = project.Name,
IsUnitTest = true,
};
execs = CreateTestVariations (new [] { exec }, (buildTask, test, candidates) =>
new MacExecuteTask (buildTask, processManager, crashReportSnapshotFactory) { IsUnitTest = true } );
new MacExecuteTask (this, buildTask, processManager, crashReportSnapshotFactory) { IsUnitTest = true } );
}

foreach (var e in execs)
Expand All @@ -1079,7 +1125,7 @@ Task PopulateTasksAsync ()
Target = "dependencies",
WorkingDirectory = Path.GetFullPath (Path.Combine (Harness.RootDirectory, "mtouch")),
};
var nunitExecutionMTouch = new NUnitExecuteTask (buildMTouch, processManager)
var nunitExecutionMTouch = new NUnitExecuteTask (this, buildMTouch, processManager)
{
TestLibrary = Path.Combine (Harness.RootDirectory, "mtouch", "bin", "Debug", "mtouch.dll"),
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "mtouch", "mtouch.csproj"))),
Expand All @@ -1099,7 +1145,7 @@ Task PopulateTasksAsync ()
Target = "build-unit-tests",
WorkingDirectory = Path.GetFullPath (Path.Combine (Harness.RootDirectory, "generator")),
};
var runGenerator = new NUnitExecuteTask (buildGenerator, processManager) {
var runGenerator = new NUnitExecuteTask (this, buildGenerator, processManager) {
TestLibrary = Path.Combine (Harness.RootDirectory, "generator", "bin", "Debug", "generator-tests.dll"),
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "generator", "generator-tests.csproj"))),
Platform = TestPlatform.iOS,
Expand All @@ -1117,7 +1163,7 @@ Task PopulateTasksAsync ()
SpecifyConfiguration = false,
Platform = TestPlatform.iOS,
};
var runDotNetGenerator = new DotNetTestTask (buildDotNetGenerator, processManager) {
var runDotNetGenerator = new DotNetTestTask (this, buildDotNetGenerator, processManager) {
TestProject = buildDotNetGeneratorProject,
Platform = TestPlatform.iOS,
TestName = "Generator tests",
Expand Down Expand Up @@ -1163,7 +1209,7 @@ Task PopulateTasksAsync ()
Ignored = !IncludeXtro,
Timeout = TimeSpan.FromMinutes (15),
};
var runXtroReporter = new RunXtroTask (buildXtroTests, processManager, crashReportSnapshotFactory) {
var runXtroReporter = new RunXtroTask (this, buildXtroTests, processManager, crashReportSnapshotFactory) {
Platform = TestPlatform.Mac,
TestName = buildXtroTests.TestName,
Ignored = buildXtroTests.Ignored,
Expand All @@ -1179,7 +1225,7 @@ Task PopulateTasksAsync ()
Ignored = !IncludeCecil,
Timeout = TimeSpan.FromMinutes (5),
};
var runCecilTests = new NUnitExecuteTask (buildCecilTests, processManager) {
var runCecilTests = new NUnitExecuteTask (this, buildCecilTests, processManager) {
TestLibrary = Path.Combine (buildCecilTests.WorkingDirectory, "bin", "Debug", "cecil-tests.dll"),
TestProject = new TestProject (Path.Combine (buildCecilTests.WorkingDirectory, "cecil-tests.csproj")),
Platform = TestPlatform.iOS,
Expand All @@ -1206,7 +1252,7 @@ Task PopulateTasksAsync ()
Platform = TestPlatform.All,
ProjectConfiguration = "Debug",
};
var runSampleTests = new NUnitExecuteTask (buildSampleTests, processManager) {
var runSampleTests = new NUnitExecuteTask (this, buildSampleTests, processManager) {
TestLibrary = Path.Combine (Harness.RootDirectory, "sampletester", "bin", "Debug", "sampletester.dll"),
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "sampletester", "sampletester.csproj"))),
Platform = TestPlatform.All,
Expand Down
5 changes: 3 additions & 2 deletions tests/xharness/Jenkins/TestTasks/BuildToolTask.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;
using System.Threading.Tasks;
using Microsoft.DotNet.XHarness.iOS.Shared.Execution;
using Xharness.TestTasks;

namespace Xharness.Jenkins.TestTasks
{
public abstract class BuildToolTask : AppleTestTask
public abstract class BuildToolTask : AppleTestTask, IBuildToolTask
{
protected Xharness.TestTasks.BuildTool buildToolTask;
protected BuildTool buildToolTask;

public IProcessManager ProcessManager { get; }

Expand Down
4 changes: 2 additions & 2 deletions tests/xharness/Jenkins/TestTasks/DotNetTestTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

namespace Xharness.Jenkins.TestTasks {
class DotNetTestTask : RunTestTask {
public DotNetTestTask (DotNetBuildTask build_task, IProcessManager processManager)
: base (build_task, processManager)
public DotNetTestTask (Jenkins jenkins, DotNetBuildTask build_task, IProcessManager processManager)
: base (jenkins, build_task, processManager)
{
DotNetBuildTask.SetDotNetEnvironmentVariables (Environment);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/xharness/Jenkins/TestTasks/MacExecuteTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class MacExecuteTask : MacTask
public bool BCLTest;
public bool IsUnitTest;

public MacExecuteTask (BuildToolTask build_task, IProcessManager processManager, ICrashSnapshotReporterFactory crashReportSnapshotFactory)
: base (build_task, processManager)
public MacExecuteTask (Jenkins jenkins, BuildToolTask build_task, IProcessManager processManager, ICrashSnapshotReporterFactory crashReportSnapshotFactory)
: base (jenkins, build_task, processManager)
{
this.CrashReportSnapshotFactory = crashReportSnapshotFactory ?? throw new ArgumentNullException (nameof (crashReportSnapshotFactory));
}
Expand Down
4 changes: 2 additions & 2 deletions tests/xharness/Jenkins/TestTasks/MacTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ namespace Xharness.Jenkins.TestTasks
{
abstract class MacTask : RunTestTask
{
public MacTask (BuildToolTask build_task, IProcessManager processManager)
: base (build_task, processManager)
public MacTask (Jenkins jenkins, BuildToolTask build_task, IProcessManager processManager)
: base (jenkins, build_task, processManager)
{
}

Expand Down
4 changes: 2 additions & 2 deletions tests/xharness/Jenkins/TestTasks/NUnitExecuteTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class NUnitExecuteTask : RunTestTask
public bool ProduceHtmlReport = true;
public bool InProcess;

public NUnitExecuteTask (BuildToolTask build_task, IProcessManager processManager)
: base (build_task, processManager)
public NUnitExecuteTask (Jenkins jenkins, BuildToolTask build_task, IProcessManager processManager)
: base (jenkins, build_task, processManager)
{
}

Expand Down
6 changes: 3 additions & 3 deletions tests/xharness/Jenkins/TestTasks/RunDeviceTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ public override string ProgressMessage {
}
}

public RunDeviceTask (IHardwareDeviceLoader devices, MSBuildTask build_task, IProcessManager ProcessManager, IEnumerable<IHardwareDevice> candidates)
: base (build_task, ProcessManager, candidates.OrderBy ((v) => v.DebugSpeed))
public RunDeviceTask (Jenkins jenkins, IHardwareDeviceLoader devices, MSBuildTask buildTask, IProcessManager processManager, IEnumerable<IHardwareDevice> candidates)
: base (jenkins, buildTask, processManager, candidates.OrderBy ((v) => v.DebugSpeed))
{
switch (build_task.Platform) {
switch (buildTask.Platform) {
case TestPlatform.iOS:
case TestPlatform.iOS_Unified:
case TestPlatform.iOS_Unified32:
Expand Down
8 changes: 5 additions & 3 deletions tests/xharness/Jenkins/TestTasks/RunSimulatorTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public ISimulatorDevice [] Simulators {
}
}

public RunSimulatorTask (ISimulatorLoader simulators, MSBuildTask build_task, IProcessManager ProcessManager, IEnumerable<ISimulatorDevice> candidates = null)
: base (build_task, ProcessManager, candidates)
public RunSimulatorTask (Jenkins jenkins, ISimulatorLoader simulators, MSBuildTask buildTask, IProcessManager processManager, IEnumerable<ISimulatorDevice> candidates = null)
: base (jenkins, buildTask, processManager, candidates)
{
var project = Path.GetFileNameWithoutExtension (ProjectFile);
if (project.EndsWith ("-tvos", StringComparison.Ordinal)) {
Expand Down Expand Up @@ -127,8 +127,10 @@ protected override async Task RunTestAsync ()
ExecutionResult = runner.Result;

KnownFailure = null;
if (Jenkins.IsKnownTestIssue (runner.MainLog, out KnownFailure))
if (Jenkins.IsKnownTestIssue (runner.MainLog, out var failure)) {
KnownFailure = failure;
Jenkins.MainLog.WriteLine ($"Test run has a known failure: '{KnownFailure}'");
}
}

protected override string XIMode {
Expand Down
5 changes: 3 additions & 2 deletions tests/xharness/Jenkins/TestTasks/RunTestTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@
using Microsoft.DotNet.XHarness.iOS.Shared.Execution;
using Microsoft.DotNet.XHarness.iOS.Shared.Logging;
using Microsoft.DotNet.XHarness.iOS.Shared.Utilities;
using Xharness.TestTasks;

namespace Xharness.Jenkins.TestTasks {
internal abstract class RunTestTask : AppleTestTask
{
protected IProcessManager ProcessManager { get; }
IResultParser ResultParser { get; } = new XmlResultParser ();

public readonly BuildToolTask BuildTask;
public readonly IBuildToolTask BuildTask;
public TimeSpan Timeout = TimeSpan.FromMinutes (10);
public double TimeoutMultiplier { get; set; } = 1;
public string WorkingDirectory;

public RunTestTask (BuildToolTask build_task, IProcessManager processManager) : base (build_task.Jenkins)
public RunTestTask (Jenkins jenkins, IBuildToolTask build_task, IProcessManager processManager) : base (jenkins)
{
this.BuildTask = build_task;
this.ProcessManager = processManager ?? throw new ArgumentNullException (nameof (processManager));
Expand Down
4 changes: 2 additions & 2 deletions tests/xharness/Jenkins/TestTasks/RunXITask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ abstract class RunXITask<TDevice> : RunTestTask where TDevice : class, IDevice

public string BundleIdentifier => runner.AppInformation.BundleIdentifier;

public RunXITask (BuildToolTask build_task, IProcessManager processManager, IEnumerable<TDevice> candidates)
: base (build_task, processManager)
public RunXITask (Jenkins jenkins, BuildToolTask build_task, IProcessManager processManager, IEnumerable<TDevice> candidates)
: base (jenkins, build_task, processManager)
{
this.Candidates = candidates;
}
Expand Down
Loading

1 comment on commit dbc89f0

@xamarin-release-manager
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build was (probably) aborted

🔥 Jenkins job (on internal Jenkins) failed in stage(s) 'Install Provisioning Profiles' 🔥 : hudson.AbortException: script returned exit code 104

Build succeeded
✅ Packages:

Please sign in to comment.