зеркало из
1
0
Форкнуть 0

Replace use of ReflectionOnlyLoad as well as AssemblyReader class by using mono.cecil.

This commit is contained in:
Charlie Poole 2015-08-05 16:29:04 -07:00
Родитель 12d688830e
Коммит 6671ba59de
16 изменённых файлов: 120 добавлений и 440 удалений

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

@ -134,6 +134,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.framework.tests-porta
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunitlite.runner-portable", "src\NUnitFramework\nunitlite.runner\nunitlite.runner-portable.csproj", "{D339BFC2-AF3F-46FA-899A-14BAD4BCA35B}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunitlite.runner-portable", "src\NUnitFramework\nunitlite.runner\nunitlite.runner-portable.csproj", "{D339BFC2-AF3F-46FA-899A-14BAD4BCA35B}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "targets", "targets", "{2821D6DA-4F95-4002-BC35-00E8B7F9961A}"
ProjectSection(SolutionItems) = preProject
targets\Build.Targets = targets\Build.Targets
targets\Common.Properties = targets\Common.Properties
targets\Packaging.Targets = targets\Packaging.Targets
targets\Testing.Targets = targets\Testing.Targets
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -354,6 +362,7 @@ Global
{A4F0C741-6ED4-46C8-AE75-57E1C7197E22} = {A21BFC37-44FC-41A0-B6E7-6F949F45A635} {A4F0C741-6ED4-46C8-AE75-57E1C7197E22} = {A21BFC37-44FC-41A0-B6E7-6F949F45A635}
{C4D16DF1-B6FA-42F5-834E-B01DA1BAA1FF} = {A21BFC37-44FC-41A0-B6E7-6F949F45A635} {C4D16DF1-B6FA-42F5-834E-B01DA1BAA1FF} = {A21BFC37-44FC-41A0-B6E7-6F949F45A635}
{A972031D-2F61-4183-AF75-99EE1A9F6B32} = {49D441DF-39FD-4F4D-AECA-86CF8EFE23AF} {A972031D-2F61-4183-AF75-99EE1A9F6B32} = {49D441DF-39FD-4F4D-AECA-86CF8EFE23AF}
{2821D6DA-4F95-4002-BC35-00E8B7F9961A} = {49D441DF-39FD-4F4D-AECA-86CF8EFE23AF}
{775FAD50-3623-4922-97C4-DFB29A8BE4C7} = {31B45C4C-206F-4F31-9CC6-33BF11DFEE39} {775FAD50-3623-4922-97C4-DFB29A8BE4C7} = {31B45C4C-206F-4F31-9CC6-33BF11DFEE39}
{372A3447-D657-40FF-A089-77C19FEC30C8} = {31B45C4C-206F-4F31-9CC6-33BF11DFEE39} {372A3447-D657-40FF-A089-77C19FEC30C8} = {31B45C4C-206F-4F31-9CC6-33BF11DFEE39}
{D694CB69-6CFB-4762-86C2-EB27B808B282} = {31B45C4C-206F-4F31-9CC6-33BF11DFEE39} {D694CB69-6CFB-4762-86C2-EB27B808B282} = {31B45C4C-206F-4F31-9CC6-33BF11DFEE39}

Двоичные данные
packages/Mono.Cecil.0.9.6.1/Mono.Cecil.0.9.6.1.nupkg поставляемый Normal file

Двоичный файл не отображается.

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

@ -4,6 +4,8 @@
<repository path="../src/NUnitFramework/tests/packages.config" /> <repository path="../src/NUnitFramework/tests/packages.config" />
<repository path="..\src\NUnitEngine\Addins\nunit.v2.driver.tests\packages.config" /> <repository path="..\src\NUnitEngine\Addins\nunit.v2.driver.tests\packages.config" />
<repository path="..\src\NUnitEngine\mock-v2-assembly\packages.config" /> <repository path="..\src\NUnitEngine\mock-v2-assembly\packages.config" />
<repository path="..\src\NUnitEngine\nunit.core.engine\packages.config" />
<repository path="..\src\NUnitEngine\nunit.engine\packages.config" />
<repository path="..\src\NUnitEngine\nunit.v2.driver.tests\packages.config" /> <repository path="..\src\NUnitEngine\nunit.v2.driver.tests\packages.config" />
<repository path="..\src\NUnitFramework\testdata\packages.config" /> <repository path="..\src\NUnitFramework\testdata\packages.config" />
<repository path="..\src\NUnitFramework\tests\packages.config" /> <repository path="..\src\NUnitFramework\tests\packages.config" />

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

