Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Understanding assembly type from source #1529

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions TestPlatform.sln
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "perf", "perf", "{0D4DF78D-7
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "vstest.console.PlatformTests", "test\vstest.console.PlatformTests\vstest.console.PlatformTests.csproj", "{8C068694-23A2-47A2-A0DD-DB82D0AF0142}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Common.PlatformTests", "test\Microsoft.TestPlatform.Common.PlatformTests\Microsoft.TestPlatform.Common.PlatformTests.csproj", "{24C7683D-2607-4901-B8EB-83A57E49E93D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -781,6 +783,18 @@ Global
{8C068694-23A2-47A2-A0DD-DB82D0AF0142}.Release|x64.Build.0 = Release|Any CPU
{8C068694-23A2-47A2-A0DD-DB82D0AF0142}.Release|x86.ActiveCfg = Release|Any CPU
{8C068694-23A2-47A2-A0DD-DB82D0AF0142}.Release|x86.Build.0 = Release|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Debug|x64.ActiveCfg = Debug|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Debug|x64.Build.0 = Debug|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Debug|x86.ActiveCfg = Debug|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Debug|x86.Build.0 = Debug|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Release|Any CPU.Build.0 = Release|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Release|x64.ActiveCfg = Release|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Release|x64.Build.0 = Release|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Release|x86.ActiveCfg = Release|Any CPU
{24C7683D-2607-4901-B8EB-83A57E49E93D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -849,6 +863,7 @@ Global
{826CD5AF-44FA-40F6-B731-3980CADED8C0} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
{0D4DF78D-7E5F-4516-B19F-E6AA71A1DBF4} = {EE49F5DC-5835-4AE3-B3BA-8BDE0AD56330}
{8C068694-23A2-47A2-A0DD-DB82D0AF0142} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999}
{24C7683D-2607-4901-B8EB-83A57E49E93D} = {376C19DE-31E2-4FF6-88FC-0D0D6233C999}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0541B30C-FF51-4E28-B172-83F5F3934BCD}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.IO" />
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
Expand Down
72 changes: 72 additions & 0 deletions src/Microsoft.TestPlatform.Common/Utilities/PEReaderHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.VisualStudio.TestPlatform.Common.Utilities
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this class Singleton?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not required. Removed.

