private void BundleRun(TestProjectFixture fixture, string publishPath) { var hostName = BundleHelper.GetHostName(fixture); // Run the App normally RunTheApp(Path.Combine(publishPath, hostName)); // Bundle to a single-file string singleFile = BundleHelper.BundleApp(fixture); // Run the extracted app RunTheApp(singleFile); }
private void btnInfo_Click(object sender, EventArgs e) { if (BundleInst == null || cboxBundleContents.SelectedItem == null) { return; } var index = cboxBundleContents.SelectedIndex; var dirInf = BundleHelper.GetDirInfo(BundleInst.file, index); var bunAssetName = dirInf.name; //When we make a modification to an assets file in the bundle, //we replace the assets file in the manager. This way, all we //have to do is not reload from the bundle if our assets file //has been modified MemoryStream assetStream; if (!ModifiedFiles.ContainsKey(bunAssetName)) { var assetData = BundleHelper.LoadAssetDataFromBundle(BundleInst.file, index); assetStream = new MemoryStream(assetData); } else { //unused if the file already exists assetStream = null; } //warning: does not update if you import an assets file onto //a file that wasn't originally an assets file var isAssetsFile = BundleInst.file.IsAssetsFile(BundleInst.file.reader, dirInf); if (isAssetsFile) { var assetMemPath = Path.Combine(BundleInst.path, bunAssetName); var fileInst = Am.LoadAssetsFile(assetStream, assetMemPath, true); if (!LoadOrAskCldb(fileInst)) { return; } var info = new AssetsViewer(Am, fileInst, true); info.Closing += AssetsViewerClosing; info.Show(); } else { MsgBoxUtils.ShowErrorDialog("This doesn't seem to be a valid assets file."); } }
private void Bundle_extraction_is_reused() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var appName = Path.GetFileNameWithoutExtension(hostName); string publishPath = BundleHelper.GetPublishPath(fixture); // Publish the bundle var bundleDir = BundleHelper.GetBundleDir(fixture); var bundler = new Microsoft.NET.HostModel.Bundle.Bundler(hostName, bundleDir.FullName); string singleFile = bundler.GenerateBundle(publishPath); // Create a directory for extraction. var extractBaseDir = BundleHelper.GetExtractDir(fixture); // Run the bunded app for the first time, and extract files to // $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); string extractPath = Path.Combine(extractBaseDir.FullName, appName, bundler.BundleManifest.BundleID); var extractDir = new DirectoryInfo(extractPath); extractDir.Refresh(); DateTime firstWriteTime = extractDir.LastWriteTimeUtc; while (DateTime.Now == firstWriteTime) { Thread.Sleep(1); } // Run the bundled app again (reuse extracted files) Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); extractDir.Should().NotBeModifiedAfter(firstWriteTime); }
private void Bundle_Probe_Not_Passed_For_Non_Single_File_App() { var fixture = sharedTestState.TestFixture.Copy(); string appExe = BundleHelper.GetHostPath(fixture); Command.Create(appExe) .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("No BUNDLE_PROBE"); }
private void Bundle_Probe_Passed_For_Single_File_App() { var fixture = sharedTestState.TestFixture.Copy(); string singleFile = BundleHelper.BundleApp(fixture); Command.Create(singleFile, "SingleFile") .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("BUNDLE_PROBE OK"); }
private void Bundle_extraction_can_recover_missing_files() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var appName = Path.GetFileNameWithoutExtension(hostName); string publishPath = BundleHelper.GetPublishPath(fixture); // Publish the bundle var bundleDir = BundleHelper.GetBundleDir(fixture); var bundler = new Bundler(hostName, bundleDir.FullName, BundleOptions.BundleAllContent); string singleFile = BundleHelper.GenerateBundle(bundler, publishPath); // Compute bundled files List <string> bundledFiles = bundler.BundleManifest.Files.Select(file => file.RelativePath).ToList(); // Create a directory for extraction. var extractBaseDir = BundleHelper.GetExtractDir(fixture); string extractPath = Path.Combine(extractBaseDir.FullName, appName, bundler.BundleManifest.BundleID); var extractDir = new DirectoryInfo(extractPath); // Run the bunded app for the first time, and extract files to // $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); bundledFiles.ForEach(file => File.Delete(Path.Combine(extractPath, file))); extractDir.Should().Exist(); extractDir.Should().NotHaveFiles(bundledFiles); // Run the bundled app again (recover deleted files) Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); extractDir.Should().HaveFiles(bundledFiles); }
private async void Start() { try { if (Application.unityVersion != "2017.1.0p5") { Log.Warning($"当前版本:{Application.unityVersion}, 最好使用运行指南推荐版本!"); } SynchronizationContext.SetSynchronizationContext(this.contex); DontDestroyOnLoad(gameObject); Game.EventSystem.Add(DLLType.Model, typeof(Init).Assembly); Game.Scene.AddComponent <GlobalConfigComponent>(); Game.Scene.AddComponent <NetOuterComponent>(); Game.Scene.AddComponent <ResourcesComponent>(); Game.Scene.AddComponent <PlayerComponent>(); Game.Scene.AddComponent <UnitComponent>(); Game.Scene.AddComponent <ClientFrameComponent>(); //Game.Scene.AddComponent<UIComponent>(); // 下载ab包 await BundleHelper.DownloadBundle(); // 加载配置 Game.Scene.GetComponent <ResourcesComponent>().LoadBundle("config.unity3d"); Game.Scene.AddComponent <ConfigComponent>(); Game.Scene.GetComponent <ResourcesComponent>().UnloadBundle("config.unity3d"); Game.Scene.AddComponent <OpcodeTypeComponent>(); Game.Scene.AddComponent <MessageDispatherComponent>(); uiLogin = GameObject.Find("LoginCanvas"); uiLobby = GameObject.Find("LobbyCanvas"); uiLobby.SetActive(false); login.GetComponent <Button>().onClick.Add(OnLogin); enterMap.GetComponent <Button>().onClick.Add(EnterMap); UnitConfig unitConfig = (UnitConfig)Game.Scene.GetComponent <ConfigComponent>().Get(typeof(UnitConfig), 1001); Log.Debug($"config {JsonHelper.ToJson(unitConfig)}"); Game.EventSystem.Run(EventIdType.InitSceneStart); } catch (Exception e) { Log.Error(e.ToString()); } }
public void CodeBaseThrows() { var fixture = sharedTestState.TestFixture.Copy(); var singleFile = BundleHelper.BundleApp(fixture); Command.Create(singleFile, "codebase") .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("CodeBase NotSupported"); }
public void TestFilesNeverBundled(BundleOptions options) { var fixture = sharedTestState.TestFixture.Copy(); var appBaseName = BundleHelper.GetAppBaseName(fixture); string publishPath = BundleHelper.GetPublishPath(fixture); // Make up a app.runtimeconfig.dev.json file in the publish directory. File.Copy(Path.Combine(publishPath, $"{appBaseName}.runtimeconfig.json"), Path.Combine(publishPath, $"{appBaseName}.runtimeconfig.dev.json")); var bundler = BundleHelper.Bundle(fixture, options); bundler.BundleManifest.Contains($"{appBaseName}.runtimeconfig.dev.json").Should().BeFalse(); }
public SharedTestState() { RepoDirectories = new RepoDirectoriesProvider(); TestFixture = new TestProjectFixture("HammerServiceApp", RepoDirectories); TestFixture .EnsureRestoredForRid(TestFixture.CurrentRid, RepoDirectories.CorehostPackages) .PublishProject(runtime: TestFixture.CurrentRid, outputDirectory: BundleHelper.GetPublishPath(TestFixture)); ServiceFixture = new TestProjectFixture("ServicedLocation", RepoDirectories, assemblyName: "Location"); ServiceFixture .EnsureRestored(RepoDirectories.CorehostPackages) .PublishProject(outputDirectory: BundleHelper.GetPublishPath(ServiceFixture)); }
private void BundleRun(TestProjectFixture fixture, string publishDir, string singleFileDir) { var hostName = BundleHelper.GetHostName(fixture); // Run the App normally RunTheApp(Path.Combine(publishDir, hostName)); // Bundle to a single-file Bundler bundler = new Bundler(hostName, singleFileDir); string singleFile = bundler.GenerateBundle(publishDir); // Run the extracted app RunTheApp(singleFile); }
private async void BtnInfo_Click(object?sender, RoutedEventArgs e) { //when dependency loading is supported: //make sure cab:// dependencies in the bundle are loaded as well if (bundleInst != null && comboBox.SelectedItem != null) { int index = (int)((ComboBoxItem)comboBox.SelectedItem).Tag; string bunAssetName = bundleInst.file.bundleInf6.dirInf[index].name; //when we make a modification to an assets file in the bundle, //we replace the assets file in the manager. this way, all we //have to do is not reload from the bundle if our assets file //has been modified MemoryStream assetStream; if (!newFiles.ContainsKey(bunAssetName)) { byte[] assetData = BundleHelper.LoadAssetDataFromBundle(bundleInst.file, index); assetStream = new MemoryStream(assetData); } else { //unused if the file already exists assetStream = null; } //warning: does not update if you import an assets file onto //a file that wasn't originally an assets file var fileInf = BundleHelper.GetDirInfo(bundleInst.file, index); bool isAssetsFile = bundleInst.file.IsAssetsFile(bundleInst.file.reader, fileInf); if (isAssetsFile) { string assetMemPath = Path.Combine(bundleInst.path, bunAssetName); AssetsFileInstance fileInst = am.LoadAssetsFile(assetStream, assetMemPath, true); am.LoadClassDatabaseFromPackage(fileInst.file.typeTree.unityVersion); InfoWindow info = new InfoWindow(am, fileInst, bunAssetName, true); info.Closing += InfoWindowClosing; info.Show(); } else { await MessageBoxUtil.ShowDialog(this, "Error", "This doesn't seem to be a valid assets file.\n" + "If you want to export a non-assets file,\n" + "use Export."); } } }
private void BundleRun(TestProjectFixture fixture, string publishPath, string singleFileDir) { var hostName = BundleHelper.GetHostName(fixture); // Run the App normally RunTheApp(Path.Combine(publishPath, hostName)); // Bundle to a single-file // Bundle all content, until the host can handle other scenarios. Bundler bundler = new Bundler(hostName, singleFileDir, BundleOptions.BundleAllContent); string singleFile = BundleHelper.GenerateBundle(bundler, publishPath); // Run the extracted app RunTheApp(singleFile); }
public void TestBundlingSymbols(BundleOptions options) { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var appName = Path.GetFileNameWithoutExtension(hostName); string publishPath = BundleHelper.GetPublishPath(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); var bundler = new Bundler(hostName, bundleDir.FullName, options); BundleHelper.GenerateBundle(bundler, publishPath); bundler.BundleManifest.Contains($"{appName}.pdb").Should().Be(options.HasFlag(BundleOptions.BundleSymbolFiles)); }
public void TestNetCoreApp3xApp(int minorVersion) { var fixture = (minorVersion == 0) ? sharedTestState.TestFixture30.Copy() : sharedTestState.TestFixture31.Copy(); var singleFile = BundleHelper.BundleApp(fixture, targetFrameworkVersion: new Version(3, minorVersion)); Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World!"); }
public void AppContext_Native_Search_Dirs_Contains_Bundle_And_Extraction_Dirs() { var fixture = sharedTestState.TestFixture.Copy(); Bundler bundler = BundleHelper.BundleApp(fixture, out string singleFile, BundleOptions.BundleNativeBinaries); string extractionDir = BundleHelper.GetExtractionDir(fixture, bundler).Name; string bundleDir = BundleHelper.GetBundleDir(fixture).FullName; Command.Create(singleFile, "native_search_dirs") .CaptureStdErr() .CaptureStdOut() .Execute() .Should().Pass() .And.HaveStdOutContaining(extractionDir) .And.HaveStdOutContaining(bundleDir); }
public static Bundler BundleSelfContainedApp( TestProjectFixture testFixture, out string singleFile, BundleOptions options = BundleOptions.None, Version targetFrameworkVersion = null, bool disableCompression = false) { UseSingleFileSelfContainedHost(testFixture); if (targetFrameworkVersion == null || targetFrameworkVersion >= new Version(6, 0)) { options |= BundleOptions.EnableCompression; } return(BundleHelper.BundleApp(testFixture, out singleFile, options, targetFrameworkVersion)); }
public void TestBundlingNativeBinaries(BundleOptions options) { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var hostfxr = Path.GetFileName(fixture.TestProject.HostFxrDll); string publishPath = BundleHelper.GetPublishPath(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); var bundler = new Bundler(hostName, bundleDir.FullName, options); BundleHelper.GenerateBundle(bundler, publishPath); bundler.BundleManifest.Contains($"{hostfxr}").Should().Be(options.HasFlag(BundleOptions.BundleNativeBinaries)); }
private void SingleFile_Apps_Are_Serviced() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // On Windows, the hammer servicing location is %ProgramFiles%\coreservicing. // Since writing to this location requires administrative privilege, we do not run the test on Windows. // On Unix systems, the servicing location is obtained from the environment variable $CORE_SERVICING. return; } var fixture = sharedTestState.TestFixture.Copy(); var servicer = sharedTestState.ServiceFixture.Copy(); // Annotate the app as servicible, and then publish to a single-file. string depsjson = BundleHelper.GetDepsJsonPath(fixture); File.WriteAllText(depsjson, File.ReadAllText(depsjson).Replace("\"serviceable\": false", "\"serviceable\": true")); var singleFile = BundleSelfContainedApp(fixture); // Create the servicing directory, and copy the servived DLL from service fixture to the servicing directory. var serviceBasePath = Path.Combine(fixture.TestProject.ProjectDirectory, "coreservicing"); var servicePath = Path.Combine(serviceBasePath, "pkgs", BundleHelper.GetAppBaseName(servicer), "1.0.0"); Directory.CreateDirectory(servicePath); File.Copy(BundleHelper.GetAppPath(servicer), Path.Combine(servicePath, BundleHelper.GetAppName(servicer))); // Verify that the test DLL is loaded from the bundle when not being serviced Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hi Bellevue!"); // Verify that the test DLL is loaded from the servicing location when being serviced Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.CoreServicingEnvVariable, serviceBasePath) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hi Bengaluru!"); }
private void Bundle_extraction_can_recover_missing_files() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var appName = Path.GetFileNameWithoutExtension(hostName); // Publish the bundle UseSingleFileSelfContainedHost(fixture); Bundler bundler = BundleHelper.BundleApp(fixture, out string singleFile, BundleOptions.BundleNativeBinaries); // Create a directory for extraction. var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture); // Run the bunded app for the first time, and extract files to // $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); // Remove the extracted files, but keep the extraction directory var extractDir = BundleHelper.GetExtractionDir(fixture, bundler); var extractedFiles = BundleHelper.GetExtractedFiles(fixture); Array.ForEach(extractedFiles, file => File.Delete(Path.Combine(extractDir.FullName, file))); extractDir.Should().Exist(); extractDir.Should().NotHaveFiles(extractedFiles); // Run the bundled app again (recover deleted files) Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); extractDir.Should().HaveFiles(extractedFiles); }
public void TestAssemblyAlignment() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var appName = Path.GetFileNameWithoutExtension(hostName); string publishPath = BundleHelper.GetPublishPath(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); var bundler = new Bundler(hostName, bundleDir.FullName, BundleOptions.BundleAllContent); BundleHelper.GenerateBundle(bundler, publishPath); bundler.BundleManifest.Files.ForEach(file => Assert.True((file.Type != FileType.Assembly) || (file.Offset % Bundler.AssemblyAlignment == 0))); }
public void AppContext_Deps_Files_Bundled_Self_Contained() { var fixture = sharedTestState.TestFixture.Copy(); var singleFile = BundleHelper.BundleApp(fixture); Command.Create(singleFile, "appcontext") .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .NotHaveStdOutContaining("SingleFileApiTests.deps.json") .And .NotHaveStdOutContaining("Microsoft.NETCore.App.deps.json"); }
public void FullyQualifiedName() { var fixture = sharedTestState.TestFixture.Copy(); var singleFile = BundleHelper.BundleApp(fixture); Command.Create(singleFile, "fullyqualifiedname") .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("FullyQualifiedName: <Unknown>" + Environment.NewLine + "Name: <Unknown>"); }
public void GetEnvironmentArgs_0_Returns_Bundled_Executable_Path() { var fixture = sharedTestState.TestFixture.Copy(); var singleFile = BundleHelper.BundleApp(fixture); // For single-file, Environment.GetCommandLineArgs[0] // should return the file path of the host. Command.Create(singleFile, "cmdlineargs") .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining(singleFile); }
private void Bundle_Extraction_To_Relative_Path_Succeeds(string relativePath) { var fixture = sharedTestState.TestFixture.Copy(); var singleFile = BundleHelper.BundleApp(fixture, BundleOptions.None); // Run the bundled app (extract files to <path>) Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, relativePath) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); }
public SharedTestState() { RepoDirectories = new RepoDirectoriesProvider(); TestFrameworkDependentFixture = new TestProjectFixture("AppWithSubDirs", RepoDirectories); TestFrameworkDependentFixture .EnsureRestoredForRid(TestFrameworkDependentFixture.CurrentRid, RepoDirectories.CorehostPackages) .PublishProject(runtime: TestFrameworkDependentFixture.CurrentRid, outputDirectory: BundleHelper.GetPublishPath(TestFrameworkDependentFixture)); TestSelfContainedFixture = new TestProjectFixture("AppWithSubDirs", RepoDirectories); TestSelfContainedFixture .EnsureRestoredForRid(TestSelfContainedFixture.CurrentRid, RepoDirectories.CorehostPackages) .PublishProject(runtime: TestSelfContainedFixture.CurrentRid, outputDirectory: BundleHelper.GetPublishPath(TestSelfContainedFixture)); }
public void TestNetCoreApp3xApp(int minorVersion) { var fixture = (minorVersion == 0) ? sharedTestState.TestFixture30.Copy() : sharedTestState.TestFixture31.Copy(); // Targetting netcoreap3.x implies BundleOption.BundleAllContent var singleFile = BundleHelper.BundleApp(fixture, BundleOptions.None, new Version(3, minorVersion)); Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World!"); }
private void Can_Run_App_With_StatiHost() { var fixture = sharedTestState.TestFixture.Copy(); var appExe = BundleHelper.GetHostPath(fixture); ReplaceApphostWithStaticHost(fixture); Command.Create(appExe) .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); }
private void Bundle_extraction_is_reused() { var fixture = sharedTestState.TestFixture.Copy(); // Publish the bundle string singleFile; Bundler bundler = BundleHelper.BundleApp(fixture, out singleFile, BundleOptions.BundleNativeBinaries); // Create a directory for extraction. var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture); // Run the bunded app for the first time, and extract files to // $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); var appBaseName = BundleHelper.GetAppBaseName(fixture); var extractDir = BundleHelper.GetExtractionDir(fixture, bundler); extractDir.Refresh(); DateTime firstWriteTime = extractDir.LastWriteTimeUtc; while (DateTime.Now == firstWriteTime) { Thread.Sleep(1); } // Run the bundled app again (reuse extracted files) Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName) .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World"); extractDir.Should().NotBeModifiedAfter(firstWriteTime); }
public void AppContext_Native_Search_Dirs_Contains_Bundle_Dir() { var fixture = sharedTestState.TestFixture.Copy(); Bundler bundler = BundleHelper.BundleApp(fixture, out string singleFile); string extractionDir = BundleHelper.GetExtractionDir(fixture, bundler).Name; string bundleDir = BundleHelper.GetBundleDir(fixture).FullName; // If we don't extract anything to disk, the extraction dir shouldn't // appear in the native search dirs. Command.Create(singleFile, "native_search_dirs") .CaptureStdErr() .CaptureStdOut() .Execute() .Should().Pass() .And.HaveStdOutContaining(bundleDir) .And.NotHaveStdOutContaining(extractionDir); }