예제 #1
0
        public static void TestLoadInPlugin(AirMusicTechTestSetup testSetup, List <string> files)
        {
            var serviceLocator = ServiceLocator.Default;

            FrontendInitializer.RegisterTypes(serviceLocator);
            FrontendInitializer.Initialize(serviceLocator);

            var remoteVstService = serviceLocator.ResolveType <RemoteVstService>();

            var plugin = new Plugin {
                PluginLocation = new PluginLocation {
                    DllPath = testSetup.PluginDll
                }
            };

            var pluginInstance = remoteVstService.GetInteractivePluginInstance(plugin, false);

            pluginInstance.LoadPlugin().Wait();

            foreach (var file in files)
            {
                Debug.WriteLine($"Loading {file} into plugin");
                pluginInstance.SetChunk(File.ReadAllBytes(file), false);
            }
        }
예제 #2
0
        public override async Task InitializeBeforeCreatingShellAsync()
        {
            // Non-async first
            FrontendInitializer.RegisterTypes(_serviceLocator);
            FrontendInitializer.Initialize(_serviceLocator);
            _frontendService            = _serviceLocator.ResolveType <FrontendService>();
            _splashScreenService.Action = "Loading configuration…";
            LoadConfiguration();


            _serviceLocator.ResolveType <IApplicationService>().StartProcessPool();

            _splashScreenService.Action = "Migrating database…";
            if (File.Exists(FileLocations.LegacyDatabasePath))
            {
                await TaskHelper.Run(() =>
                {
                    _serviceLocator.RegisterType <Ef6MigrationService, Ef6MigrationService>();
                    var migrationService = _serviceLocator.ResolveType <Ef6MigrationService>();
                    migrationService.MigrationProgressUpdated += delegate(object sender, MigrationProgessEventArgs args)
                    {
                        _splashScreenService.Action = "Migrating database…" + args.Progress;
                    };
                    Core.Core.UseDispatcher = false;
                    migrationService.LoadData();
                    migrationService.MigratePlugins();
                    Core.Core.UseDispatcher = true;
                }).ConfigureAwait(false);

                _serviceLocator.ResolveType <GlobalService>().RuntimeConfiguration.FileOverwriteMode =
                    PresetExportInfo.FileOverwriteMode.FORCE_OVERWRITE;
                _serviceLocator.ResolveType <GlobalService>().RuntimeConfiguration.FolderExportMode =
                    PresetExportInfo.FolderExportMode.ONE_LEVEL_LAST_BANK;
            }


            _splashScreenService.Action = "Initializing commands…";

            _frontendService.InitializeCommands();

            var dataPersistenceService = _serviceLocator.ResolveType <DataPersisterService>();
            var globalService          = _serviceLocator.ResolveType <GlobalService>();
            var pluginFiles            = dataPersistenceService.GetStoredPluginFiles();

            dataPersistenceService.LoadTypesCharacteristics();
            dataPersistenceService.LoadPreviewNotePlayers();

            foreach (var pluginFile in pluginFiles)
            {
                var plugin = dataPersistenceService.LoadPlugin(pluginFile);
                _splashScreenService.Action =
                    $"({pluginFiles.IndexOf(pluginFile) + 1}/{pluginFiles.Count}) Loading data for plugin {plugin.PluginName}";
                await dataPersistenceService.LoadPresetsForPlugin(plugin);

                globalService.Plugins.Add(plugin);
            }

            dataPersistenceService.LoadDontShowAgainDialogs();
            dataPersistenceService.LoadRememberMyChoiceResults();
        }
예제 #3
0
        public static (byte[], int) GetChunkFromPlugin(AirMusicTechTestSetup testSetup)
        {
            var serviceLocator = ServiceLocator.Default;

            FrontendInitializer.RegisterTypes(serviceLocator);
            FrontendInitializer.Initialize(serviceLocator);

            var remoteVstService = serviceLocator.ResolveType <RemoteVstService>();

            var plugin = new Plugin {
                PluginLocation = new PluginLocation {
                    DllPath = testSetup.PluginDll
                }
            };

            var pluginInstance = remoteVstService.GetInteractivePluginInstance(plugin, false);

            pluginInstance.LoadPlugin().Wait();


            return(pluginInstance.GetChunk(false), pluginInstance.Plugin.VstPluginId);
        }