@ -34,13 +34,13 @@ namespace NUnit.Engine.Drivers
private const string NUNITLITE_FRAMEWORK = "nunitlite"; private const string NUNITLITE_FRAMEWORK = "nunitlite";
/// <summary> /// <summary>
/// Gets a flag indicating whether a given AssemblyName /// Gets a flag indicating whether a given assembly name and version
/// represents a test framework supported by this factory. /// represent a test framework supported by this factory.
/// </summary> /// </summary>
public bool IsSupportedFramework(AssemblyName reference) public bool IsSupportedTestFramework(string assemblyName, Version version)
{ {
return reference.Name == NUNIT_FRAMEWORK && reference.Version.Major == 2 return assemblyName == NUNIT_FRAMEWORK && version.Major == 2
|| reference.Name == NUNITLITE_FRAMEWORK && reference.Version.Major == 1; || assemblyName == NUNITLITE_FRAMEWORK && version.Major == 1;
} }
/// <summary> /// <summary>
@ -48,11 +48,12 @@ namespace NUnit.Engine.Drivers
/// which the assembly is already known to reference. /// which the assembly is already known to reference.
/// </summary> /// </summary>
/// <param name="domain">The domain in which the assembly will be loaded</param> /// <param name="domain">The domain in which the assembly will be loaded</param>
/// <param name="frameworkReference">The name of the test framework reference</param> /// <param name="assemblyName">The name of the test framework reference</param>
/// <param name="version">The version of the test framework reference</param>
/// <returns></returns> /// <returns></returns>
public IFrameworkDriver GetDriver(AppDomain domain, AssemblyName frameworkReference) public IFrameworkDriver GetDriver(AppDomain domain, string assemblyName, Version version)
{ {
if (!IsSupportedFramework(frameworkReference)) if (!IsSupportedTestFramework(assemblyName, version))
throw new ArgumentException("Invalid framework name", "frameworkAssemblyName"); throw new ArgumentException("Invalid framework name", "frameworkAssemblyName");
return new NUnit2FrameworkDriver(domain); return new NUnit2FrameworkDriver(domain);

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

@ -39,6 +39,18 @@
<NoWarn>1685</NoWarn> <NoWarn>1685</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\packages\Mono.Cecil.0.9.6.1\lib\net20\Mono.Cecil.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\packages\Mono.Cecil.0.9.6.1\lib\net20\Mono.Cecil.Mdb.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\packages\Mono.Cecil.0.9.6.1\lib\net20\Mono.Cecil.Pdb.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
@ -202,6 +214,9 @@
<Folder Include="Agents\" /> <Folder Include="Agents\" />
<Folder Include="Services\ResultWriters\" /> <Folder Include="Services\ResultWriters\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

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

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Mono.Cecil" version="0.9.6.1" targetFramework="net20" />
</packages>

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

@ -32,18 +32,19 @@ namespace NUnit.Engine.Extensibility
public interface IDriverFactory public interface IDriverFactory
{ {
/// <summary> /// <summary>
/// Gets a flag indicating whether a given AssemblyName /// Gets a flag indicating whether a given assembly name and version
/// represents a test framework supported by this factory. /// represent a test framework supported by this factory.
/// </summary> /// </summary>
bool IsSupportedFramework(AssemblyName refAssembly); bool IsSupportedTestFramework(string assemblyName, Version version);
/// <summary> /// <summary>
/// Gets a driver for a given test assembly and a framework /// Gets a driver for a given test assembly and a framework
/// which the assembly is already known to reference. /// which the assembly is already known to reference.
/// </summary> /// </summary>
/// <param name="domain">The domain in which the assembly will be loaded</param> /// <param name="domain">The domain in which the assembly will be loaded</param>
/// <param name="frameworkReference">The AssemblyName of the test framework reference</param> /// <param name="assemblyName">The Name of the test framework reference</param>
/// <param name="version">The version of the test framework reference</param>
/// <returns></returns> /// <returns></returns>
IFrameworkDriver GetDriver(AppDomain domain, AssemblyName frameworkReference); IFrameworkDriver GetDriver(AppDomain domain, string assemblyName, Version version);
} }
} }

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

