public void ValidateTargetsME3() { GlobalTest.Init(); var root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME3); Console.WriteLine("TargetTesting: Game directories folder for ME3: " + root); var normal = Path.Combine(root, "normal"); //correct game GameTarget gt = new GameTarget(Mod.MEGame.ME3, normal, false); var failureReason = gt.ValidateTarget(); Assert.IsNull(failureReason, "GameTarget for ME3 Normal should not have returned a failure string when validating against the correct game. Failure reason returned: " + failureReason); Assert.IsTrue(gt.IsValid, "GameTarget for ME3 Normal should have been marked as valid when validating against the correct game, but it wasn't"); //wrong game gt = new GameTarget(Mod.MEGame.ME1, normal, false); failureReason = gt.ValidateTarget(); Assert.IsNotNull(failureReason, "GameTarget for ME3 Normal should have returned a failure string when validating against the wrong game (ME1), but none was returned"); Assert.IsFalse(gt.IsValid, "GameTarget for ME3 Normal should have been marked as invalid when validating against the wrong game (ME1), but wasn't"); gt = new GameTarget(Mod.MEGame.ME2, normal, false); failureReason = gt.ValidateTarget(); Assert.IsNotNull(failureReason, "GameTarget for ME3 Normal should have returned a failure string when validating against the wrong game (ME2), but none was returned"); Assert.IsFalse(gt.IsValid, "GameTarget for ME3 Normal should have been marked as invalid when validating against the wrong game (ME2), but wasn't"); }
public void TestBuildingExtractionQueues() { GlobalTest.Init(); Console.WriteLine("Fetching third party services"); App.ThirdPartyImportingService = OnlineContent.FetchThirdPartyImportingService(); App.ThirdPartyIdentificationService = OnlineContent.FetchThirdPartyIdentificationManifest(); var compressedModsDirectory = Path.Combine(GlobalTest.GetTestDataDirectory(), "compressedmods"); List <Mod> modsFoundInArchive = new List <Mod>(); void addModCallback(Mod m) { Console.WriteLine($"Found mod in archive: {m.ModName}"); modsFoundInArchive.Add(m); } void failedModCallback(Mod m) { //Console.WriteLine($"A mod failed to load. This may be expected: {m.ModName}"); } void logMessageCallback(string m) { Console.WriteLine(m); } #region Get Targets List <GameTarget> targets = new List <GameTarget>(); var root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME1); foreach (var d in Directory.GetDirectories(root)) { GameTarget gt = new GameTarget(Mod.MEGame.ME1, d, false, false); gt.ValidateTarget(); if (gt.IsValid) { targets.Add(gt); } } root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME2); foreach (var d in Directory.GetDirectories(root)) { GameTarget gt = new GameTarget(Mod.MEGame.ME2, d, false, false); gt.ValidateTarget(); if (gt.IsValid) { targets.Add(gt); } } root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME3); foreach (var d in Directory.GetDirectories(root)) { GameTarget gt = new GameTarget(Mod.MEGame.ME3, d, false, false); gt.ValidateTarget(); if (gt.IsValid) { targets.Add(gt); } } #endregion //Compressed Mods foreach (var archive in Directory.GetFiles(compressedModsDirectory)) { modsFoundInArchive.Clear(); var realArchiveInfo = GlobalTest.ParseRealArchiveAttributes(archive); Console.WriteLine($@"Inspecting archive: { archive}"); ModArchiveImporter.InspectArchive(archive, addModCallback, failedModCallback, logMessageCallback, forcedMD5: realArchiveInfo.md5, forcedSize: realArchiveInfo.size); var archiveZ = new SevenZipExtractor(archive); foreach (var mod in modsFoundInArchive) { bool altsOn = false; while (true) { if (altsOn) { foreach (var job in mod.InstallationJobs) { List <string> selectedGroups = new List <string>(); foreach (var altfile in job.AlternateFiles) { if (altfile.GroupName != null) { if (selectedGroups.Contains(altfile.GroupName)) { continue; //we already did first time of this. I know that's a weak test case... } selectedGroups.Add(altfile.GroupName); } altfile.IsSelected = true; } } } var refs = mod.GetAllRelativeReferences(!mod.IsVirtualized, archiveZ); //test //validate references are actually in this archive foreach (var fileREf in refs) { var expectedPath = FilesystemInterposer.PathCombine(mod.IsInArchive, mod.ModPath, fileREf); //var expectedPath = fileREf; var inArchiveFile = archiveZ.ArchiveFileData.FirstOrDefault(x => x.FileName == expectedPath); Assert.IsNotNull(inArchiveFile.FileName, "Relative referenced file was not found in archive: " + fileREf); } //size test Assert.AreNotEqual(0, mod.SizeRequiredtoExtract, "Archive extraction size is zero! For file " + archive); var targetsForMod = targets.Where(x => x.Game == mod.Game).ToList(); foreach (var target in targetsForMod) { var queue = mod.GetInstallationQueues(target); foreach (var jobMapping in queue.Item1) { foreach (var unpackedItem in jobMapping.Value.unpackedJobMapping) { string sourceFile; if (jobMapping.Key.JobDirectory == null || unpackedItem.Value.IsFullRelativeFilePath) { sourceFile = FilesystemInterposer.PathCombine(mod.IsInArchive, mod.ModPath, unpackedItem.Value.FilePath); } else { sourceFile = FilesystemInterposer.PathCombine(mod.IsInArchive, mod.ModPath, jobMapping.Key.JobDirectory, unpackedItem.Value.FilePath); } Assert.IsTrue(archiveZ.ArchiveFileNames.Contains(sourceFile), "Archive should contain a file specified by mod (mod is valid) but does not appear to. File: " + sourceFile); } } } if (!altsOn) { altsOn = true; } else { break; } } } } //EXE mods var exeModsDirectory = Path.Combine(GlobalTest.GetTestDataDirectory(), "exemods"); if (Directory.Exists(exeModsDirectory)) { foreach (var exe in Directory.GetFiles(exeModsDirectory)) { modsFoundInArchive.Clear(); //var realArchiveInfo = GlobalTest.ParseRealArchiveAttributes(exe); Console.WriteLine($@"Inspecting exe: { exe}"); ModArchiveImporter.InspectArchive(exe, addModCallback, failedModCallback, logMessageCallback); var archiveZ = new SevenZipExtractor(exe, InArchiveFormat.Nsis); foreach (var mod in modsFoundInArchive) { foreach (var job in mod.InstallationJobs) { List <string> selectedGroups = new List <string>(); foreach (var altfile in job.AlternateFiles) { if (altfile.GroupName != null) { if (selectedGroups.Contains(altfile.GroupName)) { continue; //we already did first time of this. I know that's a weak test case... } selectedGroups.Add(altfile.GroupName); } altfile.IsSelected = true; } } var refs = mod.GetAllRelativeReferences(false, archiveZ); //test and get refs. exe mods will always be virtualized as they won't have a moddesc.ini file. //exe mods remap to subconetns //same code as Mod-Extraction.cs foreach (var fileREf in refs) { var expectedPath = FilesystemInterposer.PathCombine(mod.IsInArchive, mod.ModPath, fileREf); //var expectedPath = fileREf; var inArchiveFile = archiveZ.ArchiveFileData.FirstOrDefault(x => x.FileName == expectedPath); Assert.IsNotNull(inArchiveFile.FileName, "Relative referenced file was not found in archive: " + fileREf); } mod.ExtractFromArchive(exe, "", false, testRun: true); } } } else { Console.WriteLine("No exemods directory found. This section of testing will be skipped"); } }
public void TestASIManager() { GlobalTest.Init(); Random random = new Random(); Console.WriteLine(@"Loading ASI Manager Manifest"); ASIManager.LoadManifest(); var games = new[] { Mod.MEGame.ME1, Mod.MEGame.ME2, Mod.MEGame.ME3 }; foreach (var game in games) { var root = GlobalTest.GetTestGameFoldersDirectory(game); var normal = Path.Combine(root, "normal"); GameTarget gt = new GameTarget(game, normal, true, false); var asiDir = MEDirectories.ASIPath(gt); if (Directory.Exists(asiDir)) { // Clean slate Utilities.DeleteFilesAndFoldersRecursively(asiDir); } var asisForGame = ASIManager.GetASIModsByGame(game); // 1: Test Installs of upgrades of versions foreach (var asi in asisForGame) { // Install every version of an ASI and then ensure only one ASI of that type exists in the directory. foreach (var v in asi.Versions) { var sourceBools = new bool?[] { true, false, null }; //online, local, let app decide foreach (var sourceBool in sourceBools) { // INSTALL FROM SOURCE Console.WriteLine($@"Install source variable: {sourceBool}"); Assert.IsTrue(ASIManager.InstallASIToTarget(v, gt, sourceBool), $"Installation of ASI failed: {v.Name}"); Assert.AreEqual(1, Directory.GetFiles(asiDir).Length, "The count of files in the ASI directory is not 1 after install of an ASI!"); // Check is installed var installedASIs = gt.GetInstalledASIs().OfType <KnownInstalledASIMod>().ToList(); Assert.AreEqual(1, installedASIs.Count, "The amount of installed ASIs as fetched by GameTarget GetInstalledASIs() is not equal to 1!"); // Check it maps to the correct one. var instASI = installedASIs.First(); Assert.AreEqual(v, instASI.AssociatedManifestItem, "The parsed installed ASI does not match the one we fed to ASIManager.InstallASIToTarget()!"); // Rename it to something random so the next version has to find it by the hash and not the filename. var newPath = Path.Combine(asiDir, Guid.NewGuid() + ".asi"); File.Move(instASI.InstalledPath, newPath, false); // Ensure it still can be found. installedASIs = gt.GetInstalledASIs().OfType <KnownInstalledASIMod>().ToList(); Assert.AreEqual(1, installedASIs.Count, "The amount of installed ASIs as fetched by GameTarget GetInstalledASIs() is not equal to 1 after renaming the file!"); // Make multiple clones, to ensure all old ones get deleted on upgrades. for (int i = 0; i < 5; i++) { var clonePath = Path.Combine(asiDir, instASI.AssociatedManifestItem.InstalledPrefix + i + ".asi"); File.Copy(newPath, clonePath, true); } installedASIs = gt.GetInstalledASIs().OfType <KnownInstalledASIMod>().ToList(); Assert.AreEqual(6, installedASIs.Count, "The amount of installed ASIs as fetched by GameTarget GetInstalledASIs() is not equal to 6 after cloning the file 5 times!"); } } var finalASIsPreRandomization = gt.GetInstalledASIs(); int randomCount = 0; foreach (var iam in finalASIsPreRandomization) { // Test randomly editing it. byte[] randomData = new byte[256]; random.NextBytes(randomData); File.WriteAllBytes(iam.InstalledPath, randomData); randomCount++; var unknownInstalledASIs = gt.GetInstalledASIs().OfType <UnknownInstalledASIMod>().ToList(); Assert.AreEqual(randomCount, unknownInstalledASIs.Count, "Writing random bytes to installed ASI made amount of installed ASIs not correct!"); } foreach (var v in finalASIsPreRandomization) { // Test uninstall and remove Assert.IsTrue(v.Uninstall(), $"ASI failed to uninstall: {v.InstalledPath}"); } Assert.AreEqual(0, Directory.GetFiles(asiDir).Length, "Leftover files remain after uninstalling all ASIs from target"); } } }
public void TestM3DirectoryResults() { GlobalTest.Init(); List <GameTarget> targets = new List <GameTarget>(); var root = GlobalTest.GetTestGameFoldersDirectory(MEGame.ME1); foreach (var d in Directory.GetDirectories(root)) { GameTarget gt = new GameTarget(MEGame.ME1, d, false, false); gt.ValidateTarget(); if (gt.IsValid) { targets.Add(gt); } } root = GlobalTest.GetTestGameFoldersDirectory(MEGame.ME2); foreach (var d in Directory.GetDirectories(root)) { GameTarget gt = new GameTarget(MEGame.ME2, d, false, false); gt.ValidateTarget(); if (gt.IsValid) { targets.Add(gt); } } root = GlobalTest.GetTestGameFoldersDirectory(MEGame.ME3); foreach (var d in Directory.GetDirectories(root)) { GameTarget gt = new GameTarget(MEGame.ME3, d, false, false); gt.ValidateTarget(); if (gt.IsValid) { targets.Add(gt); } } foreach (var target in targets) { string expectedDLCPath; string expectedASIPath; string expectedBioGamePath; string expectedCookedPath; string expectedExecutableDir; if (target.Game == MEGame.ME1) { expectedDLCPath = Path.Combine(target.TargetPath, @"DLC"); expectedASIPath = Path.Combine(target.TargetPath, @"Binaries", @"asi"); expectedBioGamePath = Path.Combine(target.TargetPath, @"BioGame"); expectedCookedPath = Path.Combine(target.TargetPath, @"BioGame", @"CookedPC"); expectedExecutableDir = Path.Combine(target.TargetPath, @"Binaries"); } else if (target.Game == MEGame.ME2) { expectedDLCPath = Path.Combine(target.TargetPath, @"BioGame", @"DLC"); expectedASIPath = Path.Combine(target.TargetPath, @"Binaries", @"asi"); expectedBioGamePath = Path.Combine(target.TargetPath, @"BioGame"); expectedCookedPath = Path.Combine(target.TargetPath, @"BioGame", @"CookedPC"); expectedExecutableDir = Path.Combine(target.TargetPath, @"Binaries"); } else { expectedDLCPath = Path.Combine(target.TargetPath, @"BIOGame", @"DLC"); expectedASIPath = Path.Combine(target.TargetPath, @"Binaries", @"Win32", @"asi"); expectedBioGamePath = Path.Combine(target.TargetPath, @"BIOGame"); expectedCookedPath = Path.Combine(target.TargetPath, @"BIOGame", @"CookedPCConsole"); expectedExecutableDir = Path.Combine(target.TargetPath, @"Binaries", @"Win32"); } Assert.AreEqual(expectedDLCPath, M3Directories.GetDLCPath(target)); Assert.AreEqual(expectedASIPath, M3Directories.GetASIPath(target)); Assert.AreEqual(expectedBioGamePath, M3Directories.GetBioGamePath(target)); Assert.AreEqual(expectedCookedPath, M3Directories.GetCookedPath(target)); Assert.AreEqual(expectedExecutableDir, M3Directories.GetExecutableDirectory(target)); } }
public void TestBuildingExtractionQueues() { GlobalTest.Init(); Console.WriteLine("Fetching third party services"); App.ThirdPartyImportingService = OnlineContent.FetchThirdPartyImportingService(); App.ThirdPartyIdentificationService = OnlineContent.FetchThirdPartyIdentificationManifest(); var compressedModsDirectory = Path.Combine(GlobalTest.GetTestDataDirectory(), "compressedmods"); List <Mod> modsFoundInArchive = new List <Mod>(); void addModCallback(Mod m) { Console.WriteLine($"Found mod in archive: {m.ModName}"); modsFoundInArchive.Add(m); } void failedModCallback(Mod m) { //Console.WriteLine($"A mod failed to load. This may be expected: {m.ModName}"); } void logMessageCallback(string m) { Console.WriteLine(m); } #region Get Targets List <GameTarget> targets = new List <GameTarget>(); var root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME1); foreach (var d in Directory.GetDirectories(root)) { GameTarget gt = new GameTarget(Mod.MEGame.ME1, d, false, false); if (gt.IsValid) { targets.Add(gt); } } root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME2); foreach (var d in Directory.GetDirectories(root)) { GameTarget gt = new GameTarget(Mod.MEGame.ME2, d, false, false); if (gt.IsValid) { targets.Add(gt); } } root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME3); foreach (var d in Directory.GetDirectories(root)) { GameTarget gt = new GameTarget(Mod.MEGame.ME3, d, false, false); if (gt.IsValid) { targets.Add(gt); } } #endregion foreach (var archive in Directory.GetFiles(compressedModsDirectory)) { modsFoundInArchive.Clear(); var realArchiveInfo = GlobalTest.ParseRealArchiveAttributes(archive); Console.WriteLine($"Inspecting archive: { archive}"); ModArchiveImporter.InspectArchive(archive, addModCallback, failedModCallback, logMessageCallback, forcedMD5: realArchiveInfo.md5, forcedSize: realArchiveInfo.size); var archiveZ = new SevenZipExtractor(archive); foreach (var mod in modsFoundInArchive) { mod.GetAllRelativeReferences(archiveZ); var targetsForMod = targets.Where(x => x.Game == mod.Game).ToList(); foreach (var target in targetsForMod) { mod.GetInstallationQueues(target); } } } }