[Harness] Refactor TestProject to be moved to the common lib. (#8388)

Refactor TestProject so that we can move all the tasks to the common
assembly. We had to remove all the references from Harness, that
included the MonoNativeInfo.
This commit is contained in:
Manuel de la Pena 2020-04-16 20:20:53 -04:00
Родитель e24b1f735b
Коммит d4af4e8ae5
14 изменённых файлов: 208 добавлений и 182 удалений

Просмотреть файл

@ -298,7 +298,7 @@ namespace Xharness {
}
foreach (var flavor in new MonoNativeFlavor [] { MonoNativeFlavor.Compat, MonoNativeFlavor.Unified }) {
var monoNativeInfo = new MacMonoNativeInfo (this, flavor);
var monoNativeInfo = new MacMonoNativeInfo (this, flavor, RootDirectory);
var macTestProject = new MacTestProject (monoNativeInfo.ProjectPath, targetFrameworkFlavor: MacFlavors.Modern | MacFlavors.Full) {
MonoNativeInfo = monoNativeInfo,
Name = monoNativeInfo.ProjectName,
@ -404,7 +404,7 @@ namespace Xharness {
IOSTestProjects.Add (new iOSTestProject (Path.GetFullPath (Path.Combine (RootDirectory, "linker", "ios", "link sdk", "link sdk.csproj"))) { Configurations = new string [] { "Debug", "Release" } });
foreach (var flavor in new MonoNativeFlavor [] { MonoNativeFlavor.Compat, MonoNativeFlavor.Unified }) {
var monoNativeInfo = new MonoNativeInfo (this, flavor);
var monoNativeInfo = new MonoNativeInfo (this, flavor, RootDirectory);
var iosTestProject = new iOSTestProject (monoNativeInfo.ProjectPath) {
MonoNativeInfo = monoNativeInfo,
Name = monoNativeInfo.ProjectName,
@ -663,28 +663,6 @@ namespace Xharness {
return jenkins.Run ();
}
public void Save (XmlDocument doc, string path)
{
if (!File.Exists (path)) {
doc.Save (path);
Log (1, "Created {0}", path);
} else {
var tmpPath = path + ".tmp";
doc.Save (tmpPath);
var existing = File.ReadAllText (path);
var updated = File.ReadAllText (tmpPath);
if (existing == updated) {
File.Delete (tmpPath);
Log (1, "Not saved {0}, no change", path);
} else {
File.Delete (path);
File.Move (tmpPath, path);
Log (1, "Updated {0}", path);
}
}
}
public void Save (StringWriter doc, string path)
{
if (!File.Exists (path)) {

Просмотреть файл

@ -246,18 +246,18 @@ namespace Xharness.Jenkins {
if (!project.IsExecutableProject)
return false;
if (project.IsBclTest) {
if (!project.IsBclxUnit)
if (project.IsBclTest ()) {
if (!project.IsBclxUnit ())
return IncludeBcl || IncludeBCLNUnit;
if (project.IsMscorlib)
if (project.IsMscorlib ())
return IncludeMscorlib;
return IncludeBcl || IncludeBCLxUnit;
}
if (!IncludeMonotouch && project.IsMonotouch)
if (!IncludeMonotouch && project.IsMonotouch ())
return false;
if (!IncludeNonMonotouch && !project.IsMonotouch)
if (!IncludeNonMonotouch && !project.IsMonotouch ())
return false;
if (Harness.IncludeSystemPermissionTests == false && project.Name == "introspection")
@ -1105,7 +1105,7 @@ namespace Xharness.Jenkins {
} else {
exec = new MacExecuteTask (this, build, processManager, crashReportSnapshotFactory) {
Ignored = ignored_main,
BCLTest = project.IsBclTest,
BCLTest = project.IsBclTest (),
TestName = project.Name,
IsUnitTest = true,
};

Просмотреть файл

@ -0,0 +1,50 @@
using System;
namespace Xharness {
[Flags]
public enum MacFlavors {
Modern = 1, // Xamarin.Mac/Modern app
Full = 2, // Xamarin.Mac/Full app
System = 4, // Xamarin.Mac/System app
Console = 8, // Console executable
}
public class MacTestProject : TestProject
{
public MacFlavors TargetFrameworkFlavors;
public bool GenerateFull => GenerateVariations && (TargetFrameworkFlavors & MacFlavors.Full) == MacFlavors.Full;
public bool GenerateSystem => GenerateVariations && (TargetFrameworkFlavors & MacFlavors.System) == MacFlavors.System;
public bool GenerateVariations {
get {
// If a bitwise combination of flavors, then we're generating variations
return TargetFrameworkFlavors != MacFlavors.Modern && TargetFrameworkFlavors != MacFlavors.Full && TargetFrameworkFlavors != MacFlavors.System && TargetFrameworkFlavors != MacFlavors.Console;
}
}
public string Platform = "x86";
public MacTestProject () : base ()
{
}
public MacTestProject (string path, bool isExecutableProject = true, MacFlavors targetFrameworkFlavor = MacFlavors.Full | MacFlavors.Modern) : base (path, isExecutableProject)
{
TargetFrameworkFlavors = targetFrameworkFlavor;
}
public override TestProject Clone()
{
var rv = (MacTestProject) base.Clone ();
rv.TargetFrameworkFlavors = TargetFrameworkFlavors;
rv.Platform = Platform;
return rv;
}
public override string ToString ()
{
return base.ToString () + " (" + TargetFrameworkFlavors.ToString () + ")";
}
}
}

Просмотреть файл

@ -143,21 +143,23 @@ namespace Xharness {
public class MonoNativeInfo
{
public Harness Harness { get; }
public IHarness Harness { get; }
public MonoNativeFlavor Flavor { get; }
protected virtual DevicePlatform DevicePlatform { get { return DevicePlatform.iOS; } }
string rootDirectory;
public MonoNativeInfo (Harness harness, MonoNativeFlavor flavor)
public MonoNativeInfo (IHarness harness, MonoNativeFlavor flavor, string rootDirectory)
{
Harness = harness;
Flavor = flavor;
this.Harness = harness ?? throw new ArgumentNullException (nameof (rootDirectory));
this.rootDirectory = rootDirectory ?? throw new ArgumentNullException (nameof (rootDirectory));
this.Flavor = flavor;
}
public string FlavorSuffix => Flavor == MonoNativeFlavor.Compat ? "-compat" : "-unified";
public string ProjectName => "mono-native" + FlavorSuffix;
public string ProjectPath => Path.Combine (Harness.RootDirectory, "mono-native", TemplateName + FlavorSuffix + ".csproj");
public string ProjectPath => Path.Combine (rootDirectory, "mono-native", TemplateName + FlavorSuffix + ".csproj");
string TemplateName => "mono-native" + TemplateSuffix;
public string TemplatePath => Path.Combine (Harness.RootDirectory, "mono-native", TemplateName + ".csproj.template");
public string TemplatePath => Path.Combine (rootDirectory, "mono-native", TemplateName + ".csproj.template");
protected virtual string TemplateSuffix => string.Empty;
public void Convert ()
@ -177,7 +179,7 @@ namespace Xharness {
AddProjectDefines (inputProject);
Harness.Save (inputProject, ProjectPath);
inputProject.Save (ProjectPath, Harness);
}
public void AddProjectDefines (XmlDocument project)
@ -191,7 +193,7 @@ namespace Xharness {
var info_plist = new XmlDocument ();
info_plist.LoadWithoutNetworkAccess (template_info_plist);
SetInfoPListMinimumOSVersion (info_plist, MonoNativeHelper.GetMinimumOSVersion (DevicePlatform, Flavor));
Harness.Save (info_plist, target_plist);
info_plist.Save (target_plist, Harness);
return info_plist;
}
@ -206,8 +208,8 @@ namespace Xharness {
protected override string TemplateSuffix => "-mac";
protected override DevicePlatform DevicePlatform { get { return DevicePlatform.macOS; } }
public MacMonoNativeInfo (Harness harness, MonoNativeFlavor flavor)
: base (harness, flavor)
public MacMonoNativeInfo (Harness harness, MonoNativeFlavor flavor, string rootDirectory)
: base (harness, flavor, rootDirectory)
{
}

Просмотреть файл

@ -121,7 +121,7 @@ namespace Xharness.Targets
{
ProcessProject ();
PostProcessExecutableProject ();
Harness.Save (inputProject, ProjectPath);
inputProject.Save (ProjectPath, Harness);
UpdateInfoPList ();
}
@ -137,7 +137,7 @@ namespace Xharness.Targets
protected void CreateLibraryProject ()
{
ProcessProject ();
Harness.Save (inputProject, ProjectPath);
inputProject.Save (ProjectPath, Harness);
ProjectGuid = inputProject.GetProjectGuid ();
}

Просмотреть файл

@ -68,7 +68,7 @@ namespace Xharness.Targets {
MonoNativeInfo.AddProjectDefines (csproj);
csproj.AddAdditionalDefines ("MONO_NATIVE_TODAY");
}
Harness.Save (csproj, TodayContainerProjectPath);
csproj.Save(TodayContainerProjectPath, Harness);
XmlDocument info_plist = new XmlDocument ();
var target_info_plist = Path.Combine ((IsGeneratedBclTest) ? GeneratedPath : TargetDirectory, $"Info{suffix}.plist");
@ -76,7 +76,7 @@ namespace Xharness.Targets {
info_plist.SetCFBundleIdentifier (BundleIdentifier);
info_plist.SetCFBundleName (Name);
info_plist.SetMinimumOSVersion (GetMinimumOSVersion ("8.0"));
Harness.Save (info_plist, target_info_plist);
info_plist.Save (target_info_plist, Harness);
}
void CreateTodayExtensionProject ()
@ -101,7 +101,7 @@ namespace Xharness.Targets {
csproj.AddAdditionalDefines ("MONO_NATIVE_TODAY");
}
Harness.Save (csproj, TodayExtensionProjectPath);
csproj.Save (TodayExtensionProjectPath, Harness);
TodayExtensionGuid = csproj.GetProjectGuid ();
@ -122,7 +122,7 @@ namespace Xharness.Targets {
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widget-extension</string>
");
Harness.Save (info_plist, target_info_plist);
info_plist.Save (target_info_plist, Harness);
}
protected override void ExecuteInternal ()

Просмотреть файл

@ -138,13 +138,13 @@ namespace Xharness.Targets {
inputProject.FixInfoPListInclude (Suffix);
inputProject.SetExtraLinkerDefs ("extra-linker-defs" + ExtraLinkerDefsSuffix + ".xml");
Harness.Save (inputProject, ProjectPath);
inputProject.Save (ProjectPath, Harness);
XmlDocument info_plist = new XmlDocument ();
var target_info_plist = Path.Combine (TargetDirectory, "Info" + Suffix + ".plist");
info_plist.LoadWithoutNetworkAccess (Path.Combine (TargetDirectory, "Info.plist"));
info_plist.SetMinimumOSVersion (GetMinimumOSVersion (info_plist.GetMinimumOSVersion ()));
Harness.Save (info_plist, target_info_plist);
info_plist.Save (target_info_plist, Harness);
}
}
}

Просмотреть файл

@ -44,7 +44,7 @@ namespace Xharness.Targets {
MonoNativeHelper.AddProjectDefines (csproj, MonoNativeInfo.Flavor);
MonoNativeHelper.RemoveSymlinkMode (csproj);
}
Harness.Save (csproj, WatchOSAppProjectPath);
csproj.Save (WatchOSAppProjectPath, Harness);
XmlDocument info_plist = new XmlDocument ();
var target_info_plist = Path.Combine (TargetDirectory, $"Info{Suffix}-app.plist");
@ -53,7 +53,7 @@ namespace Xharness.Targets {
info_plist.SetPListStringValue ("WKCompanionAppBundleIdentifier", BundleIdentifier);
info_plist.SetPListStringValue ("CFBundleName", Name);
info_plist.SetMinimumOSVersion (GetMinimumOSVersion (info_plist.GetMinimumOSVersion ()));
Harness.Save (info_plist, target_info_plist);
info_plist.Save(target_info_plist, Harness);
}
void CreateWatchOSContainerProject ()
@ -72,7 +72,7 @@ namespace Xharness.Targets {
MonoNativeHelper.AddProjectDefines (csproj, MonoNativeInfo.Flavor);
MonoNativeHelper.RemoveSymlinkMode (csproj);
}
Harness.Save (csproj, WatchOSProjectPath);
csproj.Save (WatchOSProjectPath, Harness);
XmlDocument info_plist = new XmlDocument ();
var target_info_plist = Path.Combine (TargetDirectory, $"Info{Suffix}.plist");
@ -80,7 +80,7 @@ namespace Xharness.Targets {
info_plist.SetCFBundleIdentifier (BundleIdentifier);
info_plist.SetCFBundleName (Name);
info_plist.SetMinimumOSVersion ("9.0");
Harness.Save (info_plist, target_info_plist);
info_plist.Save (target_info_plist, Harness);
}
void CreateWatchOSExtensionProject ()
@ -145,7 +145,7 @@ namespace Xharness.Targets {
csproj.AddExtraMtouchArgs ($"--gcc_flags='{flags}'", "iPhone", c);
}
Harness.Save (csproj, WatchOSExtensionProjectPath);
csproj.Save (WatchOSExtensionProjectPath, Harness);
WatchOSExtensionGuid = csproj.GetProjectGuid ();
@ -176,7 +176,7 @@ namespace Xharness.Targets {
<true/>
");
}
Harness.Save (info_plist, target_info_plist);
info_plist.Save (target_info_plist, Harness);
}
protected override string Imports {
@ -204,7 +204,7 @@ namespace Xharness.Targets {
csproj.FixProjectReferences (Suffix);
csproj.SetExtraLinkerDefs ("extra-linker-defs" + ExtraLinkerDefsSuffix + ".xml");
csproj.FixTestLibrariesReferences (Platform);
Harness.Save (csproj, WatchOSProjectPath);
csproj.Save (WatchOSProjectPath, Harness);
WatchOSGuid = csproj.GetProjectGuid ();
}

Просмотреть файл

@ -30,7 +30,7 @@ namespace Xharness.Targets
BundleIdentifier = info_plist.GetCFBundleIdentifier ();
info_plist.SetMinimumOSVersion (GetMinimumOSVersion (info_plist.GetMinimumOSVersion ()));
info_plist.SetUIDeviceFamily (UIDeviceFamily);
Harness.Save (info_plist, target_info_plist);
info_plist.Save (target_info_plist, Harness);
}
}
}

Просмотреть файл

@ -1,12 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
using Xharness.Jenkins.TestTasks;
using Microsoft.DotNet.XHarness.iOS.Shared.Utilities;
using Microsoft.DotNet.XHarness.iOS.Shared.Hardware;
namespace Xharness {
public class TestProject
@ -40,42 +38,6 @@ namespace Xharness {
IsExecutableProject = isExecutableProject;
}
public TestProject AsTvOSProject ()
{
var clone = Clone ();
clone.Path = System.IO.Path.Combine (System.IO.Path.GetDirectoryName (Path), System.IO.Path.GetFileNameWithoutExtension (Path) + "-tvos" + System.IO.Path.GetExtension (Path));
return clone;
}
public TestProject AsWatchOSProject ()
{
var clone = Clone ();
var fileName = System.IO.Path.GetFileNameWithoutExtension (Path);
clone.Path = System.IO.Path.Combine (System.IO.Path.GetDirectoryName (Path), fileName + (fileName.Contains("-watchos")?"":"-watchos") + System.IO.Path.GetExtension (Path));
return clone;
}
public TestProject AsTodayExtensionProject ()
{
var clone = Clone ();
clone.Path = System.IO.Path.Combine (System.IO.Path.GetDirectoryName (Path), System.IO.Path.GetFileNameWithoutExtension (Path) + "-today" + System.IO.Path.GetExtension (Path));
return clone;
}
// Get the referenced today extension project (if any)
public TestProject GetTodayExtension ()
{
var extensions = Xml.GetExtensionProjectReferences ().ToArray ();
if (!extensions.Any ())
return null;
if (extensions.Count () != 1)
throw new NotImplementedException ();
return new TestProject
{
Path = System.IO.Path.GetFullPath (System.IO.Path.Combine (System.IO.Path.GetDirectoryName (Path), extensions.First ().Replace ('\\', '/'))),
};
}
public XmlDocument Xml {
get {
if (xml == null) {
@ -86,20 +48,6 @@ namespace Xharness {
}
}
public bool IsBclTest {
get {
return Path.Contains ("bcl-test");
}
}
public bool IsMonotouch => Name.Contains ("monotouch");
public bool IsBclxUnit => IsBclTest && (Name.Contains ("xUnit") || IsMscorlib);
public bool IsMscorlib => Name.Contains ("mscorlib");
public virtual TestProject Clone ()
{
TestProject rv = (TestProject) Activator.CreateInstance (GetType ());
@ -159,79 +107,5 @@ namespace Xharness {
}
}
public class iOSTestProject : TestProject
{
public bool SkipiOSVariation;
public bool SkipwatchOSVariation; // skip both
public bool SkipwatchOSARM64_32Variation;
public bool SkipwatchOS32Variation;
public bool SkiptvOSVariation;
public bool BuildOnly;
public iOSTestProject ()
{
}
public iOSTestProject (string path, bool isExecutableProject = true)
: base (path, isExecutableProject)
{
Name = System.IO.Path.GetFileNameWithoutExtension (path);
}
public bool IsSupported (DevicePlatform devicePlatform, string productVersion)
{
if (MonoNativeInfo == null)
return true;
var min_version = MonoNativeHelper.GetMinimumOSVersion (devicePlatform, MonoNativeInfo.Flavor);
return Version.Parse (productVersion) >= Version.Parse (min_version);
}
}
[Flags]
public enum MacFlavors {
Modern = 1, // Xamarin.Mac/Modern app
Full = 2, // Xamarin.Mac/Full app
System = 4, // Xamarin.Mac/System app
Console = 8, // Console executable
}
public class MacTestProject : TestProject
{
public MacFlavors TargetFrameworkFlavors;
public bool GenerateFull => GenerateVariations && (TargetFrameworkFlavors & MacFlavors.Full) == MacFlavors.Full;
public bool GenerateSystem => GenerateVariations && (TargetFrameworkFlavors & MacFlavors.System) == MacFlavors.System;
public bool GenerateVariations {
get {
// If a bitwise combination of flavors, then we're generating variations
return TargetFrameworkFlavors != MacFlavors.Modern && TargetFrameworkFlavors != MacFlavors.Full && TargetFrameworkFlavors != MacFlavors.System && TargetFrameworkFlavors != MacFlavors.Console;
}
}
public string Platform = "x86";
public MacTestProject () : base ()
{
}
public MacTestProject (string path, bool isExecutableProject = true, MacFlavors targetFrameworkFlavor = MacFlavors.Full | MacFlavors.Modern) : base (path, isExecutableProject)
{
TargetFrameworkFlavors = targetFrameworkFlavor;
}
public override TestProject Clone()
{
var rv = (MacTestProject) base.Clone ();
rv.TargetFrameworkFlavors = TargetFrameworkFlavors;
rv.Platform = Platform;
return rv;
}
public override string ToString ()
{
return base.ToString () + " (" + TargetFrameworkFlavors.ToString () + ")";
}
}
}

Просмотреть файл

@ -0,0 +1,55 @@
using System;
using System.IO;
using System.Linq;
using Microsoft.DotNet.XHarness.iOS.Shared.Utilities;
namespace Xharness {
// particular methods used within xamarin-macios
public static class TestProjectExtensions {
public static bool IsBclTest (this TestProject self) => self.Path.Contains ("bcl-test");
public static bool IsMonotouch (this TestProject self) => self.Name.Contains ("monotouch");
public static bool IsBclxUnit (this TestProject self)
=> self.IsBclTest () && (self.Name.Contains ("xUnit") || self.IsMscorlib ());
public static bool IsMscorlib (this TestProject self) => self.Name.Contains ("mscorlib");
public static TestProject AsTvOSProject (this TestProject self)
{
var clone = self.Clone ();
clone.Path = Path.Combine (Path.GetDirectoryName (self.Path), Path.GetFileNameWithoutExtension (self.Path) + "-tvos" + Path.GetExtension (self.Path));
return clone;
}
public static TestProject AsWatchOSProject (this TestProject self)
{
var clone = self.Clone ();
var fileName = Path.GetFileNameWithoutExtension (self.Path);
clone.Path = Path.Combine (Path.GetDirectoryName (self.Path), fileName + (fileName.Contains("-watchos")?"":"-watchos") + Path.GetExtension (self.Path));
return clone;
}
public static TestProject AsTodayExtensionProject (this TestProject self)
{
var clone = self.Clone ();
clone.Path = Path.Combine (Path.GetDirectoryName (self.Path), Path.GetFileNameWithoutExtension (self.Path) + "-today" + Path.GetExtension (self.Path));
return clone;
}
// Get the referenced today extension project (if any)
public static TestProject GetTodayExtension (this TestProject self)
{
var extensions = self.Xml.GetExtensionProjectReferences ().ToArray ();
if (!extensions.Any ())
return null;
if (extensions.Count () != 1)
throw new NotImplementedException ();
return new TestProject
{
Path = Path.GetFullPath (Path.Combine (Path.GetDirectoryName (self.Path), extensions.First ().Replace ('\\', '/'))),
};
}
}
}

Просмотреть файл

@ -0,0 +1,30 @@
using System;
using System.IO;
using System.Xml;
namespace Xharness {
public static class XmlDocumentExtensions {
public static void Save (this XmlDocument doc, string path, IHarness harness)
{
if (!File.Exists (path)) {
doc.Save (path);
harness.Log (1, "Created {0}", path);
} else {
var tmpPath = path + ".tmp";
doc.Save (tmpPath);
var existing = File.ReadAllText (path);
var updated = File.ReadAllText (tmpPath);
if (existing == updated) {
File.Delete (tmpPath);
harness.Log (1, "Not saved {0}, no change", path);
} else {
File.Delete (path);
File.Move (tmpPath, path);
harness.Log (1, "Updated {0}", path);
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,33 @@
using System;
using Microsoft.DotNet.XHarness.iOS.Shared.Hardware;
namespace Xharness {
public class iOSTestProject : TestProject
{
public bool SkipiOSVariation;
public bool SkipwatchOSVariation; // skip both
public bool SkipwatchOSARM64_32Variation;
public bool SkipwatchOS32Variation;
public bool SkiptvOSVariation;
public bool BuildOnly;
public iOSTestProject ()
{
}
public iOSTestProject (string path, bool isExecutableProject = true)
: base (path, isExecutableProject)
{
Name = System.IO.Path.GetFileNameWithoutExtension (path);
}
public bool IsSupported (DevicePlatform devicePlatform, string productVersion)
{
if (MonoNativeInfo == null)
return true;
var min_version = MonoNativeHelper.GetMinimumOSVersion (devicePlatform, MonoNativeInfo.Flavor);
return Version.Parse (productVersion) >= Version.Parse (min_version);
}
}
}

Просмотреть файл

@ -134,6 +134,10 @@
<Compile Include="TestTasks\IRunXITask.cs" />
<Compile Include="TestTasks\IRunSimulatorTask.cs" />
<Compile Include="TestTasks\RunDevice.cs" />
<Compile Include="TestProjectExtensions.cs" />
<Compile Include="iOSTestProject.cs" />
<Compile Include="MacTestProject.cs" />
<Compile Include="XmlDocumentExtensions.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\tools\mtouch\SdkVersions.cs">