267 lines
14 KiB
C++
267 lines
14 KiB
C++
#include "pch.h"
|
|
|
|
#include "../../src/OpenTelemetry.AutoInstrumentation.Native/clr_helpers.h"
|
|
#include "test_helpers.h"
|
|
|
|
#include <vector>
|
|
|
|
using namespace trace;
|
|
|
|
class CLRHelperTest : public ::CLRHelperTestBase
|
|
{
|
|
};
|
|
TEST_F(CLRHelperTest, EnumeratesTypeDefs)
|
|
{
|
|
std::vector<std::wstring> expected_types = {L"Microsoft.CodeAnalysis.EmbeddedAttribute",
|
|
L"System.Runtime.CompilerServices.IsReadOnlyAttribute",
|
|
L"System.Runtime.CompilerServices.NullableAttribute",
|
|
L"System.Runtime.CompilerServices.NullableContextAttribute",
|
|
L"System.Runtime.CompilerServices.RefSafetyRulesAttribute",
|
|
L"TestApplication.ExampleLibrary.Class1",
|
|
L"TestApplication.ExampleLibrary.GenericTests.ComprehensiveCaller`2",
|
|
L"TestApplication.ExampleLibrary.GenericTests.GenericTarget`2",
|
|
L"TestApplication.ExampleLibrary.GenericTests.PointStruct",
|
|
L"TestApplication.ExampleLibrary.GenericTests.StructContainer`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.Biscuit`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.Biscuit",
|
|
L"TestApplication.ExampleLibrary.FakeClient.StructBiscuit",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogClient`2",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogTrick`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogTrick",
|
|
L"<>c",
|
|
L"Cookie",
|
|
L"Cookie",
|
|
L"<StayAndLayDown>d__4`2",
|
|
L"Raisin"};
|
|
|
|
std::vector<std::wstring> actual_types;
|
|
|
|
for (auto& def : EnumTypeDefs(metadata_import_))
|
|
{
|
|
std::wstring name(256, 0);
|
|
DWORD name_sz = 0;
|
|
DWORD flags = 0;
|
|
mdToken extends = 0;
|
|
auto hr = metadata_import_->GetTypeDefProps(def, name.data(), (DWORD)(name.size()), &name_sz, &flags, &extends);
|
|
ASSERT_TRUE(SUCCEEDED(hr));
|
|
|
|
if (name_sz > 0)
|
|
{
|
|
name = name.substr(0, name_sz - 1);
|
|
actual_types.push_back(name);
|
|
}
|
|
}
|
|
|
|
EXPECT_EQ(expected_types, actual_types);
|
|
}
|
|
|
|
TEST_F(CLRHelperTest, EnumeratesAssemblyRefs)
|
|
{
|
|
std::vector<std::wstring> expected_assemblies = {L"mscorlib"};
|
|
std::vector<std::wstring> actual_assemblies;
|
|
for (auto& ref : EnumAssemblyRefs(assembly_import_))
|
|
{
|
|
auto name = GetReferencedAssemblyMetadata(assembly_import_, ref).name;
|
|
if (!name.empty())
|
|
{
|
|
actual_assemblies.push_back(name);
|
|
}
|
|
}
|
|
EXPECT_EQ(expected_assemblies, actual_assemblies);
|
|
}
|
|
|
|
TEST_F(CLRHelperTest, GetsTypeInfoFromTypeDefs)
|
|
{
|
|
std::set<std::wstring> expected = {L"<>c",
|
|
L"<StayAndLayDown>d__4`2",
|
|
L"Cookie",
|
|
L"Microsoft.CodeAnalysis.EmbeddedAttribute",
|
|
L"Raisin",
|
|
L"System.Runtime.CompilerServices.IsReadOnlyAttribute",
|
|
L"System.Runtime.CompilerServices.NullableAttribute",
|
|
L"System.Runtime.CompilerServices.NullableContextAttribute",
|
|
L"System.Runtime.CompilerServices.RefSafetyRulesAttribute",
|
|
L"TestApplication.ExampleLibrary.Class1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.Biscuit",
|
|
L"TestApplication.ExampleLibrary.FakeClient.Biscuit`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogClient`2",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogTrick",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogTrick`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.StructBiscuit",
|
|
L"TestApplication.ExampleLibrary.GenericTests.ComprehensiveCaller`2",
|
|
L"TestApplication.ExampleLibrary.GenericTests.GenericTarget`2",
|
|
L"TestApplication.ExampleLibrary.GenericTests.PointStruct",
|
|
L"TestApplication.ExampleLibrary.GenericTests.StructContainer`1"};
|
|
std::set<std::wstring> actual;
|
|
for (auto& type_def : EnumTypeDefs(metadata_import_))
|
|
{
|
|
auto type_info = GetTypeInfo(metadata_import_, type_def);
|
|
if (type_info.IsValid())
|
|
{
|
|
actual.insert(type_info.name);
|
|
}
|
|
}
|
|
EXPECT_EQ(actual, expected);
|
|
}
|
|
|
|
TEST_F(CLRHelperTest, GetsTypeInfoFromTypeRefs)
|
|
{
|
|
std::set<std::wstring> expected = {L"DebuggingModes",
|
|
L"Enumerator",
|
|
L"System.Array",
|
|
L"System.Attribute",
|
|
L"System.AttributeTargets",
|
|
L"System.AttributeUsageAttribute",
|
|
L"System.Byte",
|
|
L"System.Collections.DictionaryEntry",
|
|
L"System.Collections.Generic.Dictionary`2",
|
|
L"System.Collections.Generic.IList`1",
|
|
L"System.Collections.Generic.List`1",
|
|
L"System.Diagnostics.DebuggableAttribute",
|
|
#ifdef _DEBUG
|
|
L"System.Diagnostics.DebuggerBrowsableAttribute",
|
|
L"System.Diagnostics.DebuggerBrowsableState",
|
|
#endif
|
|
L"System.Diagnostics.DebuggerHiddenAttribute",
|
|
#ifdef _DEBUG
|
|
L"System.Diagnostics.DebuggerStepThroughAttribute",
|
|
#endif
|
|
L"System.Exception",
|
|
L"System.Func`3",
|
|
L"System.Guid",
|
|
L"System.Int32",
|
|
L"System.Object",
|
|
L"System.Reflection.AssemblyCompanyAttribute",
|
|
L"System.Reflection.AssemblyConfigurationAttribute",
|
|
L"System.Reflection.AssemblyFileVersionAttribute",
|
|
L"System.Reflection.AssemblyInformationalVersionAttribute",
|
|
L"System.Reflection.AssemblyProductAttribute",
|
|
L"System.Reflection.AssemblyTitleAttribute",
|
|
L"System.Runtime.CompilerServices.AsyncStateMachineAttribute",
|
|
L"System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1",
|
|
L"System.Runtime.CompilerServices.CompilationRelaxationsAttribute",
|
|
L"System.Runtime.CompilerServices.CompilerGeneratedAttribute",
|
|
L"System.Runtime.CompilerServices.IAsyncStateMachine",
|
|
L"System.Runtime.CompilerServices.RuntimeCompatibilityAttribute",
|
|
L"System.Runtime.CompilerServices.TaskAwaiter",
|
|
L"System.Runtime.CompilerServices.TaskAwaiter`1",
|
|
L"System.Runtime.Versioning.TargetFrameworkAttribute",
|
|
L"System.RuntimeTypeHandle",
|
|
L"System.String",
|
|
L"System.Threading.Tasks.Task",
|
|
L"System.Threading.Tasks.Task`1",
|
|
L"System.Tuple`2",
|
|
L"System.Tuple`7",
|
|
L"System.Type",
|
|
L"System.ValueType"};
|
|
std::set<std::wstring> actual;
|
|
for (auto& type_ref : EnumTypeRefs(metadata_import_))
|
|
{
|
|
auto type_info = GetTypeInfo(metadata_import_, type_ref);
|
|
if (type_info.IsValid())
|
|
{
|
|
actual.insert(type_info.name);
|
|
}
|
|
}
|
|
EXPECT_EQ(expected, actual);
|
|
}
|
|
|
|
TEST_F(CLRHelperTest, GetsTypeInfoFromModuleRefs)
|
|
{
|
|
// TODO(cbd): figure out how to create a module ref, for now its empty
|
|
std::set<std::wstring> expected = {};
|
|
std::set<std::wstring> actual;
|
|
for (auto& module_ref : EnumModuleRefs(metadata_import_))
|
|
{
|
|
auto type_info = GetTypeInfo(metadata_import_, module_ref);
|
|
actual.insert(type_info.name);
|
|
}
|
|
EXPECT_EQ(actual, expected);
|
|
}
|
|
|
|
TEST_F(CLRHelperTest, GetsTypeInfoFromMethods)
|
|
{
|
|
std::set<std::wstring> expected = {L"<>c",
|
|
L"<StayAndLayDown>d__4`2",
|
|
L"Cookie",
|
|
L"Microsoft.CodeAnalysis.EmbeddedAttribute",
|
|
L"Raisin",
|
|
L"System.Runtime.CompilerServices.IsReadOnlyAttribute",
|
|
L"System.Runtime.CompilerServices.NullableAttribute",
|
|
L"System.Runtime.CompilerServices.NullableContextAttribute",
|
|
L"System.Runtime.CompilerServices.RefSafetyRulesAttribute",
|
|
L"TestApplication.ExampleLibrary.Class1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.Biscuit",
|
|
L"TestApplication.ExampleLibrary.FakeClient.Biscuit`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogClient`2",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogTrick",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogTrick`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.StructBiscuit",
|
|
L"TestApplication.ExampleLibrary.GenericTests.ComprehensiveCaller`2",
|
|
L"TestApplication.ExampleLibrary.GenericTests.GenericTarget`2",
|
|
L"TestApplication.ExampleLibrary.GenericTests.PointStruct",
|
|
L"TestApplication.ExampleLibrary.GenericTests.StructContainer`1"};
|
|
std::set<std::wstring> actual;
|
|
for (auto& type_def : EnumTypeDefs(metadata_import_))
|
|
{
|
|
for (auto& method_def : EnumMethods(metadata_import_, type_def))
|
|
{
|
|
auto type_info = GetTypeInfo(metadata_import_, method_def);
|
|
if (type_info.IsValid())
|
|
{
|
|
actual.insert(type_info.name);
|
|
}
|
|
}
|
|
}
|
|
EXPECT_EQ(actual, expected);
|
|
}
|
|
|
|
TEST_F(CLRHelperTest, FindTypeDefsByName)
|
|
{
|
|
std::vector<std::wstring> expected_types = {L"TestApplication.ExampleLibrary.Class1",
|
|
L"TestApplication.ExampleLibrary.GenericTests.ComprehensiveCaller`2",
|
|
L"TestApplication.ExampleLibrary.GenericTests.GenericTarget`2",
|
|
L"TestApplication.ExampleLibrary.GenericTests.PointStruct",
|
|
L"TestApplication.ExampleLibrary.GenericTests.StructContainer`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.Biscuit`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.Biscuit",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogClient`2",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogTrick`1",
|
|
L"TestApplication.ExampleLibrary.FakeClient.DogTrick"};
|
|
|
|
for (auto& def : expected_types)
|
|
{
|
|
mdTypeDef typeDef = mdTypeDefNil;
|
|
auto found = FindTypeDefByName(def, L"TestApplication.ExampleLibrary", metadata_import_, typeDef);
|
|
EXPECT_TRUE(found) << "Failed type is : " << def << std::endl;
|
|
EXPECT_NE(typeDef, mdTypeDefNil) << "Failed type is : " << def << std::endl;
|
|
}
|
|
}
|
|
|
|
TEST_F(CLRHelperTest, FindNestedTypeDefsByName)
|
|
{
|
|
std::vector<std::wstring> expected_types = {L"TestApplication.ExampleLibrary.FakeClient.Biscuit+Cookie",
|
|
L"TestApplication.ExampleLibrary.FakeClient.StructBiscuit+Cookie"};
|
|
|
|
for (auto& def : expected_types)
|
|
{
|
|
mdTypeDef typeDef = mdTypeDefNil;
|
|
auto found = FindTypeDefByName(def, L"TestApplication.ExampleLibrary", metadata_import_, typeDef);
|
|
EXPECT_TRUE(found) << "Failed type is : " << def << std::endl;
|
|
EXPECT_NE(typeDef, mdTypeDefNil) << "Failed type is : " << def << std::endl;
|
|
}
|
|
}
|
|
|
|
TEST_F(CLRHelperTest, DoesNotFindDoubleNestedTypeDefsByName)
|
|
{
|
|
std::vector<std::wstring> expected_types = {L"TestApplication.ExampleLibrary.NotARealClass",
|
|
L"TestApplication.ExampleLibrary.FakeClient.Biscuit+Cookie+Raisin"};
|
|
|
|
for (auto& def : expected_types)
|
|
{
|
|
mdTypeDef typeDef = mdTypeDefNil;
|
|
auto found = FindTypeDefByName(def, L"TestApplication.ExampleLibrary", metadata_import_, typeDef);
|
|
EXPECT_FALSE(found) << "Failed type is : " << def << std::endl;
|
|
EXPECT_EQ(typeDef, mdTypeDefNil) << "Failed type is : " << def << std::endl;
|
|
}
|
|
} |