Skip to content

Commit f74452c

Browse files
committed
Adding tests to verify legacy and new behavior returns accurate values
putting tests in separate project Recreate test proj using .net framework Move pmip reading functionality out to separate file that doesn't require Debugger.Engine references to allow for it to be unit tested. Updating to have tests that pass with real test data. cleaning up debug print statements
1 parent 81ee19d commit f74452c

11 files changed

+152758
-137
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net472</TargetFramework>
5+
6+
<IsPackable>false</IsPackable>
7+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
8+
<PlatformTarget>x64</PlatformTarget>
9+
<Platforms>AnyCPU;x64</Platforms>
10+
<VSSdkPath Condition="'$(VisualStudioVersion.Contains(`17`))'">$(ProgramFiles)\Microsoft Visual Studio\2022\Professional\VSSDK\</VSSdkPath>
11+
<VSSdkPath Condition="'$(VisualStudioVersion.Contains(`16`))'">$(MSBuildProgramFiles32)\Microsoft Visual Studio\2019\Professional\VSSDK\</VSSdkPath>
12+
<ConcordSDKDir>$(VSSdkPath)VisualStudioIntegration\</ConcordSDKDir>
13+
</PropertyGroup>
14+
15+
<ItemGroup>
16+
<None Remove="pmip_32260_3.txt" />
17+
</ItemGroup>
18+
19+
<ItemGroup>
20+
<PackageReference Include="Microsoft.TestPlatform" Version="17.2.0" />
21+
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
22+
<PackageReference Include="NUnit" Version="3.13.3" />
23+
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
24+
</ItemGroup>
25+
26+
<Import Project="$(ConcordSDKDir)Tools\bin\Microsoft.VSSDK.Debugger.VSDConfigTool.targets" />
27+
28+
<ItemGroup>
29+
<ProjectReference Include="..\UnityMixedCallStack.csproj" />
30+
</ItemGroup>
31+
32+
<ItemGroup>
33+
<None Update="TestData\line-numbers\pmip_23672_1_0.txt">
34+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
35+
</None>
36+
<None Update="TestData\line-numbers\pmip_23672_4_1.txt">
37+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
38+
</None>
39+
<None Update="TestData\pmip_31964_3.txt">
40+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
41+
</None>
42+
<None Update="TestData\pmip_32260_3.txt">
43+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
44+
</None>
45+
<None Update="TestData\pmip_44920_4.txt">
46+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
47+
</None>
48+
</ItemGroup>
49+
50+
</Project>

CallstackTestProj/TestData/line-numbers/pmip_23672_1_0.txt

Lines changed: 208 additions & 0 deletions
Large diffs are not rendered by default.

CallstackTestProj/TestData/line-numbers/pmip_23672_4_1.txt

Lines changed: 95270 additions & 0 deletions
Large diffs are not rendered by default.

CallstackTestProj/TestData/pmip_31964_3.txt

Lines changed: 15699 additions & 0 deletions
Large diffs are not rendered by default.

CallstackTestProj/TestData/pmip_32260_3.txt

Lines changed: 20617 additions & 0 deletions
Large diffs are not rendered by default.