@ -1,130 +0,0 @@
// ***********************************************************************
// Copyright (c) 2011 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using NUnit.Framework;
using System.IO;
namespace NUnit.Engine.Internal.Tests
{
[TestFixture]
public class AssemblyReaderTests
{
private AssemblyReader rdr;
[SetUp]
public void CreateReader()
{
rdr = new AssemblyReader( this.GetType().Assembly );
}
[TearDown]
public void DisposeReader()
{
if ( rdr != null )
rdr.Dispose();
rdr = null;
}
[Test]
public void CreateFromPath()
{
string path = AssemblyHelper.GetAssemblyPath(System.Reflection.Assembly.GetAssembly(GetType()));
Assert.AreEqual(path, new AssemblyReader(path).AssemblyPath);
}
[Test]
public void CreateFromAssembly()
{
string path = AssemblyHelper.GetAssemblyPath(System.Reflection.Assembly.GetAssembly(GetType()));
Assert.AreEqual(path, rdr.AssemblyPath);
}
[Test]
public void IsValidPeFile()
{
Assert.IsTrue(rdr.IsValidPeFile);
}
[Test]
public void IsValidPeFile_Fails()
{
string path = AssemblyHelper.GetAssemblyPath(System.Reflection.Assembly.GetAssembly(GetType()));
path = Path.Combine(Path.GetDirectoryName(path), "nunit.engine.api.xml");
Assert.IsFalse(new AssemblyReader(path).IsValidPeFile);
}
[Test]
public void IsDotNetFile()
{
Assert.IsTrue( rdr.IsDotNetFile );
}
[Test]
public void ImageRuntimeVersion()
{
string runtimeVersion = rdr.ImageRuntimeVersion;
StringAssert.StartsWith( "v", runtimeVersion );
new Version( runtimeVersion.Substring( 1 ) );
// This fails when we force running under a prior version
// Assert.LessOrEqual( version, Environment.Version );
}
[Test]
public void ShouldRun32BitAnyCpuCSharpAssembly()
{
string path = AssemblyHelper.GetAssemblyPath(System.Reflection.Assembly.GetAssembly(GetType()));
path = Path.Combine(Path.GetDirectoryName(path), "nunit-agent.exe");
Assert.That(new AssemblyReader(path).ShouldRun32Bit, Is.False);
}
[Test]
public void ShouldRun32Bit32BitCSharpAssembly()
{
string path = AssemblyHelper.GetAssemblyPath(System.Reflection.Assembly.GetAssembly(GetType()));
path = Path.Combine(Path.GetDirectoryName(path), "nunit-agent-x86.exe");
Assert.That(new AssemblyReader(path).ShouldRun32Bit, Is.True);
}
[Ignore("This test started failing on AppVeyor for no apparent reason. Ignoring until we figure out why.")]
[Test]
public void ShouldRun32Bit64BitCppAssembly()
{
string path = AssemblyHelper.GetAssemblyPath(System.Reflection.Assembly.GetAssembly(GetType()));
path = Path.Combine(Path.GetDirectoryName(path), "mock-cpp-clr-x64.dll");
Assume.That(path, Does.Exist);
Assert.That(new AssemblyReader(path).ShouldRun32Bit, Is.False);
}
[Test]
public void ShouldRun32Bit32BitCppAssembly()
{
string path = AssemblyHelper.GetAssemblyPath(System.Reflection.Assembly.GetAssembly(GetType()));
path = Path.Combine(Path.GetDirectoryName(path), "mock-cpp-clr-x86.dll");
Assume.That(path, Does.Exist);
Assert.That(new AssemblyReader(path).ShouldRun32Bit, Is.True);
}
}
}

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

