diff --git a/Il2CppTests/TestRunner.cs b/Il2CppTests/TestRunner.cs index 521d153..118b862 100644 --- a/Il2CppTests/TestRunner.cs +++ b/Il2CppTests/TestRunner.cs @@ -132,14 +132,12 @@ namespace Il2CppInspector TypeModel model; using (new Benchmark("Create .NET type model")) model = new TypeModel(il2cpp); - var appModelTask = Task.Run(() => { using (new Benchmark("Create application model")) return new AppModel(model, makeDefaultBuild: false).Build(compiler: CppCompilerType.MSVC); }); var nameSuffix = i++ > 0 ? "-" + (i - 1) : ""; - var compareTasks = new List(); var csTask = Task.Run(() => { @@ -152,6 +150,14 @@ namespace Il2CppInspector compareTasks.Add(Task.Run(() => compareFiles(testPath, nameSuffix + ".cs", $"test-result{nameSuffix}.cs"))); }); + + var dllTask = Task.Run(() => { + using (new Benchmark("Create .NET assembly shims")) + new AssemblyShims(model).Write(testPath + $@"\test-dll-result{nameSuffix}"); + + compareTasks.Add(Task.Run(() => compareBinaryFiles(testPath + $@"\test-dll-result{nameSuffix}", + testPath + @"\..\..\TestExpectedResults\dll-" + Path.GetFileName(testPath) + nameSuffix))); + }); var appModel = await appModelTask; @@ -179,12 +185,34 @@ namespace Il2CppInspector testPath + $@"\test-result{nameSuffix}.json"); }); - await Task.WhenAll(csTask, jsonTask, cppTask, pyTask); + await Task.WhenAll(csTask, dllTask, jsonTask, cppTask, pyTask); await Task.WhenAll(compareTasks); })); await Task.WhenAll(imageTasks); } + // Compare two folders full of binary files + private void compareBinaryFiles(string resultFolder, string expectedFolder) { + var expectedFiles = Directory.GetFiles(expectedFolder).Select(f => Path.GetFileName(f)); + + foreach (var file in expectedFiles) { + var resultPath = Path.Combine(resultFolder, file); + Assert.That(File.Exists(resultPath), $"File does not exist ({file})"); + + var resultData = File.ReadAllBytes(resultPath); + var expectedData = File.ReadAllBytes(Path.Combine(expectedFolder, file)); + + Assert.AreEqual(expectedData.Length, resultData.Length, $"File lengths do not match ({file})"); + + // A few bytes in the PE header and the end of the string table are changed each build + // so we have to allow for that; we can't use SequenceEqual + var differences = resultData.Zip(expectedData, (x, y) => x == y).Count(eq => !eq); + + // If anything has really changed it will change more than this many bytes + Assert.LessOrEqual(differences, 18, $"File contents differ too much ({file} has {differences} differences)"); + } + } + // We have to pass testPath rather than storing it as a field so that tests can be parallelized private void compareFiles(string testPath, string expectedFilenameSuffix, string actualFilename) { var expected = File.ReadAllLines(testPath + @"\..\..\TestExpectedResults\" + Path.GetFileName(testPath) + expectedFilenameSuffix); diff --git a/Il2CppTests/update-expected-results.ps1 b/Il2CppTests/update-expected-results.ps1 index e4e0afc..587c01e 100644 --- a/Il2CppTests/update-expected-results.ps1 +++ b/Il2CppTests/update-expected-results.ps1 @@ -6,19 +6,27 @@ # It is only intended to be used during development, not for end-user scenarios # Get all test results +echo "Initializing" + $cs = (gci "$PSScriptRoot/TestBinaries/*/*" -Filter test-result.cs) $cs2 = (gci "$PSScriptRoot/TestBinaries/*/*" -Filter test-result-1.cs) $json = (gci "$PSScriptRoot/TestBinaries/*/*" -Filter test-result.json) $json2 = (gci "$PSScriptRoot/TestBinaries/*/*" -Filter test-result-1.json) $cpp = (gci "$PSScriptRoot/TestBinaries/*/test-cpp-result/appdata/*" -Filter il2cpp-types.h) $cpp2 = (gci "$PSScriptRoot/TestBinaries/*/test-cpp-result-1/appdata/*" -Filter il2cpp-types.h) +$dll = (gci "$PSScriptRoot/TestBinaries/*/test-dll-result/*") +$dll2 = (gci "$PSScriptRoot/TestBinaries/*/test-dll-result-1/*") # Get path to expected test results $results = "$PSScriptRoot/TestExpectedResults" # Wipe existing results -rm -Recurse -Force $results >$null -mkdir $results >$null +echo "Removing previous results" + +rm -Recurse -Force $results >$null 2>&1 +mkdir $results >$null 2>&1 + +echo "Updating .cs files" $cs | % { $target = $results + "/" + (Split-Path -Path (Split-Path -Path $_) -Leaf) + ".cs" @@ -30,6 +38,8 @@ $cs2 | % { cp $_ -Destination $target -Force } +echo "Updating .json files" + $json | % { $target = $results + "/" + (Split-Path -Path (Split-Path -Path $_) -Leaf) + ".json" cp $_ -Destination $target -Force @@ -40,6 +50,8 @@ $json2 | % { cp $_ -Destination $target -Force } +echo "Updating .h files" + $cpp | % { $target = $results + "/" + (Split-Path -Path (Split-Path -Path (Split-Path -Path (Split-Path -Path $_))) -Leaf) + ".h" cp $_ -Destination $target -Force @@ -48,4 +60,20 @@ $cpp | % { $cpp2 | % { $target = $results + "/" + (Split-Path -Path (Split-Path -Path (Split-Path -Path (Split-Path -Path $_))) -Leaf) + "-1.h" cp $_ -Destination $target -Force -} \ No newline at end of file +} + +echo "Updating .dll files" + +$dll | % { + $targetPath = $results + "/dll-" + (Split-Path -Path (Split-Path -Path (Split-Path -Path $_)) -Leaf) + mkdir $targetPath >$null 2>&1 + $target = $targetPath + "/" + (Split-Path -Path $_ -Leaf) + cp $_ -Destination $target -Force +} + +$dll2 | % { + $targetPath = $results + "/dll-" + (Split-Path -Path (Split-Path -Path (Split-Path -Path $_)) -Leaf) + "-1" + mkdir $targetPath >$null 2>&1 + $target = $targetPath + "/" + (Split-Path -Path $_ -Leaf) + cp $_ -Destination $target -Force +}