CallstackTestProj/UnitTest1.cs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Globalization;
5+
using System.IO;
6+
using UnityMixedCallStack;
7+
8+
namespace CallstackTestProj
9+
{
10+
[TestFixture]
11+
public class Tests
12+
{
13+
private Tuple<string, string>[] m_legacyData =
14+
{
15+
Tuple.Create("000001C44A1C81D7", "[UnityEditor.CoreModule.dll] (wrapper managed-to-native) UnityEditor.EditorGUIUtility:RenderPlayModeViewCamerasInternal_Injected (UnityEngine.RenderTexture,int,UnityEngine.Vector2&,bool,bool)"),
16+
Tuple.Create("000001C44A1C8083", "[UnityEditor.CoreModule.dll] UnityEditor.EditorGUIUtility:RenderPlayModeViewCamerasInternal (UnityEngine.RenderTexture,int,UnityEngine.Vector2,bool,bool)"),
17+
Tuple.Create("000001C44A1C52EB", "[UnityEditor.CoreModule.dll] UnityEditor.PlayModeView:RenderView (UnityEngine.Vector2,bool)"),
18+
Tuple.Create("000001C449F19A23", "[UnityEditor.CoreModule.dll] UnityEditor.GameView:OnGUI ()"),
19+
Tuple.Create("000001C449F12BF8", "[UnityEditor.CoreModule.dll] UnityEditor.HostView:InvokeOnGUI (UnityEngine.Rect)"),
20+
Tuple.Create("000001C449F12793", "[UnityEditor.CoreModule.dll] UnityEditor.DockArea:DrawView (UnityEngine.Rect)"),
21+
Tuple.Create("000001C449EF1353", "[UnityEditor.CoreModule.dll] UnityEditor.DockArea:OldOnGUI ()"),
22+
Tuple.Create("000001C449EBCCE9", "[UnityEngine.UIElementsModule.dll] UnityEngine.UIElements.IMGUIContainer:DoOnGUI (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,bool,UnityEngine.Rect,System.Action,bool)"),
23+
Tuple.Create("000001C449EBAC13", "[UnityEngine.UIElementsModule.dll] UnityEngine.UIElements.IMGUIContainer:HandleIMGUIEvent (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,System.Action,bool)")
24+
};
25+
26+
[Test]
27+
public void LegacyDataTest()
28+
{
29+
Assert.IsTrue(PmipReader.ReadPmipFile(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "pmip_32260_3.txt")));
30+
PmipReader.Sort();
31+
32+
foreach (Tuple<string, string> t in m_legacyData)
33+
{
34+
if (PmipReader.TryGetDescriptionForIp(ulong.Parse(t.Item1, NumberStyles.HexNumber), out string retVal))
35+
{
36+
Assert.AreEqual(t.Item2, retVal);
37+
}
38+
else
39+
Assert.Fail();
40+
}
41+
PmipReader.DisposeStreams();
42+
}
43+
44+
private Tuple<string, string>[] m_legacyModeData =
45+
{
46+
Tuple.Create("000001C4F5DC03FF", "[Assembly-CSharp.dll] SpinMe:FooBar ()"),
47+
Tuple.Create("000001C4F5DC02D3", "[Assembly-CSharp.dll] SpinMe:Foo ()"),
48+
Tuple.Create("000001C4F5DBF6F3", "[Assembly-CSharp.dll] SpinMe:Update ()"),
49+
Tuple.Create("000001C3FF868578", "[mscorlib.dll] (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)")
50+
};
51+
52+
[Test]
53+
public void LegacyModeDataTest()
54+
{
55+
Assert.IsTrue(PmipReader.ReadPmipFile(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "pmip_31964_3.txt")));
56+
PmipReader.Sort();
57+
58+
foreach (Tuple<string, string> t in m_legacyModeData)
59+
{
60+
if (PmipReader.TryGetDescriptionForIp(ulong.Parse(t.Item1, NumberStyles.HexNumber), out string retVal))
61+
{
62+
Assert.AreEqual(t.Item2, retVal);
63+
}
64+
else
65+
Assert.Fail();
66+
};
67+
PmipReader.DisposeStreams();
68+
}
69+
70+
private Tuple<string, string>[] m_lineNumbersData =
71+
{
72+
Tuple.Create("00000244C7A990BF", "[Assembly-CSharp.dll] SpinMe:FooBar ()"),
73+
Tuple.Create("00000244C7A98F93", "[Assembly-CSharp.dll] SpinMe:Foo () : 32"),
74+
Tuple.Create("00000244C7A98153", "[Assembly-CSharp.dll] SpinMe:Update () : 26"),
75+
Tuple.Create("00000244EC9DF6B8", "[mscorlib.dll] (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)")
76+
};
77+
78+
[Test]
79+
public void LineNumbersDataTest()
80+
{
81+
Assert.IsTrue(PmipReader.ReadPmipFile(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "line-numbers", "pmip_23672_1_0.txt")));
82+
Assert.IsTrue(PmipReader.ReadPmipFile(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "line-numbers", "pmip_23672_4_1.txt")));
83+
PmipReader.Sort();
84+
85+
foreach (Tuple<string, string> t in m_lineNumbersData)
86+
{
87+
if (PmipReader.TryGetDescriptionForIp(ulong.Parse(t.Item1, NumberStyles.HexNumber), out string retVal))
88+
{
89+
Assert.AreEqual(t.Item2, retVal);
90+
}
91+
else
92+
Assert.Fail($"Couldn't find address: {t.Item1}");
93+
};
94+
95+
PmipReader.DisposeStreams();
96+
}
97+
}
98+
}