@ -41,10 +41,37 @@ namespace NUnit.Engine.Services.Tests
services.ServiceManager.StartServices(); services.ServiceManager.StartServices();
} }
[TearDown]
public void StopService()
{
_runtimeService.StopService();
}
[Test] [Test]
public void ServiceIsStarted() public void ServiceIsStarted()
{ {
Assert.That(_runtimeService.Status, Is.EqualTo(ServiceStatus.Started)); Assert.That(_runtimeService.Status, Is.EqualTo(ServiceStatus.Started));
} }
[TestCase("mock-nunit-assembly.exe", "net-2.0", false)]
[TestCase("net-2.0/mock-nunit-assembly.exe", "net-2.0", false)]
[TestCase("net-4.0/mock-nunit-assembly.exe", "net-4.0", false)]
// TODO: Change this case when the 4.0/4.5 bug is fixed
[TestCase("net-4.5/mock-nunit-assembly.exe", "net-4.0", false)]
[TestCase("mock-cpp-clr-x64.dll", "net-4.0", false)]
[TestCase("mock-cpp-clr-x86.dll", "net-4.0", true)]
[TestCase("nunit-agent.exe", "net-2.0", false)]
[TestCase("nunit-agent-x86.exe", "net-2.0", true)]
// TODO: Make the following cases work correctly in case we want to use
// the engine to run them in the future.
[TestCase("netcf-3.5/mock-nunit-assembly.exe", "net-2.0", false)]
[TestCase("sl-5.0/mock-nunit-assembly.dll", "net-4.0", false)]
[TestCase("portable/mock-nunit-assembly.dll", "net-4.0", false)]
public void SelectRuntimeFramework(string assemblyName, string expectedRuntime, bool runAsX86)
{
var package = new TestPackage(assemblyName);
Assert.That(_runtimeService.SelectRuntimeFramework(package), Is.EqualTo(expectedRuntime));
Assert.That(package.GetSetting("RunAsX86", false), Is.EqualTo(runAsX86));
}
} }
} }

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

@ -63,7 +63,6 @@
<Compile Include="Api\TestFilterTests.cs" /> <Compile Include="Api\TestFilterTests.cs" />
<Compile Include="Api\TestPackageTests.cs" /> <Compile Include="Api\TestPackageTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Internal\AssemblyReaderTests.cs" />
<Compile Include="Drivers\NotRunnableFrameworkDriverTests.cs" /> <Compile Include="Drivers\NotRunnableFrameworkDriverTests.cs" />
<Compile Include="Drivers\NUnit3FrameworkDriverTests.cs" /> <Compile Include="Drivers\NUnit3FrameworkDriverTests.cs" />
<Compile Include="Internal\PathUtilTests.cs" /> <Compile Include="Internal\PathUtilTests.cs" />

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

@ -32,12 +32,12 @@ namespace NUnit.Engine.Drivers
private const string NUNIT_FRAMEWORK = "nunit.framework"; private const string NUNIT_FRAMEWORK = "nunit.framework";
/// <summary> /// <summary>
/// Gets a flag indicating whether a given AssemblyName /// Gets a flag indicating whether a given assembly name and version
/// represents a test framework supported by this factory. /// represent a test framework supported by this factory.
/// </summary> /// </summary>
public bool IsSupportedFramework(AssemblyName reference) public bool IsSupportedTestFramework(string assemblyName, Version version)
{ {
return reference.Name == NUNIT_FRAMEWORK && reference.Version.Major == 3; return assemblyName == NUNIT_FRAMEWORK && version.Major == 3;
} }
/// <summary> /// <summary>
@ -45,11 +45,12 @@ namespace NUnit.Engine.Drivers
/// which the assembly is already known to reference. /// which the assembly is already known to reference.
/// </summary> /// </summary>
/// <param name="domain">The domain in which the assembly will be loaded</param> /// <param name="domain">The domain in which the assembly will be loaded</param>
/// <param name="frameworkReference">The AssemblyName of the test framework reference</param> /// <param name="assemblyName">The Name of the test framework reference</param>
/// <param name="version">The version of the test framework reference</param>
/// <returns></returns> /// <returns></returns>
public IFrameworkDriver GetDriver(AppDomain domain, AssemblyName frameworkReference) public IFrameworkDriver GetDriver(AppDomain domain, string assemblyName, Version version)
{ {
Guard.ArgumentValid(IsSupportedFramework(frameworkReference), "Invalid framework name", "frameworkAssemblyName"); Guard.ArgumentValid(IsSupportedTestFramework(assemblyName, version), "Invalid framework name", "frameworkAssemblyName");
return new NUnit3FrameworkDriver(domain); return new NUnit3FrameworkDriver(domain);
} }

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