예제 #4
0
        public void Setup(string className)
        {
            Core.Core.UseDispatcher = false;

            LogManager.AddDebugListener(false);
            var module2 = new CoreModule();

            module2.Initialize(_serviceLocator);
            var module = new MVVMModule();

            module.Initialize(_serviceLocator);
            RegisterOrchestraTypes();

            ApplicationDatabaseContext.DefaultDatabasePath = Path.Combine(Directory.GetCurrentDirectory(),
                                                                          $@"TestData\{className}\LegacyDatabases\LegacyDb.sqlite3");
            DataPersisterService.DefaultDataStoragePath =
                Path.Combine(Directory.GetCurrentDirectory(), $@"TestData\");

            PresetDataPersisterService.DefaultDatabaseFile = Path.Combine(Directory.GetCurrentDirectory(),
                                                                          $@"TestData\{className}\PresetData.sqlite3");

            Directory.CreateDirectory(DataPersisterService.DefaultPluginStoragePath);
            Directory.CreateDirectory(Path.GetDirectoryName(ApplicationDatabaseContext.DefaultDatabasePath));
            Directory.CreateDirectory(Path.GetDirectoryName(PresetDataPersisterService.DefaultDatabaseFile));


            File.Delete(ApplicationDatabaseContext.DefaultDatabasePath);
            File.Copy(@"Resources\PresetMagician.test.sqlite3", ApplicationDatabaseContext.DefaultDatabasePath);

            FrontendInitializer.RegisterTypes(_serviceLocator);
            FrontendInitializer.Initialize(_serviceLocator);

            var frontendService = _serviceLocator.ResolveType <FrontendService>();

            frontendService.InitializeCommands();
        }
예제 #5
0
        public static void Main(string[] args)
        {
            FrontendInitializer.RegisterTypes(ServiceLocator.Default);
            FrontendInitializer.Initialize(ServiceLocator.Default);
            var vendorPresetParserService = ServiceLocator.Default.ResolveType <VendorPresetParserService>();
            var logger = new RollingInMemoryLogListener();

            LogManager.AddListener(logger);

            var pluginTestDirectory = @"C:\Program Files\VSTPlugins";
            var testResults         = new List <PluginTestResult>();

            var presetParserDictionary = vendorPresetParserService.GetPresetHandlerListByPlugin();


            var testData       = ReadTestData();
            var ignoredPlugins = ReadIgnoredPlugins();

            List <string> IgnoredPresetParsers = new List <string>();

            IgnoredPresetParsers.Add("VoidPresetParser");

            var localLogger = new MiniConsoleLogger();
            var hasIgnored  = false;

            localLogger.SetConsoleLogLevelFilter(new HashSet <LogLevel> {
                LogLevel.Error, LogLevel.Warning
            });

            if (args.Length > 0)
            {
                foreach (var key in presetParserDictionary.Keys.ToList())
                {
                    if (!presetParserDictionary[key].PresetParserType.ToLower().Contains(args[0].ToLower()))
                    {
                        presetParserDictionary.Remove(key);
                        hasIgnored = true;
                    }
                }
            }

            foreach (var presetParserKeyValue in presetParserDictionary)
            {
                var presetParser = presetParserKeyValue.Value;
                var pluginId     = presetParserKeyValue.Key;

                if (IgnoredPresetParsers.Contains(presetParser.PresetParserType))
                {
                    continue;
                }

                if (IsIgnored(ignoredPlugins, presetParser.PresetParserType, pluginId))
                {
                    continue;
                }

                Console.Write(presetParser.PresetParserType + ": ");

                var start = DateTime.Now;

                var pluginLocation = new PluginLocation
                {
                    DllPath = @"C:\Program Files\VstPlugins\Foobar.dll", IsPresent = true
                };

                var plugin = new Plugin
                {
                    VstPluginId = pluginId, PluginLocation = pluginLocation,
                    PluginInfo  = new VstPluginInfoSurrogate
                    {
                        ProgramCount = 1, Flags = VstPluginFlags.ProgramChunks, PluginID = pluginId
                    }
                };

                var stubProcess = new StubVstHostProcess();
                stubProcess.PluginId = pluginId;

                var remoteInstance = new RemotePluginInstance(stubProcess, plugin);

                presetParser.DataPersistence = new NullPresetPersistence();
                presetParser.PluginInstance  = remoteInstance;
                presetParser.RootBank        = plugin.RootBank.First();
                presetParser.Logger.Clear();
                presetParser.Logger.MirrorTo(localLogger);

                var testResult = new PluginTestResult
                {
                    VendorPresetParser = presetParser.PresetParserType,
                    PluginId           = plugin.VstPluginId
                };

                double timeForNumPresets = 0;
                double timeForDoScan     = 0;
                double totalTime         = 0;
                try
                {
                    presetParser.Init();
                    testResult.ReportedPresets = presetParser.GetNumPresets();
                    timeForNumPresets          = (DateTime.Now - start).TotalSeconds;
                    start = DateTime.Now;
                    presetParser.DoScan().GetAwaiter().GetResult();
                    timeForDoScan = (DateTime.Now - start).TotalSeconds;
                    totalTime     = timeForNumPresets + timeForDoScan;
                }
                catch (Exception e)
                {
                    testResult.Error = "Errored";
                    Console.WriteLine(e.Message);
                    Console.WriteLine(e.StackTrace);
                }

                testResult.Presets = plugin.Presets.Count;

                var timePerPreset = (totalTime / testResult.Presets) * 1000;
                // ReSharper disable once LocalizableElement
                Console.WriteLine(
                    $"{testResult.Presets} parsed in {totalTime:F3}s (avg {timePerPreset:F3}ms / Preset, DoScan {timeForDoScan:F3}s, NumPresets {timeForNumPresets:F3}s");

                var testDataEntries    = GetTestDataEntries(testData, presetParser.PresetParserType, pluginId);
                var hasTestDataEntries = testDataEntries.Count > 0;
                var testDataOk         = true;
                foreach (var preset in plugin.Presets)
                {
                    if (preset.Metadata.BankPath == "")
                    {
                        testResult.BankMissing++;
                    }

                    foreach (var testDataEntry in testDataEntries.ToList())
                    {
                        if (preset.Metadata.PresetName == testDataEntry.ProgramName &&
                            preset.Metadata.BankPath == testDataEntry.BankPath)
                        {
                            var testFilename = PathUtils.SanitizeFilename(
                                testDataEntry.PresetParser + "." + preset.OriginalMetadata.PresetName +
                                ".testdata");
                            var myDocumentsTestDataFile = Path.Combine(GetPatchFilesDirectory(), testFilename);
                            var localTestDataFile       = Path.Combine("TestData", testFilename);


                            var presetHash = testDataEntry.Hash.TrimEnd();
                            if (preset.PresetHash != presetHash)
                            {
                                var fileMessage     = "";
                                var wrongPresetData = myDocumentsTestDataFile + ".wrong";
                                testDataOk = false;

                                if (File.Exists(myDocumentsTestDataFile))
                                {
                                    fileMessage = $"Original preset data in {myDocumentsTestDataFile}" +
                                                  Environment.NewLine +
                                                  $"Current (wrong) preset data in {wrongPresetData}";
                                }
                                else
                                {
                                    fileMessage =
                                        $"Original preset data not found (expected in {myDocumentsTestDataFile})" +
                                        Environment.NewLine +
                                        $"Current (wrong) preset data in {wrongPresetData}";
                                }

                                File.WriteAllBytes(wrongPresetData, LZ4Pickler.Unpickle(
                                                       NullPresetPersistence.PresetData[preset.OriginalMetadata.SourceFile]));
                                testResult.DetailedErrors.Add(
                                    $"Found preset {testDataEntry.ProgramName} with bank path " +
                                    $"{testDataEntry.BankPath} but the preset hashes were different. " +
                                    $"Expected hash {presetHash} but found hash {preset.PresetHash}" +
                                    Environment.NewLine + Environment.NewLine + $"{fileMessage}");
                            }
                            else
                            {
                                // Check if the file exists in the output directory
                                if (!File.Exists(myDocumentsTestDataFile))
                                {
                                    if (File.Exists(localTestDataFile))
                                    {
                                        File.Copy(localTestDataFile, myDocumentsTestDataFile);
                                    }
                                    else
                                    {
                                        File.WriteAllBytes(myDocumentsTestDataFile,
                                                           LZ4Pickler.Unpickle(
                                                               NullPresetPersistence.PresetData[preset.OriginalMetadata.SourceFile]));
                                    }
                                }
                                else
                                {
                                    if (!File.Exists(localTestDataFile))
                                    {
                                        testResult.DetailedErrors.Add(
                                            $"Warning: The preset data file {testFilename} exists in the documents " +
                                            "folder but not in the source folder. Copy from documents to git folder. " +
                                            "If already done, remember to clean the presetparsertest project.");
                                    }
                                }

                                var hash = HashUtils.getIxxHash(File.ReadAllBytes(myDocumentsTestDataFile));

                                if (hash != presetHash)
                                {
                                    testResult.DetailedErrors.Add(
                                        $"Warning: The preset data file {myDocumentsTestDataFile} exists but does not match the " +
                                        $"preset hash from the reference presets. Expected: {testDataEntry.Hash} found {hash}");
                                }
                            }

                            testDataEntries.Remove(testDataEntry);
                        }
                    }
                }

                if (testDataEntries.Count > 0)
                {
                    foreach (var missingTestDataEntry in testDataEntries)
                    {
                        var presetHash = missingTestDataEntry.Hash.TrimEnd();
                        testResult.DetailedErrors.Add(
                            $"Did not find preset {missingTestDataEntry.ProgramName} with bank path " +
                            $"{missingTestDataEntry.BankPath} and hash {presetHash}");
                    }

                    testResult.IsOK = false;
                }

                if (plugin.Presets.Count > 0)
                {
                    var randomPreset = plugin.Presets.OrderBy(qu => Guid.NewGuid()).First();
                    testResult.RndHash       = randomPreset.PresetHash;
                    testResult.RndPresetName = randomPreset.Metadata.PresetName;
                    testResult.RndBankPath   = randomPreset.Metadata.BankPath;
                }

                var mockFxp = Path.Combine(Directory.GetCurrentDirectory(), "mock.fxp");
                var fxp     = new FXP();
                fxp.ReadFile(Path.Combine(Directory.GetCurrentDirectory(), "test.fxp"));
                fxp.FxID = VstUtils.PluginIdNumberToIdString(pluginId);
                fxp.WriteFile(mockFxp);
                // Test additional banks
                var bankFile = new BankFile();
                bankFile.Path     = mockFxp;
                bankFile.BankName = "Default";

                plugin.AdditionalBankFiles.Clear();
                plugin.AdditionalBankFiles.Add(bankFile);

                bool additionalBankFileCountOk = false;


                if (presetParser.GetNumPresets() == testResult.ReportedPresets + 1)
                {
                    additionalBankFileCountOk = true;
                }
                else
                {
                    testResult.Error += " additionalBankFileCount failed";
                }

                plugin.Presets.Clear();
                NullPresetPersistence.PresetData.Clear();
                presetParser.DoScan().GetAwaiter().GetResult();

                var additionalBankFileScanOk = false;

                if (plugin.Presets.Count == testResult.Presets + 1)
                {
                    additionalBankFileScanOk = true;
                }
                else
                {
                    testResult.Error += " additionalBankFileScan failed";
                }

                bool bankMissingOk = false;
                if (NumBankMissingsOk.ContainsKey(testResult.PluginId))
                {
                    if (testResult.BankMissing <= NumBankMissingsOk[testResult.PluginId])
                    {
                        bankMissingOk = true;
                    }
                }
                else
                {
                    if (testResult.BankMissing < 2)
                    {
                        bankMissingOk = true;
                    }
                }

                if (hasTestDataEntries && testDataOk && testResult.Presets > 5 && bankMissingOk &&
                    testResult.Presets == testResult.ReportedPresets && additionalBankFileCountOk &&
                    additionalBankFileScanOk)
                {
                    testResult.IsOK = true;
                }

                testResults.Add(testResult);

                NullPresetPersistence.PresetData.Clear();
            }


            var consoleTable = ConsoleTable.From(from testRes in testResults
                                                 where testRes.IsOK == false
                                                 orderby testRes.Presets
                                                 select testRes);

            Console.WriteLine(consoleTable.ToMinimalString());

            foreach (var testRes in (from testRes in testResults
                                     where testRes.DetailedErrors.Count > 0
                                     orderby testRes.Presets
                                     select testRes))
            {
                Console.WriteLine(Environment.NewLine);
                Console.WriteLine($"Detailed Errors for {testRes.VendorPresetParser}");
                Console.WriteLine($"------------------------------------------------------------");

                foreach (var detailedError in testRes.DetailedErrors)
                {
                    Console.WriteLine($"Error #{testRes.DetailedErrors.IndexOf(detailedError)}: {detailedError}");
                }
            }

            Console.WriteLine($"Stuff left: {consoleTable.Rows.Count} / {presetParserDictionary.Count}");

            foreach (var data in GlobalMethodTimeLogger.GetTopMethods())
            {
                Console.WriteLine($"{data.Name}: {data.Duration.TotalSeconds.ToString()}ms");
            }

            if (hasIgnored)
            {
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
                Console.WriteLine("Warning: Filter active!!");
            }
        }
예제 #6
0
        static void Main()
        {
            /* var b = new byte[] {0x46, 0x61};
             *
             * Debug.WriteLine(RolandMemory.DecodeValueAsInt(b, 2, 7));
             * return;*/
            var culture = CultureInfo.GetCultureInfo("en-US");

            //Culture for any thread
            CultureInfo.DefaultThreadCurrentCulture = culture;

            //Culture for UI in any thread
            CultureInfo.DefaultThreadCurrentUICulture = culture;
            CultureInfo.CurrentUICulture = culture;
            CultureInfo.CurrentCulture   = culture;

            var doStructureDump = false;

            foreach (var configFile in Directory.EnumerateFiles(
                         @"DevData\Roland", "TestConfig.json",
                         SearchOption.AllDirectories))
            {
                /*if (!configFile.Contains("SYSTEM-1"))
                 * {
                 * continue;
                 * }*/

                var rolandTestConfig = RolandTestConfig.LoadTestConfig(configFile);

                var serviceLocator = ServiceLocator.Default;

                FrontendInitializer.RegisterTypes(serviceLocator);
                FrontendInitializer.Initialize(serviceLocator);

                var remoteVstService = serviceLocator.ResolveType <RemoteVstService>();

                var plugin = new Plugin {
                    PluginLocation = new PluginLocation {
                        DllPath = rolandTestConfig.Plugin
                    }
                };

                var pluginInstance = remoteVstService.GetInteractivePluginInstance(plugin, false);

                pluginInstance.LoadPlugin().Wait();

                var koaParser = new KoaBankFileParser(rolandTestConfig.ExportConfig.KoaFileHeader,
                                                      rolandTestConfig.ExportConfig.KoaPresetNameLength,
                                                      rolandTestConfig.ExportConfig.KoaPresetLength, rolandTestConfig.ExportConfig.KoaNumPresets);

                Directory.CreateDirectory(rolandTestConfig.OutputDirectory);

                var definitionCsv = Path.Combine(rolandTestConfig.OutputDirectory, "RolandScript.csv");
                var rolandScript  = ParseScript(rolandTestConfig, rolandTestConfig.ExportConfig);
                rolandScript.ConvertToCsv(definitionCsv);

                var converter = new RolandConverter(rolandTestConfig.ExportConfig);
                converter.LoadDefinitionFromCsvFile(definitionCsv);

                var hadOriginal = false;
                foreach (var patchDirectory in rolandTestConfig.PresetDirectories)
                {
                    Debug.WriteLine($"Processing patch directory {patchDirectory}");
                    foreach (var patchFile in Directory.EnumerateFiles(
                                 patchDirectory, "*.bin",
                                 SearchOption.AllDirectories))
                    {
                        var presets = koaParser.Parse(patchFile);
                        Debug.WriteLine($"Processed patch file {patchFile}, found {presets.Count} patches");

                        foreach (var preset in presets)
                        {
                            var currentPreset =
                                $"{Path.GetFileName(preset.BankFile)}.{preset.Index}.{PathUtils.SanitizeFilename(preset.PresetName.Trim())}";
                            var outputFile = Path.Combine(rolandTestConfig.OutputDirectory,
                                                          currentPreset);

                            var originalPatchDump = outputFile + ".originalpatchdump";

                            var okPluginPatchDumpFile = outputFile + ".okpluginpatchdump";

                            converter.SetFileMemory(preset.PresetData);

                            var memory = new RolandMemory();
                            memory.SetFileData(preset.PresetData);


                            Debug.WriteLine($"Processed {currentPreset}");

                            var sw = new Stopwatch();
                            sw.Start();

                            var exportedData = converter.Export();

                            try
                            {
                                var sortedDump = RolandPatchDump.SortDump(exportedData);

                                byte[] sortedPluginDump;
                                if (File.Exists(okPluginPatchDumpFile))
                                {
                                    sortedPluginDump =
                                        RolandPatchDump.SortDump(File.ReadAllBytes(okPluginPatchDumpFile));
                                }
                                else
                                {
                                    pluginInstance.SetChunk(sortedDump, false);

                                    sortedPluginDump = RolandPatchDump.SortDump(pluginInstance.GetChunk(false));
                                }

                                var pluginDumpVsGeneratedDumpErrors =
                                    RolandPatchDump.ComparePatchDumps(sortedPluginDump, sortedDump, rolandTestConfig, rolandScript);
                                var sortedDumpEqual = pluginDumpVsGeneratedDumpErrors.Count == 0;

                                var sortedOriginalDumpEqual             = true;
                                var sortedOriginalDumpEqualToPluginDump = false;
                                var originalDumpVsGeneratedDumpErrors   = new List <string>();
                                if (File.Exists(originalPatchDump))
                                {
                                    var sortedOriginal = RolandPatchDump.SortDump(File.ReadAllBytes(originalPatchDump));

                                    originalDumpVsGeneratedDumpErrors =
                                        RolandPatchDump.ComparePatchDumps(sortedOriginal, sortedDump, rolandTestConfig, rolandScript);

                                    sortedOriginalDumpEqual = originalDumpVsGeneratedDumpErrors.Count == 0;


                                    hadOriginal = true;
                                }

                                var patchDumpFile       = outputFile + ".patchdump";
                                var structureDumpFile   = outputFile + ".structure";
                                var pluginPatchDumpFile = outputFile + ".pluginpatchdump";


                                var presetDataFile = outputFile + ".presetdata";
                                File.WriteAllBytes(patchDumpFile, sortedDump);

                                File.WriteAllBytes(pluginPatchDumpFile, sortedPluginDump);
                                File.WriteAllBytes(presetDataFile, preset.PresetData);

                                if (File.Exists(originalPatchDump))
                                {
                                    memory.Load(originalPatchDump);
                                    var sortedOriginal = RolandPatchDump.SortDump(File.ReadAllBytes(originalPatchDump));
                                    File.WriteAllBytes(originalPatchDump + ".sorted", sortedOriginal);
                                }


                                if (doStructureDump || (!sortedDumpEqual || !sortedOriginalDumpEqual))
                                {
                                    File.WriteAllText(structureDumpFile, rolandScript.Dump(memory));
                                }

                                if ((!sortedDumpEqual || !sortedOriginalDumpEqual) &&
                                    !sortedOriginalDumpEqualToPluginDump)
                                {
                                    // Last resort: Compare the plugin dump against the sorted original dump because of "if float goes in, float comes out slightly different"

                                    Debug.WriteLine("Plugin Dump vs Generated Dump Errors");
                                    Debug.WriteLine("------------------------------------");
                                    Debug.WriteLine(string.Join(Environment.NewLine, pluginDumpVsGeneratedDumpErrors));

                                    Debug.WriteLine("Original Dump vs Generated Dump Errors");
                                    Debug.WriteLine("------------------------------------");
                                    Debug.WriteLine(string.Join(Environment.NewLine, originalDumpVsGeneratedDumpErrors));

                                    throw new Exception(
                                              $"Dumps not equal. sortedDumpEqual {sortedDumpEqual} sortedOriginalDumpEqual {sortedOriginalDumpEqual}");
                                }

                                if (!File.Exists(okPluginPatchDumpFile))
                                {
                                    File.Copy(pluginPatchDumpFile, okPluginPatchDumpFile);
                                }
                            }
                            catch (Exception e)
                            {
                                var structureDumpFile = outputFile + ".structure";
                                File.WriteAllText(structureDumpFile, rolandScript.Dump(memory));
                                throw e;
                            }

                            Debug.WriteLine($"{sw.Elapsed.TotalMilliseconds} ms");
                        }
                    }
                }

                if (!hadOriginal)
                {
                    throw new Exception($"Had no original to test against for config {configFile}");
                }
            }

            // return;
        }