PmipReader.cs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+

2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Globalization;
6+
using System.IO;
7+
using UnityMixedCallstack;
8+
9+
namespace UnityMixedCallStack
10+
{
11+
public class PmipReader
12+
{
13+
private static List<Range> _rangesSortedByIp = new List<Range>();
14+
private static List<Range> _legacyRanges = new List<Range>();
15+
private static FuzzyRangeComparer _comparer = new FuzzyRangeComparer();
16+
private static FileStream _fileStream;
17+
private static StreamReader _fileStreamReader;
18+
19+
public static void Sort()
20+
{
21+
_legacyRanges.Sort((r1, r2) => r1.Start.CompareTo(r2.Start));
22+
_rangesSortedByIp.Sort((r1, r2) => r1.Start.CompareTo(r2.Start));
23+
}
24+
25+
public static void DisposeStreams()
26+
{
27+
_fileStreamReader?.Dispose();
28+
_fileStreamReader = null;
29+
30+
_fileStream?.Dispose();
31+
_fileStream = null;
32+
33+
_rangesSortedByIp.Clear();
34+
}
35+
public static bool ReadPmipFile(string filePath)
36+
{
37+
//_debugPane?.OutputString("MIXEDCALLSTACK :: Reading pmip file: " + filePath + "\n");
38+
DisposeStreams();
39+
try
40+
{
41+
_fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
42+
_fileStreamReader = new StreamReader(_fileStream);
43+
var versionStr = _fileStreamReader.ReadLine();
44+
const char delimiter = ':';
45+
var tokens = versionStr.Split(delimiter);
46+
47+
if (tokens.Length != 2)
48+
throw new Exception("Failed reading input file " + filePath + ": Incorrect format");
49+
50+
if (!double.TryParse(tokens[1], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var version))
51+
throw new Exception("Failed reading input file " + filePath + ": Incorrect version format");
52+
53+
if (version > 2.0)
54+
throw new Exception("Failed reading input file " + filePath + ": A newer version of UnityMixedCallstacks plugin is required to read this file");
55+
}
56+
catch (Exception ex)
57+
{
58+
//_debugPane?.OutputString("MIXEDCALLSTACK :: Unable to read dumped pmip file: " + ex.Message + "\n");
59+
DisposeStreams();
60+
return false;
61+
}
62+
63+
try
64+
{
65+
string line;
66+
while ((line = _fileStreamReader.ReadLine()) != null)
67+
{
68+
const char delemiter = ';';
69+
var tokens = line.Split(delemiter);
70+
71+
//should never happen, but lets be safe and not get array out of bounds if it does
72+
if (tokens.Length == 3 || tokens.Length == 4)
73+
{
74+
string startip = tokens[0];
75+
string endip = tokens[1];
76+
string description = tokens[2];
77+
string file = "";
78+
if (tokens.Length == 4)
79+
file = tokens[3];
80+
81+
if (startip.StartsWith("---"))
82+
{
83+
startip = startip.Remove(0, 3);
84+
}
85+
86+
var startiplong = ulong.Parse(startip, NumberStyles.HexNumber);
87+
var endipint = ulong.Parse(endip, NumberStyles.HexNumber);
88+
if (tokens[0].StartsWith("---"))
89+
{
90+
// legacy stored in new pmip file
91+
_legacyRanges.Add(new Range() { Name = description, File = file, Start = startiplong, End = endipint });
92+
}
93+
else
94+
_rangesSortedByIp.Add(new Range() { Name = description, File = file, Start = startiplong, End = endipint });
95+
}
96+
}
97+
//_debugPane?.OutputString("MIXEDCALLSTACK :: map now has " + _rangesSortedByIp.Count + " entries! legacy map has: " + _legacyRanges.Count + "\n");
98+
}
99+
catch (Exception ex)
100+
{
101+
//_debugPane?.OutputString("MIXEDCALLSTACK :: Unable to read dumped pmip file: " + ex.Message + "\n");
102+
DisposeStreams();
103+
return false;
104+
}
105+
return true;
106+
}
107+
108+
public static bool TryGetDescriptionForIp(ulong ip, out string name)
109+
{
110+
name = string.Empty;
111+
112+
//_debugPane?.OutputString("MIXEDCALLSTACK :: Looking for ip: " + String.Format("{0:X}", ip) + "\n");
113+
var rangeToFindIp = new Range() { Start = ip };
114+
var index = _rangesSortedByIp.BinarySearch(rangeToFindIp, _comparer);
115+
116+
if (index >= 0)
117+
{
118+
//_debugPane?.OutputString("MIXEDCALLSTACK :: SUCCESS!!\n");
119+
name = _rangesSortedByIp[index].Name;
120+
return true;
121+
}
122+
123+
index = _legacyRanges.BinarySearch(rangeToFindIp, _comparer);
124+
if (index >= 0)
125+
{
126+
//_debugPane?.OutputString("MIXEDCALLSTACK :: LEGACY SUCCESS!! "+ String.Format("{0:X}", _legacyRanges[index].Start) +" -- "+ String.Format("{0:X}", _legacyRanges[index].End) + "\n");
127+
name = _legacyRanges[index].Name;
128+
return true;
129+
}
130+
131+
return false;
132+
}
133+
134+
}
135+
}