@ -1,230 +0,0 @@
// ***********************************************************************
// Copyright (c) 2011 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using System.Reflection;
using System.Text;
using System.IO;
namespace NUnit.Engine.Internal
{
/// <summary>
/// AssemblyReader knows how to find various things in an assembly header
/// </summary>
public class AssemblyReader : IDisposable
{
private readonly string assemblyPath;
private BinaryReader rdr;
private FileStream fs;
private UInt16 dos_magic = 0xffff;
private UInt32 pe_signature = 0xffffffff;
private UInt16 numberOfSections;
private UInt16 optionalHeaderSize;
private PEType peType;
private UInt32 numDataDirectoryEntries;
private CorFlags corFlags;
private uint peHeader;
private uint fileHeader;
private uint optionalHeader;
private uint dataDirectory;
private uint dataSections;
private struct DataSection
{
public uint VirtualAddress;
public uint VirtualSize;
public uint FileOffset;
};
private enum PEType : ushort
{
PE32 = 0x10b,
PE32Plus = 0x20b
}
[Flags]
private enum CorFlags : uint
{
// CorHdr.h
COMIMAGE_FLAGS_ILONLY = 0x00000001,
COMIMAGE_FLAGS_32BITREQUIRED = 0x00000002,
COMIMAGE_FLAGS_IL_LIBRARY = 0x00000004,
COMIMAGE_FLAGS_STRONGNAMESIGNED = 0x00000008,
COMIMAGE_FLAGS_NATIVE_ENTRYPOINT = 0x00000010,
COMIMAGE_FLAGS_TRACKDEBUGDATA = 0x00010000,
COMIMAGE_FLAGS_32BITPREFERRED = 0x00020000,
}
private DataSection[] sections;
public AssemblyReader( string assemblyPath )
{
this.assemblyPath = assemblyPath;
CalcHeaderOffsets();
}
public AssemblyReader( Assembly assembly )
{
this.assemblyPath = AssemblyHelper.GetAssemblyPath( assembly );
CalcHeaderOffsets();
}
private void CalcHeaderOffsets()
{
this.fs = new FileStream( assemblyPath, FileMode.Open, FileAccess.Read );
this.rdr = new BinaryReader( fs );
dos_magic = rdr.ReadUInt16();
if ( dos_magic == 0x5a4d )
{
fs.Position = 0x3c;
peHeader = rdr.ReadUInt32();
fileHeader = peHeader + 4;
optionalHeader = fileHeader + 20;
fs.Position = optionalHeader;
peType = (PEType)rdr.ReadUInt16();
dataDirectory = peType == PEType.PE32Plus
? optionalHeader + 112
: optionalHeader + 96;
fs.Position = dataDirectory - 4;
numDataDirectoryEntries = rdr.ReadUInt32();
fs.Position = peHeader;
pe_signature = rdr.ReadUInt32();
rdr.ReadUInt16(); // machine
numberOfSections = rdr.ReadUInt16();
fs.Position += 12;
optionalHeaderSize = rdr.ReadUInt16();
dataSections = optionalHeader + optionalHeaderSize;
sections = new DataSection[numberOfSections];
fs.Position = dataSections;
for( int i = 0; i < numberOfSections; i++ )
{
fs.Position += 8;
sections[i].VirtualSize = rdr.ReadUInt32();
sections[i].VirtualAddress = rdr.ReadUInt32();
uint rawDataSize = rdr.ReadUInt32();
sections[i].FileOffset = rdr.ReadUInt32();
if ( sections[i].VirtualSize == 0 )
sections[i].VirtualSize = rawDataSize;
fs.Position += 16;
}
if (IsDotNetFile)
{
uint rva = DataDirectoryRva(14);
if (rva != 0)
{
fs.Position = RvaToLfa(rva) + 8;
uint metadata = rdr.ReadUInt32();
fs.Position = RvaToLfa(metadata);
if (rdr.ReadUInt32() == 0x424a5342)
{
// Copy string representing runtime version
fs.Position += 12;
StringBuilder sb = new StringBuilder();
char c;
while ((c = rdr.ReadChar()) != '\0')
sb.Append(c);
if (sb[0] == 'v') // Last sanity check
ImageRuntimeVersion = sb.ToString();
// Could do fixups here for bad values in older files
// like 1.x86, 1.build, etc. But we are only using
// the major version anyway
// Jump back and find the CorFlags
fs.Position = RvaToLfa(rva) + 16;
corFlags = (CorFlags)rdr.ReadUInt32();
}
}
}
}
}
private uint DataDirectoryRva( int n )
{
fs.Position = dataDirectory + n * 8;
return rdr.ReadUInt32();
}
private uint RvaToLfa(uint rva)
{
foreach (var section in sections)
if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize)
return rva - section.VirtualAddress + section.FileOffset;
return 0;
}
public string AssemblyPath
{
get { return assemblyPath; }
}
public bool IsValidPeFile
{
get { return dos_magic == 0x5a4d && pe_signature == 0x00004550; }
}
public bool IsDotNetFile
{
get { return IsValidPeFile && numDataDirectoryEntries > 14 && DataDirectoryRva(14) != 0; }
}
/// <summary>
/// Will return true if the assembly is 32 bit, or if it prefers to run 32-bit
/// </summary>
public bool ShouldRun32Bit
{
get
{
// C++/CLI
if ((corFlags & CorFlags.COMIMAGE_FLAGS_NATIVE_ENTRYPOINT) != 0)
return peType != PEType.PE32Plus;
return peType != PEType.PE32Plus && (corFlags & CorFlags.COMIMAGE_FLAGS_32BITREQUIRED) != 0;
}
}
public string ImageRuntimeVersion { get; private set; }
public void Dispose()
{
if ( fs != null )
fs.Close();
if ( rdr != null )
rdr.Close();
fs = null;
rdr = null;
}
}
}

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

