Tests: Add TestRunner configuration
This commit is contained in:
@@ -18,25 +18,10 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
internal class Benchmark : IDisposable
|
|
||||||
{
|
|
||||||
private readonly Stopwatch timer = new Stopwatch();
|
|
||||||
private readonly string benchmarkName;
|
|
||||||
|
|
||||||
public Benchmark(string benchmarkName) {
|
|
||||||
this.benchmarkName = benchmarkName;
|
|
||||||
timer.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() {
|
|
||||||
timer.Stop();
|
|
||||||
Console.WriteLine($"{benchmarkName}: {timer.Elapsed.TotalSeconds:N2} sec");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public partial class TestRunner
|
public partial class TestRunner
|
||||||
{
|
{
|
||||||
|
// Test runner
|
||||||
private async Task runTest(string testPath, LoadOptions loadOptions = null) {
|
private async Task runTest(string testPath, LoadOptions loadOptions = null) {
|
||||||
// Android
|
// Android
|
||||||
var testFile = testPath + @"\" + Path.GetFileName(testPath) + ".so";
|
var testFile = testPath + @"\" + Path.GetFileName(testPath) + ".so";
|
||||||
@@ -126,66 +111,81 @@ namespace Il2CppInspector
|
|||||||
if (inspectors.Count == 0)
|
if (inspectors.Count == 0)
|
||||||
throw new Exception("Could not find any images in the IL2CPP binary");
|
throw new Exception("Could not find any images in the IL2CPP binary");
|
||||||
|
|
||||||
|
// End if we were only testing file load
|
||||||
|
if (!GenerateCpp && !GenerateCS && !GenerateDLL && !GenerateJSON && !GeneratePython)
|
||||||
|
return;
|
||||||
|
|
||||||
// Dump each image in the binary separately
|
// Dump each image in the binary separately
|
||||||
var imageTasks = inspectors.Select((il2cpp, i) => Task.Run(async () =>
|
var imageTasks = inspectors.Select((il2cpp, i) => Task.Run(async () =>
|
||||||
{
|
{
|
||||||
TypeModel model;
|
TypeModel model;
|
||||||
using (new Benchmark("Create .NET type model"))
|
using (new Benchmark("Create .NET type model"))
|
||||||
model = new TypeModel(il2cpp);
|
model = new TypeModel(il2cpp);
|
||||||
var appModelTask = Task.Run(() => {
|
|
||||||
using (new Benchmark("Create application model"))
|
Task<AppModel> appModelTask = null;
|
||||||
return new AppModel(model, makeDefaultBuild: false).Build(compiler: CppCompilerType.MSVC);
|
if (GenerateCpp || GenerateJSON || GeneratePython)
|
||||||
});
|
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 nameSuffix = i++ > 0 ? "-" + (i - 1) : "";
|
||||||
|
var generateTasks = new List<Task>();
|
||||||
var compareTasks = new List<Task>();
|
var compareTasks = new List<Task>();
|
||||||
|
|
||||||
var csTask = Task.Run(() => {
|
if (GenerateCS)
|
||||||
using (new Benchmark("Create C# code stubs"))
|
generateTasks.Add(Task.Run(() => {
|
||||||
new CSharpCodeStubs(model) {
|
using (new Benchmark("Create C# code stubs"))
|
||||||
ExcludedNamespaces = Constants.DefaultExcludedNamespaces,
|
new CSharpCodeStubs(model) {
|
||||||
SuppressMetadata = false,
|
ExcludedNamespaces = Constants.DefaultExcludedNamespaces,
|
||||||
MustCompile = true
|
SuppressMetadata = false,
|
||||||
}.WriteSingleFile(testPath + $@"\test-result{nameSuffix}.cs");
|
MustCompile = true
|
||||||
|
}.WriteSingleFile(testPath + $@"\test-result{nameSuffix}.cs");
|
||||||
|
|
||||||
compareTasks.Add(Task.Run(() => compareFiles(testPath, nameSuffix + ".cs", $"test-result{nameSuffix}.cs")));
|
compareTasks.Add(Task.Run(() => compareFiles(testPath, nameSuffix + ".cs", $"test-result{nameSuffix}.cs")));
|
||||||
});
|
}));
|
||||||
|
|
||||||
var dllTask = Task.Run(() => {
|
if (GenerateDLL)
|
||||||
using (new Benchmark("Create .NET assembly shims"))
|
generateTasks.Add(Task.Run(() => {
|
||||||
new AssemblyShims(model).Write(testPath + $@"\test-dll-result{nameSuffix}");
|
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}",
|
compareTasks.Add(Task.Run(() => compareBinaryFiles(testPath + $@"\test-dll-result{nameSuffix}",
|
||||||
testPath + @"\..\..\TestExpectedResults\dll-" + Path.GetFileName(testPath) + nameSuffix)));
|
testPath + @"\..\..\TestExpectedResults\dll-" + Path.GetFileName(testPath) + nameSuffix)));
|
||||||
});
|
}));
|
||||||
|
|
||||||
var appModel = await appModelTask;
|
AppModel appModel = null;
|
||||||
|
if (appModelTask != null)
|
||||||
|
appModel = await appModelTask;
|
||||||
|
|
||||||
var jsonTask = Task.Run(() => {
|
if (GenerateJSON || GeneratePython)
|
||||||
using (new Benchmark("Create JSON metadata"))
|
generateTasks.Add(Task.Run(() => {
|
||||||
new JSONMetadata(appModel)
|
using (new Benchmark("Create JSON metadata"))
|
||||||
.Write(testPath + $@"\test-result{nameSuffix}.json");
|
new JSONMetadata(appModel)
|
||||||
|
.Write(testPath + $@"\test-result{nameSuffix}.json");
|
||||||
|
|
||||||
compareTasks.Add(Task.Run(() => compareFiles(testPath, nameSuffix + ".json", $"test-result{nameSuffix}.json")));
|
compareTasks.Add(Task.Run(() => compareFiles(testPath, nameSuffix + ".json", $"test-result{nameSuffix}.json")));
|
||||||
});
|
}));
|
||||||
|
|
||||||
var cppTask = Task.Run(() => {
|
if (GenerateCpp || GeneratePython)
|
||||||
using (new Benchmark("Create C++ scaffolding"))
|
generateTasks.Add(Task.Run(() => {
|
||||||
new CppScaffolding(appModel)
|
using (new Benchmark("Create C++ scaffolding"))
|
||||||
.Write(testPath + $@"\test-cpp-result{nameSuffix}");
|
new CppScaffolding(appModel)
|
||||||
|
.Write(testPath + $@"\test-cpp-result{nameSuffix}");
|
||||||
|
|
||||||
compareTasks.Add(Task.Run(() => compareFiles(testPath, nameSuffix + ".h", $@"test-cpp-result{nameSuffix}\appdata\il2cpp-types.h")));
|
compareTasks.Add(Task.Run(() => compareFiles(testPath, nameSuffix + ".h", $@"test-cpp-result{nameSuffix}\appdata\il2cpp-types.h")));
|
||||||
});
|
}));
|
||||||
|
|
||||||
var pyTask = Task.Run(() => {
|
if (GeneratePython)
|
||||||
var python = new PythonScript(appModel);
|
generateTasks.Add(Task.Run(() => {
|
||||||
foreach (var target in PythonScript.GetAvailableTargets())
|
var python = new PythonScript(appModel);
|
||||||
python.WriteScriptToFile(testPath + $@"\test-{target.ToLower()}{nameSuffix}.py", target,
|
foreach (var target in PythonScript.GetAvailableTargets())
|
||||||
testPath + $@"\test-cpp-result{nameSuffix}\appdata\il2cpp-types.h",
|
python.WriteScriptToFile(testPath + $@"\test-{target.ToLower()}{nameSuffix}.py", target,
|
||||||
testPath + $@"\test-result{nameSuffix}.json");
|
testPath + $@"\test-cpp-result{nameSuffix}\appdata\il2cpp-types.h",
|
||||||
});
|
testPath + $@"\test-result{nameSuffix}.json");
|
||||||
|
}));
|
||||||
|
|
||||||
await Task.WhenAll(csTask, dllTask, jsonTask, cppTask, pyTask);
|
await Task.WhenAll(generateTasks);
|
||||||
await Task.WhenAll(compareTasks);
|
await Task.WhenAll(compareTasks);
|
||||||
}));
|
}));
|
||||||
await Task.WhenAll(imageTasks);
|
await Task.WhenAll(imageTasks);
|
||||||
@@ -193,6 +193,10 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// Compare two folders full of binary files
|
// Compare two folders full of binary files
|
||||||
private void compareBinaryFiles(string resultFolder, string expectedFolder) {
|
private void compareBinaryFiles(string resultFolder, string expectedFolder) {
|
||||||
|
|
||||||
|
if (!EnableCompare)
|
||||||
|
return;
|
||||||
|
|
||||||
var expectedFiles = Directory.GetFiles(expectedFolder).Select(f => Path.GetFileName(f));
|
var expectedFiles = Directory.GetFiles(expectedFolder).Select(f => Path.GetFileName(f));
|
||||||
|
|
||||||
foreach (var file in expectedFiles) {
|
foreach (var file in expectedFiles) {
|
||||||
@@ -215,6 +219,10 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// We have to pass testPath rather than storing it as a field so that tests can be parallelized
|
// 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) {
|
private void compareFiles(string testPath, string expectedFilenameSuffix, string actualFilename) {
|
||||||
|
|
||||||
|
if (!EnableCompare)
|
||||||
|
return;
|
||||||
|
|
||||||
var expected = File.ReadAllLines(testPath + @"\..\..\TestExpectedResults\" + Path.GetFileName(testPath) + expectedFilenameSuffix);
|
var expected = File.ReadAllLines(testPath + @"\..\..\TestExpectedResults\" + Path.GetFileName(testPath) + expectedFilenameSuffix);
|
||||||
var actual = File.ReadAllLines(testPath + @"\" + actualFilename);
|
var actual = File.ReadAllLines(testPath + @"\" + actualFilename);
|
||||||
|
|
||||||
@@ -240,4 +248,21 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick benchmarking tool
|
||||||
|
internal class Benchmark : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Stopwatch timer = new Stopwatch();
|
||||||
|
private readonly string benchmarkName;
|
||||||
|
|
||||||
|
public Benchmark(string benchmarkName) {
|
||||||
|
this.benchmarkName = benchmarkName;
|
||||||
|
timer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
timer.Stop();
|
||||||
|
Console.WriteLine($"{benchmarkName}: {timer.Elapsed.TotalSeconds:N2} sec");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
Il2CppTests/TestRunnerConfig.cs
Normal file
21
Il2CppTests/TestRunnerConfig.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019-2021 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Il2CppInspector
|
||||||
|
{
|
||||||
|
// Configuration options for test runner
|
||||||
|
// Determines which integration tests to run
|
||||||
|
public partial class TestRunner
|
||||||
|
{
|
||||||
|
public const bool GenerateCS = true;
|
||||||
|
public const bool GenerateDLL = true;
|
||||||
|
public const bool GenerateJSON = true;
|
||||||
|
public const bool GenerateCpp = true;
|
||||||
|
public const bool GeneratePython = true;
|
||||||
|
|
||||||
|
public const bool EnableCompare = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user