UnityMixedCallstack.csproj

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<PropertyGroup>
44
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
@@ -55,22 +55,24 @@
5555
<StartWorkingDirectory>$(DevEnvDir)</StartWorkingDirectory>
5656
<StartArguments>/rootsuffix Exp</StartArguments>
5757
</PropertyGroup>
58-
5958
<PropertyGroup>
6059
<VsVersion Condition="'$(VisualStudioVersion.Contains(`17`))'">VS2022</VsVersion>
6160
<VsVersion Condition="'$(VisualStudioVersion.Contains(`16`))'">VS2019</VsVersion>
6261
<OutputPath>bin\$(VsVersion)\$(Configuration)\</OutputPath>
63-
<IntermediateOutputPath>obj\$(VsVersion)\$(Configuration)\</IntermediateOutputPath>
62+
<IntermediateOutputPath>obj\$(VsVersion)\$(Configuration)\</IntermediateOutputPath>
6463
</PropertyGroup>
6564
<Choose>
6665
<When Condition="'$(VsVersion)' == 'VS2022'">
6766
<PropertyGroup>
6867
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
6968
</PropertyGroup>
7069
<ItemGroup>
71-
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.0.31902.203" />
72-
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.0.5232" />
73-
<PackageReference Include="Microsoft.VisualStudio.Debugger.Engine" Version="17.0.1110801" />
70+
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.2.32505.173" />
71+
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.2.2186">
72+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
73+
<PrivateAssets>all</PrivateAssets>
74+
</PackageReference>
75+
<PackageReference Include="Microsoft.VisualStudio.Debugger.Engine" Version="17.0.2012801" />
7476
</ItemGroup>
7577
</When>
7678
<Otherwise>
@@ -87,13 +89,10 @@
8789
<ItemGroup>
8890
<Reference Include="System" />
8991
<Reference Include="System.Core" />
90-
<Reference Include="Microsoft.VisualStudio.Debugger.Engine">
91-
<HintPath>$(ConcordSDKDir)Reference Assemblies\Microsoft.VisualStudio.Debugger.Engine.dll</HintPath>
92-
<Private>False</Private>
93-
</Reference>
9492
</ItemGroup>
9593
<ItemGroup>
9694
<Compile Include="FuzzyRangeComparer.cs" />
95+
<Compile Include="PmipReader.cs" />
9796
<Compile Include="UnityMixedCallStackFilter.cs" />
9897
<Compile Include="Properties\AssemblyInfo.cs" />
9998
</ItemGroup>
@@ -104,9 +103,20 @@
104103
</ItemGroup>
105104
<ItemGroup>
106105
<None Include="source.extension.vsixmanifest">
107-
<SubType>Designer</SubType>
106+
<SubType>Designer</SubType>
108107
</None>
109-
</ItemGroup>
108+
</ItemGroup>
109+
<ItemGroup>
110+
<PackageReference Include="Microsoft.NET.Test.Sdk">
111+
<Version>17.2.0</Version>
112+
</PackageReference>
113+
<PackageReference Include="Microsoft.TestPlatform">
114+
<Version>17.2.0</Version>
115+
</PackageReference>
116+
</ItemGroup>
117+
<ItemGroup>
118+
<Content Include="pmip_32260_3.txt" />
119+
</ItemGroup>
110120
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
111121
<Import Project="$(ConcordSDKDir)Tools\bin\Microsoft.VSSDK.Debugger.VSDConfigTool.targets" />
112122
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />

0 commit comments

Comments
 (0)