@ -25,6 +25,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using Mono.Cecil;
using NUnit.Engine.Drivers; using NUnit.Engine.Drivers;
using NUnit.Engine.Extensibility; using NUnit.Engine.Extensibility;
@ -57,14 +58,14 @@ namespace NUnit.Engine.Services
try try
{ {
var references = GetAssemblyReferences(assemblyPath); var references = AssemblyDefinition.ReadAssembly(assemblyPath).MainModule.AssemblyReferences;
foreach (var factory in _factories) foreach (var factory in _factories)
{ {
foreach (var reference in references) foreach (var reference in references)
{ {
if (factory.IsSupportedFramework(reference)) if (factory.IsSupportedTestFramework(reference.Name, reference.Version))
return factory.GetDriver(domain, reference); return factory.GetDriver(domain, reference.Name, reference.Version);
} }
} }
} }
@ -76,32 +77,6 @@ namespace NUnit.Engine.Services
return new NotRunnableFrameworkDriver(assemblyPath, "Unable to locate a driver for " + assemblyPath); return new NotRunnableFrameworkDriver(assemblyPath, "Unable to locate a driver for " + assemblyPath);
} }
private static AssemblyName[] GetAssemblyReferences(string assemblyPath)
{
var reflectionDomain = AppDomain.CreateDomain("ReflectionDomain");
try
{
var agentType = typeof(ReflectionAgent);
var agent = reflectionDomain.CreateInstanceAndUnwrap(agentType.Assembly.FullName, agentType.FullName) as ReflectionAgent;
return agent.GetReferencedAssemblies(assemblyPath);
}
finally
{
AppDomain.Unload(reflectionDomain);
}
}
private class ReflectionAgent : MarshalByRefObject
{
public AssemblyName[] GetReferencedAssemblies(string assemblyPath)
{
var testAssembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
var references = testAssembly.GetReferencedAssemblies();
return references;
}
}
#endregion #endregion
#region Service Overrides #region Service Overrides

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