{
using System;
using System.IO;
using System.Reflection.PortableExecutable;

using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;

public class PEReaderHelper
{
private readonly IFileHelper fileHelper;

/// <summary>
/// Initializes a new instance of the <see cref="PEReaderHelper"/> class.
/// </summary>
public PEReaderHelper() : this(new FileHelper())
{
}

/// <summary>
/// Initializes a new instance of the <see cref="PEReaderHelper"/> class.
/// </summary>
/// <param name="fileHelper">File helper.</param>
public PEReaderHelper(FileHelper fileHelper)
Copy link
Contributor

Choose a reason for hiding this comment

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

Use type IFileHelper.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

{
this.fileHelper = fileHelper;
}

/// <summary>
/// Determines assembly type from file.
/// </summary>
public AssemblyType GetAssemblyType(string filePath)
{
var assemblyType = AssemblyType.None;

try
{
using (var fileStream = fileHelper.GetStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Add this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

using (var peReader = new PEReader(fileStream))
{
// Resources for PEReader:
// 1. https://msdn.microsoft.com/library/windows/desktop/ms680547(v=vs.85).aspx?id=19509
// 2. https://github.com/dotnet/corefx/tree/master/src/System.Reflection.Metadata

var peHeaders = peReader.PEHeaders;
var corHeader = peHeaders.CorHeader;
var corHeaderStartOffset = peHeaders.CorHeaderStartOffset;
Copy link
Contributor

Choose a reason for hiding this comment

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

Add link to documentation in comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done


assemblyType = (corHeader != null && corHeaderStartOffset >= 0) ?
Copy link
Contributor

Choose a reason for hiding this comment

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

can you point the documentation for how to determine if the assembly is managed or native

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Documentation links added in above lines

AssemblyType.Managed :
AssemblyType.Native;
}
}
catch (Exception ex)
{
EqtTrace.Warning("GetAssemblyTypeFromAssemblyMetadata: failed to determine assembly type: {0} for assembly: {1}", ex, filePath);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Keep message prefix to Classname.Method name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

}

if (EqtTrace.IsInfoEnabled)
{
EqtTrace.Info("AssemblyMetadataProvider.GetAssemblyType: Determined assemblyType:'{0}' for source: '{1}'", assemblyType, filePath);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: change the class name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

}

return assemblyType;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ public Stream GetStream(string filePath, FileMode mode, FileAccess access = File
return new FileStream(filePath, mode, access);
}

/// <inheritdoc/>
public Stream GetStream(string filePath, FileMode mode, FileAccess access, FileShare share)
{
return new FileStream(filePath, mode, access, share);
}


/// <inheritdoc/>
public IEnumerable<string> EnumerateFiles(
string directory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ public interface IFileHelper
/// <returns>A <see cref="Stream"/> that supports read/write on the file.</returns>
Stream GetStream(string filePath, FileMode mode, FileAccess access = FileAccess.ReadWrite);

/// <summary>
/// Gets a stream for the file.
/// </summary>
/// <param name="filePath">Path to the file.</param>
/// <param name="mode"><see cref="FileMode"/> for file operations.</param>
/// <param name="access"><see cref="FileAccess"/> for file operations.</param>
/// <param name="share"><see cref="FileShare"/> for file operations.</param>
/// <returns>A <see cref="Stream"/> that supports read/write on the file.</returns>
Stream GetStream(string filePath, FileMode mode, FileAccess access, FileShare share);

/// <summary>
/// Enumerates files which match a pattern (case insensitive) in a directory.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TestPlatformRoot Condition="$(TestPlatformRoot) == ''">..\..\</TestPlatformRoot>
<TestProject>true</TestProject>
</PropertyGroup>
<Import Project="$(TestPlatformRoot)scripts/build/TestPlatform.Settings.targets" />
<PropertyGroup>
<TargetFrameworks>netcoreapp1.0;net451</TargetFrameworks>
<OutputType Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">Exe</OutputType>
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: this line is not required.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

<AssemblyName>Microsoft.TestPlatform.Common.PlatformTests</AssemblyName>
<EnableCodeAnalysis>true</EnableCodeAnalysis>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.TestPlatform.TestUtilities\Microsoft.TestPlatform.TestUtilities.csproj" />
<PackageReference Include="Microsoft.TestPlatform.TestAsset.NativeCPP">
<Version>2.0.0</Version>
Copy link
Contributor

Choose a reason for hiding this comment

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

Please never upload nupkg with same version after changing the content. It will leads to different behavior based on user nuget cache.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not doing in this as we are only using it this nuget. Will update if happens in future changes

</PackageReference>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
<Reference Include="System.Runtime" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>
<Import Project="$(TestPlatformRoot)scripts\build\TestPlatform.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace TestPlatform.Common.UnitTests.Utilities
{
using Microsoft.TestPlatform.TestUtilities;
using Microsoft.VisualStudio.TestPlatform.Common.Utilities;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class PEReaderHelperTests : IntegrationTestBase
{
private PEReaderHelper peReaderHelper;

public PEReaderHelperTests()
{
this.peReaderHelper = new PEReaderHelper();
}

[TestMethod]
[DataRow("net451")]
[DataRow("netcoreapp1.0")]
[DataRow("netcoreapp2.0")]
public void GetAssemblyTypeForManagedDll(string framework)
{
var assemblyPath = this.testEnvironment.GetTestAsset("SimpleTestProject3.dll", framework);
var assemblyType = this.peReaderHelper.GetAssemblyType(assemblyPath);

Assert.AreEqual(AssemblyType.Managed, assemblyType);
}

[TestMethod]
public void GetAssemblyTypeForNativeDll()
{
var assemblyPath = $@"{this.testEnvironment.PackageDirectory}\microsoft.testplatform.testasset.nativecpp\2.0.0\contentFiles\any\any\Microsoft.TestPlatform.TestAsset.NativeCPP.dll";
var assemblyType = this.peReaderHelper.GetAssemblyType(assemblyPath);

Assert.AreEqual(AssemblyType.Native, assemblyType);
}

[TestMethod]
public void GetAssemblyTypeForManagedExe()
{
var assemblyPath = this.testEnvironment.GetTestAsset("ConsoleManagedApp.exe", "net451");
var assemblyType = this.peReaderHelper.GetAssemblyType(assemblyPath);

Assert.AreEqual(AssemblyType.Managed, assemblyType);
}

[TestMethod]
[DataRow("netcoreapp1.0")]
[DataRow("netcoreapp2.0")]
public void GetAssemblyTypeForNetCoreManagedExe(string framework)
{
var assemblyPath = this.testEnvironment.GetTestAsset("ConsoleManagedApp.dll", framework);
var assemblyType = this.peReaderHelper.GetAssemblyType(assemblyPath);

Assert.AreEqual(AssemblyType.Managed, assemblyType);
}

[TestMethod]
public void GetAssemblyTypeForNativeExe()
{
var assemblyPath = $@"{this.testEnvironment.PackageDirectory}\microsoft.testplatform.testasset.nativecpp\2.0.0\contentFiles\any\any\Microsoft.TestPlatform.TestAsset.ConsoleNativeApp.exe";
var assemblyType = this.peReaderHelper.GetAssemblyType(assemblyPath);

Assert.AreEqual(AssemblyType.Native, assemblyType);
}

[TestMethod]
public void GetAssemblyTypeShouldReturnNoneInCaseOfError()
{
var assemblyType = this.peReaderHelper.GetAssemblyType("invalidFile.dll");

Assert.AreEqual(AssemblyType.None, assemblyType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<ProjectGuid>{076CE7E6-92E8-49FD-9D98-57D377FAA46E}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>CPPSimpleProj</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<ProjectName>Microsoft.TestPlatform.TestAsset.NativeCPP</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
Copy link
Contributor

Choose a reason for hiding this comment

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

Why ConsoleNativeApp.cpp is binary file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// ConsoleNativeApp.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


int main()
{
return 0;
}

Loading