diff --git a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Microsoft.DotNet.XHarness.iOS.Shared.csproj b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Microsoft.DotNet.XHarness.iOS.Shared.csproj
index 9a15ed58e6f4..d50bb048ff0c 100644
--- a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Microsoft.DotNet.XHarness.iOS.Shared.csproj
+++ b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Microsoft.DotNet.XHarness.iOS.Shared.csproj
@@ -11,4 +11,7 @@
+
+
+
diff --git a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestImporter/ProjectDefinition.cs b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestImporter/ProjectDefinition.cs
index dd3c157a44e4..7114b773477e 100644
--- a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestImporter/ProjectDefinition.cs
+++ b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestImporter/ProjectDefinition.cs
@@ -4,6 +4,8 @@
using System.Reflection;
using System.Collections.Generic;
+using Mono.Cecil;
+
namespace Microsoft.DotNet.XHarness.iOS.Shared.TestImporter {
///
/// Class that defines a bcl test project. A bcl test project by definition is the combination of the name
@@ -24,6 +26,16 @@ public bool IsXUnit {
}
}
+ Dictionary assemblies = new Dictionary ();
+ AssemblyDefinition LoadAssembly (string path)
+ {
+ lock (assemblies) {
+ if (!assemblies.TryGetValue (path, out var ad))
+ assemblies [path] = ad = AssemblyDefinition.ReadAssembly (path, new ReaderParameters (ReadingMode.Deferred));
+ return ad;
+ }
+ }
+
public ProjectDefinition (string name, IAssemblyLocator locator, ITestAssemblyDefinitionFactory factory, string [] assemblies, string extraArgs)
{
if (assemblies.Length == 0)
@@ -51,12 +63,12 @@ public ProjectDefinition (string name, IAssemblyLocator locator, ITestAssemblyDe
ExtraArgs = extraArgs;
}
- static (string FailureMessage, IEnumerable References) GetAssemblyReferences (string assemblyPath)
+ (string FailureMessage, IEnumerable References) GetAssemblyReferences (string assemblyPath)
{
if (!File.Exists (assemblyPath))
return ($"The file {assemblyPath} does not exist.", null);
- var a = Assembly.LoadFile (assemblyPath);
- return (null, a.GetReferencedAssemblies ().Select ((arg) => arg.Name));
+ var ad = LoadAssembly (assemblyPath);
+ return (null, ad.MainModule.AssemblyReferences.Select ((arg) => arg.Name));
}
///
@@ -97,32 +109,35 @@ public bool Validate ()
return (failureMessage, set);
}
- public (string FailureMessage, Dictionary Types) GetTypeForAssemblies (string monoRootPath, Platform platform)
+ public (string FailureMessage, Dictionary Types) GetTypeForAssemblies (string monoRootPath, Platform platform)
{
if (monoRootPath == null)
throw new ArgumentNullException (nameof (monoRootPath));
- var dict = new Dictionary ();
+ var dict = new Dictionary ();
// loop over the paths, grab the assembly, find a type and then add it
foreach (var definition in TestAssemblies) {
var path = definition.GetPath (platform);
if (!File.Exists (path))
return ($"The assembly {path} does not exist. Please make sure it exists, then re-generate the project files by executing 'git clean -xfd && make' in the tests/ directory.", null);
- var a = Assembly.LoadFile (path);
- try {
- var types = a.ExportedTypes;
- if (!types.Any ()) {
- continue;
- }
- dict [Path.GetFileName (path)] = types.First (t => !t.IsGenericType && (t.FullName.EndsWith ("Test") || t.FullName.EndsWith ("Tests")) && t.Namespace != null);
- } catch (ReflectionTypeLoadException e) { // ReflectionTypeLoadException
- // we did get an exception, possible reason, the type comes from an assebly not loaded, but
- // nevertheless we can do something about it, get all the not null types in the exception
- // and use one of them
- var types = e.Types.Where (t => t != null).Where (t => !t.IsGenericType && (t.FullName.EndsWith ("Test") || t.FullName.EndsWith ("Tests")) && t.Namespace != null);
- if (types.Any ()) {
- dict [Path.GetFileName (path)] = types.First ();
- }
- }
+ var ad = LoadAssembly (path);
+ var accessibleType = ad.MainModule.Types.FirstOrDefault ((t) => {
+ if (!t.IsPublic)
+ return false;
+
+ if (t.HasGenericParameters)
+ return false;
+
+ if (t.Namespace == null)
+ return false;
+
+ if (!t.FullName.EndsWith ("Test", StringComparison.OrdinalIgnoreCase) && !t.FullName.EndsWith ("Tests", StringComparison.OrdinalIgnoreCase))
+ return false;
+
+ return true;
+ });
+ if (accessibleType == null)
+ continue;
+ dict [Path.GetFileName (path)] = accessibleType;
}
return (null, dict);
}
diff --git a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestImporter/Templates/Managed/RegisterTypeGenerator.cs b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestImporter/Templates/Managed/RegisterTypeGenerator.cs
index cffe420d0ff7..ab315fd5950c 100644
--- a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestImporter/Templates/Managed/RegisterTypeGenerator.cs
+++ b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestImporter/Templates/Managed/RegisterTypeGenerator.cs
@@ -4,6 +4,8 @@
using System.Threading.Tasks;
using System.Collections.Generic;
+using Mono.Cecil;
+
namespace Microsoft.DotNet.XHarness.iOS.Shared.TestImporter.Templates.Managed {
public static class RegisterTypeGenerator {
@@ -11,7 +13,7 @@ public static class RegisterTypeGenerator {
static readonly string KeysReplacement = "%KEY VALUES%";
static readonly string IsxUnitReplacement = "%IS XUNIT%";
- public static async Task GenerateCodeAsync ((string FailureMessage, Dictionary Types) typeRegistration, bool isXunit,
+ public static async Task GenerateCodeAsync ((string FailureMessage, Dictionary Types) typeRegistration, bool isXunit,
Stream template)
{
var importStringBuilder = new StringBuilder ();