Xamarin Public Jenkins (auto-signing) 94b2861243 Imported Upstream version 4.8.0.309
Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
2016-11-10 13:04:39 +00:00

328 lines
10 KiB
C#

using System;
using System.IO;
using System.Reflection;
using Mono.Cecil.Cil;
using NUnit.Framework;
using Mono.Cecil.PE;
namespace Mono.Cecil.Tests {
public abstract class BaseTestFixture {
protected static void IgnoreOnMono ()
{
if (Platform.OnMono)
Assert.Ignore ();
}
public static string GetResourcePath (string name, Assembly assembly)
{
return Path.Combine (FindResourcesDirectory (assembly), name);
}
public static string GetAssemblyResourcePath (string name, Assembly assembly)
{
return GetResourcePath (Path.Combine ("assemblies", name), assembly);
}
public static string GetCSharpResourcePath (string name, Assembly assembly)
{
return GetResourcePath (Path.Combine ("cs", name), assembly);
}
public static string GetILResourcePath (string name, Assembly assembly)
{
return GetResourcePath (Path.Combine ("il", name), assembly);
}
public ModuleDefinition GetResourceModule (string name)
{
return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().Assembly));
}
public ModuleDefinition GetResourceModule (string name, ReaderParameters parameters)
{
return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().Assembly), parameters);
}
public ModuleDefinition GetResourceModule (string name, ReadingMode mode)
{
return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, GetType ().Assembly), new ReaderParameters (mode));
}
internal Image GetResourceImage (string name)
{
var file = new FileStream (GetAssemblyResourcePath (name, GetType ().Assembly), FileMode.Open, FileAccess.Read);
return ImageReader.ReadImage (Disposable.Owned (file as Stream), file.Name);
}
public ModuleDefinition GetCurrentModule ()
{
return ModuleDefinition.ReadModule (GetType ().Module.FullyQualifiedName);
}
public ModuleDefinition GetCurrentModule (ReaderParameters parameters)
{
return ModuleDefinition.ReadModule (GetType ().Module.FullyQualifiedName, parameters);
}
public static string FindResourcesDirectory (Assembly assembly)
{
var path = Path.GetDirectoryName (new Uri (assembly.CodeBase).LocalPath);
while (!Directory.Exists (Path.Combine (path, "Resources"))) {
var old = path;
path = Path.GetDirectoryName (path);
Assert.AreNotEqual (old, path);
}
return Path.Combine (path, "Resources");
}
public static void AssertCode (string expected, MethodDefinition method)
{
Assert.IsTrue (method.HasBody);
Assert.IsNotNull (method.Body);
Assert.AreEqual (Normalize (expected), Normalize (Formatter.FormatMethodBody (method)));
}
static string Normalize (string str)
{
return str.Trim ().Replace ("\r\n", "\n");
}
public static void TestModule (string file, Action<ModuleDefinition> test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null, IAssemblyResolver assemblyResolver = null, bool applyWindowsRuntimeProjections = false)
{
Run (new ModuleTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections));
}
public static void TestCSharp (string file, Action<ModuleDefinition> test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null, IAssemblyResolver assemblyResolver = null, bool applyWindowsRuntimeProjections = false)
{
Run (new CSharpTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections));
}
public static void TestIL (string file, Action<ModuleDefinition> test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null, IAssemblyResolver assemblyResolver = null, bool applyWindowsRuntimeProjections = false)
{
Run (new ILTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections));
}
static void Run (TestCase testCase)
{
using (var runner = new TestRunner (testCase, TestCaseType.ReadDeferred))
runner.RunTest ();
using (var runner = new TestRunner (testCase, TestCaseType.ReadImmediate))
runner.RunTest ();
if (testCase.ReadOnly)
return;
using (var runner = new TestRunner (testCase, TestCaseType.WriteFromDeferred))
runner.RunTest ();
using (var runner = new TestRunner (testCase, TestCaseType.WriteFromImmediate))
runner.RunTest ();
}
}
abstract class TestCase {
public readonly bool Verify;
public readonly bool ReadOnly;
public readonly Type SymbolReaderProvider;
public readonly Type SymbolWriterProvider;
public readonly IAssemblyResolver AssemblyResolver;
public readonly Action<ModuleDefinition> Test;
public readonly bool ApplyWindowsRuntimeProjections;
public abstract string ModuleLocation { get; }
protected Assembly Assembly { get { return Test.Method.Module.Assembly; } }
protected TestCase (Action<ModuleDefinition> test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider, IAssemblyResolver assemblyResolver, bool applyWindowsRuntimeProjections)
{
Test = test;
Verify = verify;
ReadOnly = readOnly;
SymbolReaderProvider = symbolReaderProvider;
SymbolWriterProvider = symbolWriterProvider;
AssemblyResolver = assemblyResolver;
ApplyWindowsRuntimeProjections = applyWindowsRuntimeProjections;
}
}
class ModuleTestCase : TestCase {
public readonly string Module;
public ModuleTestCase (string module, Action<ModuleDefinition> test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider, IAssemblyResolver assemblyResolver, bool applyWindowsRuntimeProjections)
: base (test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections)
{
Module = module;
}
public override string ModuleLocation
{
get { return BaseTestFixture.GetAssemblyResourcePath (Module, Assembly); }
}
}
class CSharpTestCase : TestCase {
public readonly string File;
public CSharpTestCase (string file, Action<ModuleDefinition> test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider, IAssemblyResolver assemblyResolver, bool applyWindowsRuntimeProjections)
: base (test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections)
{
File = file;
}
public override string ModuleLocation
{
get
{
return CompilationService.CompileResource (BaseTestFixture.GetCSharpResourcePath (File, Assembly));
}
}
}
class ILTestCase : TestCase {
public readonly string File;
public ILTestCase (string file, Action<ModuleDefinition> test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider, IAssemblyResolver assemblyResolver, bool applyWindowsRuntimeProjections)
: base (test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections)
{
File = file;
}
public override string ModuleLocation
{
get
{
return CompilationService.CompileResource (BaseTestFixture.GetILResourcePath (File, Assembly)); ;
}
}
}
class TestRunner : IDisposable {
readonly TestCase test_case;
readonly TestCaseType type;
ModuleDefinition test_module;
DefaultAssemblyResolver test_resolver;
public TestRunner (TestCase testCase, TestCaseType type)
{
this.test_case = testCase;
this.type = type;
}
ModuleDefinition GetModule ()
{
var location = test_case.ModuleLocation;
var parameters = new ReaderParameters {
SymbolReaderProvider = GetSymbolReaderProvider (),
AssemblyResolver = GetAssemblyResolver (),
ApplyWindowsRuntimeProjections = test_case.ApplyWindowsRuntimeProjections
};
switch (type) {
case TestCaseType.ReadImmediate:
parameters.ReadingMode = ReadingMode.Immediate;
return ModuleDefinition.ReadModule (location, parameters);
case TestCaseType.ReadDeferred:
parameters.ReadingMode = ReadingMode.Deferred;
return ModuleDefinition.ReadModule (location, parameters);
case TestCaseType.WriteFromImmediate:
parameters.ReadingMode = ReadingMode.Immediate;
return RoundTrip (location, parameters, "cecil-irt");
case TestCaseType.WriteFromDeferred:
parameters.ReadingMode = ReadingMode.Deferred;
return RoundTrip (location, parameters, "cecil-drt");
default:
return null;
}
}
ISymbolReaderProvider GetSymbolReaderProvider ()
{
if (test_case.SymbolReaderProvider == null)
return null;
return (ISymbolReaderProvider) Activator.CreateInstance (test_case.SymbolReaderProvider);
}
ISymbolWriterProvider GetSymbolWriterProvider ()
{
if (test_case.SymbolReaderProvider == null)
return null;
return (ISymbolWriterProvider) Activator.CreateInstance (test_case.SymbolWriterProvider);
}
IAssemblyResolver GetAssemblyResolver ()
{
if (test_case.AssemblyResolver != null)
return test_case.AssemblyResolver;
test_resolver = new DefaultAssemblyResolver ();
var directory = Path.GetDirectoryName (test_case.ModuleLocation);
test_resolver.AddSearchDirectory (directory);
return test_resolver;
}
ModuleDefinition RoundTrip (string location, ReaderParameters reader_parameters, string folder)
{
var rt_folder = Path.Combine (Path.GetTempPath (), folder);
if (!Directory.Exists (rt_folder))
Directory.CreateDirectory (rt_folder);
var rt_module = Path.Combine (rt_folder, Path.GetFileName (location));
using (var module = ModuleDefinition.ReadModule (location, reader_parameters)) {
var writer_parameters = new WriterParameters {
SymbolWriterProvider = GetSymbolWriterProvider (),
};
test_case.Test (module);
module.Write (rt_module, writer_parameters);
}
if (test_case.Verify)
CompilationService.Verify (rt_module);
return ModuleDefinition.ReadModule (rt_module, reader_parameters);
}
public void RunTest ()
{
var module = GetModule ();
if (module == null)
return;
test_module = module;
test_case.Test (module);
}
public void Dispose ()
{
if (test_module != null)
test_module.Dispose ();
if (test_resolver != null)
test_resolver.Dispose ();
}
}
enum TestCaseType {
ReadImmediate,
ReadDeferred,
WriteFromImmediate,
WriteFromDeferred,
}
}