@ -23,6 +23,7 @@
using System; using System;
using System.IO; using System.IO;
using Mono.Cecil;
using NUnit.Common; using NUnit.Common;
using NUnit.Engine.Internal; using NUnit.Engine.Internal;
@ -114,34 +115,25 @@ namespace NUnit.Engine.Services
// contribute any information to the decision, so we skip it. // contribute any information to the decision, so we skip it.
if (PathUtils.IsAssemblyFileType(assembly) && File.Exists(assembly)) if (PathUtils.IsAssemblyFileType(assembly) && File.Exists(assembly))
{ {
using (var reader = new AssemblyReader(assembly)) var module = AssemblyDefinition.ReadAssembly(assembly).MainModule;
var NativeEntryPoint = (ModuleAttributes)16;
var mask = ModuleAttributes.Required32Bit | NativeEntryPoint;
if (module.Architecture != TargetArchitecture.AMD64 &&
module.Architecture != TargetArchitecture.IA64 &&
(module.Attributes & mask) != 0)
{ {
if (!reader.IsValidPeFile) package.Settings[PackageSettings.RunAsX86] = true;
log.Debug("{0} is not a valid PE file", assembly); log.Debug("Assembly {0} will be run x86", assembly);
else if (!reader.IsDotNetFile)
log.Debug("{0} is not a managed assembly", assembly);
else
{
if (reader.ShouldRun32Bit)
{
package.Settings[PackageSettings.RunAsX86] = true;
log.Debug("Assembly {0} will be run x86", assembly);
}
var imageRuntimeVersion = reader.ImageRuntimeVersion;
if (imageRuntimeVersion != null)
{
var v = new Version(imageRuntimeVersion.Substring(1));
log.Debug("Assembly {0} uses version {1}", assembly, v);
// TODO: We are doing two jobs here: (1) getting the
// target version and (2) applying a policy that says
// we run under the highest version of all assemblies.
// We should implement the policy at a higher level.
if (v > targetVersion) targetVersion = v;
}
}
} }
var v = new Version(module.RuntimeVersion.Substring(1));
log.Debug("Assembly {0} uses version {1}", assembly, v);
// TODO: We are doing two jobs here: (1) getting the
// target version and (2) applying a policy that says
// we run under the highest version of all assemblies.
// We should implement the policy at a higher level.
if (v > targetVersion) targetVersion = v;
} }
} }

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

@ -37,6 +37,15 @@
<NoWarn>1685</NoWarn> <NoWarn>1685</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Mono.Cecil">
<HintPath>..\..\..\packages\Mono.Cecil.0.9.6.1\lib\net20\Mono.Cecil.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Mdb">
<HintPath>..\..\..\packages\Mono.Cecil.0.9.6.1\lib\net20\Mono.Cecil.Mdb.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Pdb">
<HintPath>..\..\..\packages\Mono.Cecil.0.9.6.1\lib\net20\Mono.Cecil.Pdb.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
@ -83,7 +92,6 @@
<Compile Include="Agents\TestAgent.cs" /> <Compile Include="Agents\TestAgent.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="CallbackHandler.cs" /> <Compile Include="CallbackHandler.cs" />
<Compile Include="Internal\AssemblyReader.cs" />
<Compile Include="Internal\DomainUsage.cs" /> <Compile Include="Internal\DomainUsage.cs" />
<Compile Include="Internal\NUnitConfiguration.cs" /> <Compile Include="Internal\NUnitConfiguration.cs" />
<Compile Include="Internal\PathUtils.cs" /> <Compile Include="Internal\PathUtils.cs" />
@ -150,7 +158,9 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

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

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Mono.Cecil" version="0.9.6.1" targetFramework="net20" />
</packages>