public void TestAlwaysFailWhenAddingStaticallyListedFilesWithAbsentFileHash(bool isSourceFile) { var dropPaths = new List <string>(); var dropClient = new MockDropClient(addFileFunc: (item) => { dropPaths.Add(item.RelativeDropPath); return(Task.FromResult(AddFileResult.Associated)); }); var ipcProvider = IpcFactory.GetProvider(); var bxlApiClient = new Client(ipcProvider.GetClient(ipcProvider.CreateNewConnectionString(), new ClientConfig())); WithSetup( dropClient, (daemon, etwListener) => { // only hash and file rewrite count are important here; the rest are just fake values var hash = FileContentInfo.CreateWithUnknownLength(ContentHashingUtilities.CreateSpecialValue(1)).Render(); var addArtifactsCommand = global::Tool.ServicePipDaemon.ServicePipDaemon.ParseArgs( $"addartifacts --ipcServerMoniker {daemon.Config.Moniker} --file non-existent-file.txt --dropPath remote-file-name.txt --hash {hash} --fileId 12345:{(isSourceFile ? 0 : 1)}", new UnixParser()); var ipcResult = addArtifactsCommand.Command.ServerAction(addArtifactsCommand, daemon).GetAwaiter().GetResult(); XAssert.IsTrue(dropPaths.Count == 0); XAssert.IsFalse(ipcResult.Succeeded); XAssert.AreEqual(IpcResultStatus.InvalidInput, ipcResult.ExitCode); }, bxlApiClient); }
public void TestAddFile_AssociateDoesntNeedServer() { // this client only touches item.BlobIdentifier and returns 'Associated' var dropClient = new MockDropClient(addFileFunc: (item) => { Assert.NotNull(item.BlobIdentifier); return(Task.FromResult(AddFileResult.Associated)); }); WithSetup(dropClient, (daemon, etwListener) => { var provider = IpcFactory.GetProvider(); var connStr = provider.CreateNewConnectionString(); var contentInfo = new FileContentInfo(new ContentHash(HashType.Vso0), length: 123456); var client = new Client(provider.GetClient(connStr, new ClientConfig())); var addFileItem = new DropItemForBuildXLFile(client, filePath: "file-which-doesnt-exist.txt", fileId: "23423423:1", chunkDedup: TestChunkDedup, fileContentInfo: contentInfo); // addfile succeeds without needing BuildXL server nor the file on disk IIpcResult result = daemon.AddFileAsync(addFileItem).GetAwaiter().GetResult(); XAssert.IsTrue(result.Succeeded); // calling MaterializeFile fails because no BuildXL server is running Assert.Throws <DaemonException>(() => addFileItem.EnsureMaterialized().GetAwaiter().GetResult()); }); }
private MockDropClient GetFailingMockDropClient(Func <Exception> exceptionFactory) { return(new MockDropClient( createFunc: () => MockDropClient.CreateFailingTask <DropItem>(exceptionFactory), addFileFunc: (item) => MockDropClient.CreateFailingTask <AddFileResult>(exceptionFactory), finalizeFunc: () => MockDropClient.CreateFailingTask <FinalizeResult>(exceptionFactory))); }
public void TestAddingDirectoryContainingFilesWithAbsentFileHash(bool isSourceFile) { string remoteDirectoryPath = "remoteDirectory"; string fakeDirectoryId = "123:1:12345"; var directoryPath = Path.Combine(TestOutputDirectory, "foo"); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } var dropPaths = new List <string>(); var dropClient = new MockDropClient(addFileFunc: (item) => { dropPaths.Add(item.RelativeDropPath); return(Task.FromResult(AddFileResult.Associated)); }); var ipcProvider = IpcFactory.GetProvider(); // this lambda mocks BuildXL server receiving 'GetSealedDirectoryContent' API call and returning a response var ipcExecutor = new LambdaIpcOperationExecutor(op => { var cmd = ReceiveGetSealedDirectoryContentCommandAndCheckItMatchesDirectoryId(op.Payload, fakeDirectoryId); var file = new SealedDirectoryFile( Path.Combine(directoryPath, "file.txt"), new FileArtifact(new AbsolutePath(1), isSourceFile ? 0 : 1), FileContentInfo.CreateWithUnknownLength(global::BuildXL.Scheduler.WellKnownContentHashes.AbsentFile)); return(IpcResult.Success(cmd.RenderResult(new List <SealedDirectoryFile> { file }))); }); WithIpcServer( ipcProvider, ipcExecutor, new ServerConfig(), (moniker, mockServer) => { var bxlApiClient = new Client(ipcProvider.GetClient(ipcProvider.RenderConnectionString(moniker), new ClientConfig())); WithSetup( dropClient, (daemon, etwListener) => { var addArtifactsCommand = Program.ParseArgs($"addartifacts --ipcServerMoniker {moniker.Id} --directory {directoryPath} --directoryId {fakeDirectoryId} --directoryDropPath {remoteDirectoryPath} --directoryFilter .*", new UnixParser()); var ipcResult = addArtifactsCommand.Command.ServerAction(addArtifactsCommand, daemon).GetAwaiter().GetResult(); XAssert.IsTrue(dropPaths.Count == 0); // if an absent file is a source file, drop operation should have failed; otherwise, we simply skip it XAssert.AreEqual(!isSourceFile, ipcResult.Succeeded); XAssert.AreEqual(isSourceFile ? IpcResultStatus.InvalidInput : IpcResultStatus.Success, ipcResult.ExitCode); }, bxlApiClient); return(Task.CompletedTask); }).GetAwaiter().GetResult(); }
public void TestCreate(bool shouldSucceed) { var dropClient = new MockDropClient(createSucceeds: shouldSucceed); WithSetup(dropClient, (daemon, etwListener) => { AssertRpcResult(shouldSucceed, daemon.Create()); AssertDequeueEtwEvent(etwListener, shouldSucceed, EventKind.DropCreation); }); }
public void TestNonCreatorCantFinalize() { var dropClient = new MockDropClient(createSucceeds: true, finalizeSucceeds: false); WithSetup(dropClient, (daemon, etwListener) => { // This daemon is not the creator of the drop so it can't finalize it AssertRpcResult(false, daemon.Finalize()); Assert.True(etwListener.IsEmpty); }); }
public void TestNonCreatorDoesntFinalizeOnStop() { var dropClient = new MockDropClient(createSucceeds: true, finalizeSucceeds: false); WithSetup(dropClient, (daemon, etwListener) => { // We don't call create for this daemon daemon.RequestStop(); Assert.True(etwListener.IsEmpty); }); }
public void TestLazilyMaterializedSymlinkRejected() { string fileId = "142342:3"; string filePath = Path.Combine(TestOutputDirectory, nameof(TestLazilyMaterializedSymlinkRejected) + "-test.txt"); if (File.Exists(filePath)) { File.Delete(filePath); } // this client wants to read the file var dropClient = new MockDropClient(addFileFunc: (item) => { Assert.NotNull(item.BlobIdentifier); var ex = Assert.Throws <DaemonException>(() => item.EnsureMaterialized().GetAwaiter().GetResult()); // rethrowing because that's what a real IDropClient would do (then Daemon is expected to handle it) throw ex; }); WithSetup(dropClient, (daemon, etwListener, dropConfig) => { var dropName = GetDropFullName(dropConfig); var ipcProvider = IpcFactory.GetProvider(); var ipcExecutor = new LambdaIpcOperationExecutor(op => { // this mock BuildXL server materializes a regular file, which we will treat as a symlink in this test var cmd = ReceiveMaterializeFileCmdAndCheckItMatchesFileId(op.Payload, fileId); File.WriteAllText(filePath, TestFileContent); return(IpcResult.Success(cmd.RenderResult(true))); }); WithIpcServer( ipcProvider, ipcExecutor, new ServerConfig(), (moniker, mockServer) => { var client = new Client(ipcProvider.GetClient(ipcProvider.RenderConnectionString(moniker), new ClientConfig())); var addFileItem = new DropItemForBuildXLFile( symlinkTester: (file) => file == filePath ? true : false, client: client, fullDropName: dropName, filePath: filePath, fileId: fileId, fileContentInfo: TestFileContentInfo); // addfile files IIpcResult result = daemon.AddFileAsync(addFileItem).GetAwaiter().GetResult(); XAssert.IsFalse(result.Succeeded, "expected addfile to fail; instead it succeeded and returned payload: " + result.Payload); XAssert.IsTrue(result.Payload.Contains(DropItemForBuildXLFile.MaterializationResultIsSymlinkErrorPrefix)); }); }); }
public void TestFinalizeOnStopErrorsAreQueued() { var dropClient = new MockDropClient(createSucceeds: true, finalizeSucceeds: false); WithSetup(dropClient, (daemon, etwListener) => { daemon.Create(); etwListener.DequeueDropEvent(); // Dequeue create daemon.RequestStop(); AssertDequeueEtwEvent(etwListener, succeeded: false, kind: EventKind.DropFinalization); }); }
public void TestFinalize(bool shouldSucceed) { var dropClient = new MockDropClient(finalizeSucceeds: shouldSucceed); WithSetup(dropClient, (daemon, etwListener) => { daemon.Create(); // We can only finalize if we created AssertDequeueEtwEvent(etwListener, true, EventKind.DropCreation); AssertRpcResult(shouldSucceed, daemon.Finalize()); AssertDequeueEtwEvent(etwListener, shouldSucceed, EventKind.DropFinalization); }); }
public void TestCreateFinalize(bool shouldCreateSucceed, bool shouldFinalizeSucceed) { var dropClient = new MockDropClient(createSucceeds: shouldCreateSucceed, finalizeSucceeds: shouldFinalizeSucceed); WithSetup(dropClient, (daemon, etwListener) => { var rpcResult = daemon.Create(); AssertRpcResult(shouldCreateSucceed, rpcResult); rpcResult = daemon.Finalize(); AssertRpcResult(shouldFinalizeSucceed, rpcResult); AssertDequeueEtwEvent(etwListener, shouldCreateSucceed, EventKind.DropCreation); AssertDequeueEtwEvent(etwListener, shouldFinalizeSucceed, EventKind.DropFinalization); }); }
public void TestDropDaemonOutrightRejectSymlinks() { // create a regular file that mocks a symlink (because creating symlinks on Windows is difficult?!?) var targetFile = Path.Combine(TestOutputDirectory, nameof(TestDropDaemonOutrightRejectSymlinks) + "-test.txt"); File.WriteAllText(targetFile, "drop symlink test file"); // check that drop daemon rejects it outright var dropClient = new MockDropClient(addFileSucceeds: true); WithSetup(dropClient, async(daemon, etwListener) => { var ipcResult = await daemon.AddFileAsync(new DropItemForFile(targetFile), symlinkTester: (file) => file == targetFile ? true : false); Assert.False(ipcResult.Succeeded, "adding symlink to drop succeeded while it was expected to fail"); Assert.True(ipcResult.Payload.Contains(global::Tool.DropDaemon.DropDaemon.SymlinkAddErrorMessagePrefix)); }); }
public void TestAddBuildXLFile_UploadCallsBuildXLServer() { string fileId = "142342:2"; string filePath = Path.Combine(TestOutputDirectory, nameof(TestAddBuildXLFile_UploadCallsBuildXLServer) + "-test.txt"); if (File.Exists(filePath)) { File.Delete(filePath); } // this client wants to read the file var dropClient = new MockDropClient(addFileFunc: (item) => { Assert.NotNull(item.BlobIdentifier); var fileInfo = item.EnsureMaterialized().GetAwaiter().GetResult(); XAssert.IsTrue(fileInfo != null && fileInfo.Exists); XAssert.AreEqual(TestFileContent, File.ReadAllText(fileInfo.FullName)); return(Task.FromResult(AddFileResult.UploadedAndAssociated)); }); WithSetup(dropClient, (daemon, etwListener, dropConfig) => { var dropName = GetDropFullName(dropConfig); var ipcProvider = IpcFactory.GetProvider(); var ipcExecutor = new LambdaIpcOperationExecutor(op => { var cmd = ReceiveMaterializeFileCmdAndCheckItMatchesFileId(op.Payload, fileId); File.WriteAllText(filePath, TestFileContent); return(IpcResult.Success(cmd.RenderResult(true))); }); WithIpcServer( ipcProvider, ipcExecutor, new ServerConfig(), (moniker, mockServer) => { var client = new Client(ipcProvider.GetClient(ipcProvider.RenderConnectionString(moniker), new ClientConfig())); var addFileItem = new DropItemForBuildXLFile(client, dropName, filePath, fileId, fileContentInfo: TestFileContentInfo); // addfile succeeds IIpcResult result = daemon.AddFileAsync(addFileItem).GetAwaiter().GetResult(); XAssert.IsTrue(result.Succeeded, result.Payload); }); }); }
public void TestUrlAndErrorMessageFields(bool shouldSucceed) { var url = "xya://drop.url"; var errorMessage = shouldSucceed ? string.Empty : "err"; var createFunc = shouldSucceed ? new MockDropClient.CreateDelegate(() => Task.FromResult(new DropItem())) : new MockDropClient.CreateDelegate(() => MockDropClient.FailTask <DropItem>(errorMessage)); var dropClient = new MockDropClient(dropUrl: url, createFunc: createFunc); WithSetup(dropClient, (daemon, etwListener) => { var rpcResult = daemon.Create(); AssertRpcResult(shouldSucceed, rpcResult); var dropEvent = AssertDequeueEtwEvent(etwListener, shouldSucceed, EventKind.DropCreation); Assert.Equal(url, dropEvent.DropUrl); Assert.True(dropEvent.ErrorMessage.Contains(errorMessage)); }); }
public void TestMultipleFinalizationBehavior() { var dropClient = new MockDropClient(createSucceeds: true, finalizeSucceeds: true); WithSetup(dropClient, (daemon, etwListener) => { daemon.Create(); AssertDequeueEtwEvent(etwListener, succeeded: true, kind: EventKind.DropCreation); AssertRpcResult(true, daemon.Finalize()); AssertDequeueEtwEvent(etwListener, succeeded: true, kind: EventKind.DropFinalization); // Subsequent finalizations are ignored by the daemon AssertRpcResult(false, daemon.Finalize()); AssertRpcResult(false, daemon.Finalize()); Assert.True(etwListener.IsEmpty); // We failed by design, there's no ETW event }); }
public void FinalizeIsCalledOnStop() { var dropClient = new MockDropClient(createSucceeds: true, finalizeSucceeds: true); WithSetup(dropClient, (daemon, etwListener) => { daemon.Create(); AssertDequeueEtwEvent(etwListener, succeeded: true, kind: EventKind.DropCreation); daemon.RequestStop(); // Stop called for finalization AssertDequeueEtwEvent(etwListener, succeeded: true, kind: EventKind.DropFinalization); AssertRpcResult(false, daemon.Finalize()); Assert.True(etwListener.IsEmpty); // We failed by design, there's no ETW event }); }
public void FinalizeOnStopAfterNormalFinalizationIsOk() { var dropClient = new MockDropClient(createSucceeds: true, finalizeSucceeds: true); WithSetup(dropClient, (daemon, etwListener) => { daemon.Create(); etwListener.DequeueDropEvent(); // Dequeue create AssertRpcResult(true, daemon.Finalize()); AssertDequeueEtwEvent(etwListener, succeeded: true, kind: EventKind.DropFinalization); daemon.RequestStop(); // Stop called for finalization, // but nothing happens because finalize was called before Assert.True(etwListener.IsEmpty); }); }
public void TestSingleDropOperation(DropOp dropOp, bool shouldSucceed) { var dropClient = new MockDropClient(createSucceeds: shouldSucceed, finalizeSucceeds: shouldSucceed); WithSetup(dropClient, (daemon, etwListener) => { var rpcResult = dropOp == DropOp.Create ? daemon.Create() : dropOp == DropOp.Finalize ? daemon.Finalize() : null; Assert.True(rpcResult != null, "unknown drop operation: " + dropOp); Assert.Equal(shouldSucceed, rpcResult.Succeeded); var expectedEventKind = dropOp == DropOp.Create ? EventKind.DropCreation : dropOp == DropOp.Finalize ? EventKind.DropFinalization : EventKind.TargetAdded; // something bogus, just to make the compiler happy AssertDequeueEtwEvent(etwListener, shouldSucceed, expectedEventKind); }); }
public void TestAdddingDirectoryToDropWithSpecifiedRelativePathReplacement(string dropPath, string replaceOldValue, string replaceNewValue, params string[] expectedFiles) { /* * Directory content: * a * dir\b * dir\dir\c * dir\dir2\d * dir3\e */ var expectedDropPaths = new HashSet <string>(expectedFiles); var dropPaths = new List <string>(); var fakeDirectoryId = "123:1:12345"; var directoryPath = Path.Combine(TestOutputDirectory, "foo"); var files = new List <string> { Path.Combine(directoryPath, "a"), Path.Combine(directoryPath, "dir", "b"), Path.Combine(directoryPath, "dir", "dir", "c"), Path.Combine(directoryPath, "dir", "dir2", "d"), Path.Combine(directoryPath, "dir3", "e"), }; var dropClient = new MockDropClient(addFileFunc: (item) => { dropPaths.Add(item.RelativeDropPath); return(Task.FromResult(AddFileResult.UploadedAndAssociated)); }); var ipcProvider = IpcFactory.GetProvider(); // this lambda mocks BuildXL server receiving 'GetSealedDirectoryContent' API call and returning a response var ipcExecutor = new LambdaIpcOperationExecutor(op => { var cmd = ReceiveGetSealedDirectoryContentCommandAndCheckItMatchesDirectoryId(op.Payload, fakeDirectoryId); // Now 'fake' the response - here we only care about the 'FileName' field. // In real life it's not the case, but this is a test and our custom addFileFunc // in dropClient simply collects the drop file names. var result = files.Select(file => CreateFakeSealedDirectoryFile(file)).ToList(); return(IpcResult.Success(cmd.RenderResult(result))); }); WithIpcServer( ipcProvider, ipcExecutor, new ServerConfig(), (moniker, mockServer) => { var bxlApiClient = CreateDummyBxlApiClient(ipcProvider, moniker); WithSetup( dropClient, (daemon, etwListener, dropConfig) => { var addArtifactsCommand = global::Tool.ServicePipDaemon.ServicePipDaemon.ParseArgs( $"addartifacts --ipcServerMoniker {moniker.Id} --service {dropConfig.Service} --name {dropConfig.Name} --directory {directoryPath} --directoryId {fakeDirectoryId} --directoryDropPath {dropPath} --directoryFilter .* --directoryRelativePathReplace {serializeReplaceArgument(replaceOldValue, replaceNewValue)} --directoryFilterUseRelativePath false", new UnixParser()); var ipcResult = addArtifactsCommand.Command.ServerAction(addArtifactsCommand, daemon).GetAwaiter().GetResult(); XAssert.IsTrue(ipcResult.Succeeded, ipcResult.Payload); XAssert.AreSetsEqual(expectedDropPaths, dropPaths, expectedResult: true); }, bxlApiClient); return(Task.CompletedTask); }).GetAwaiter().GetResult(); string serializeReplaceArgument(string oldValue, string newValue) { if (oldValue != null || newValue != null) { return($"#{oldValue}#{newValue}#"); } return("##"); } }
public void TestAddDirectoryToDrop() { var dropPaths = new System.Collections.Generic.List <string>(); var expectedDropPaths = new System.Collections.Generic.HashSet <string>(); string directoryId = "123:1:12345"; // TestOutputDirectory // |- foo <directory> <- 'uploading' this directory // |- b.txt // |- c.txt // |- bar <directory> // |- d.txt var path = Path.Combine(TestOutputDirectory, "foo"); if (Directory.Exists(path)) { Directory.Delete(path, recursive: true); } Directory.CreateDirectory(path); var fileFooB = Path.Combine(TestOutputDirectory, "foo", "b.txt"); File.WriteAllText(fileFooB, Guid.NewGuid().ToString()); expectedDropPaths.Add("remote/b.txt"); var fileFooC = Path.Combine(TestOutputDirectory, "foo", "c.txt"); File.WriteAllText(fileFooC, Guid.NewGuid().ToString()); expectedDropPaths.Add("remote/c.txt"); path = Path.Combine(TestOutputDirectory, "foo", "bar"); Directory.CreateDirectory(path); var fileFooBarD = Path.Combine(TestOutputDirectory, "foo", "bar", "d.txt"); File.WriteAllText(fileFooBarD, Guid.NewGuid().ToString()); expectedDropPaths.Add("remote/bar/d.txt"); var dropClient = new MockDropClient(addFileFunc: (item) => { dropPaths.Add(item.RelativeDropPath); return(Task.FromResult(AddFileResult.UploadedAndAssociated)); }); var ipcProvider = IpcFactory.GetProvider(); var ipcExecutor = new LambdaIpcOperationExecutor(op => { // this lambda mocks BuildXL server receiving 'GetSealedDirectoryContent' API call and returning a response var cmd = ReceiveGetSealedDirectoryContentCommandAndCheckItMatchesDirectoryId(op.Payload, directoryId); // Now 'fake' the response - here we only care about the 'FileName' field. // In real life it's not the case, but this is a test and our custom addFileFunc // in dropClient simply collects the drop file names. var result = new System.Collections.Generic.List <SealedDirectoryFile> { CreateFakeSealedDirectoryFile(fileFooB), CreateFakeSealedDirectoryFile(fileFooC), CreateFakeSealedDirectoryFile(fileFooBarD) }; return(IpcResult.Success(cmd.RenderResult(result))); }); WithSetup(dropClient, async(daemon, etwListener) => { await WithIpcServer( ipcProvider, ipcExecutor, new ServerConfig(), async(moniker, mockServer) => { var client = new Client(ipcProvider.GetClient(ipcProvider.RenderConnectionString(moniker), new ClientConfig())); var ipcResult = await daemon.AddDirectoryAsync(Path.Combine(TestOutputDirectory, "foo"), directoryId, "remote", TestChunkDedup, client); XAssert.IsTrue(ipcResult.Succeeded, ipcResult.Payload); XAssert.AreSetsEqual(expectedDropPaths, dropPaths, expectedResult: true); }); }); }
[InlineData(".*d\\.txt$")] // no files public void TestAddDirectoryToDropWithFilters(string filter) { // TestOutputDirectory // |- foo <directory> <- 'uploading' this directory // |- a.txt // |- b.txt // |- bar <directory> // |- c.txt string remoteDirectoryPath = "remoteDirectory"; string fakeDirectoryId = "123:1:12345"; var directoryPath = Path.Combine(TestOutputDirectory, "foo"); var files = new List <(string fileName, string remoteFileName)> { (Path.Combine(directoryPath, "a.txt"), $"{remoteDirectoryPath}/a.txt"), (Path.Combine(directoryPath, "b.txt"), $"{remoteDirectoryPath}/b.txt"), (Path.Combine(directoryPath, "bar", "c.txt"), $"{remoteDirectoryPath}/bar/c.txt"), }; var dropPaths = new List <string>(); var expectedDropPaths = new HashSet <string>(); var regex = new Regex(filter, RegexOptions.IgnoreCase | RegexOptions.Compiled); expectedDropPaths.AddRange(files.Where(a => regex.IsMatch(a.fileName)).Select(a => a.remoteFileName)); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } var dropClient = new MockDropClient(addFileFunc: (item) => { dropPaths.Add(item.RelativeDropPath); return(Task.FromResult(AddFileResult.UploadedAndAssociated)); }); var ipcProvider = IpcFactory.GetProvider(); // this lambda mocks BuildXL server receiving 'GetSealedDirectoryContent' API call and returning a response var ipcExecutor = new LambdaIpcOperationExecutor(op => { var cmd = ReceiveGetSealedDirectoryContentCommandAndCheckItMatchesDirectoryId(op.Payload, fakeDirectoryId); // Now 'fake' the response - here we only care about the 'FileName' field. // In real life it's not the case, but this is a test and our custom addFileFunc // in dropClient simply collects the drop file names. var result = files.Select(a => CreateFakeSealedDirectoryFile(a.fileName)).ToList(); return(IpcResult.Success(cmd.RenderResult(result))); }); WithIpcServer( ipcProvider, ipcExecutor, new ServerConfig(), (moniker, mockServer) => { var bxlApiClient = new Client(ipcProvider.GetClient(ipcProvider.RenderConnectionString(moniker), new ClientConfig())); WithSetup( dropClient, (daemon, etwListener) => { var addArtifactsCommand = global::Tool.ServicePipDaemon.ServicePipDaemon.ParseArgs( $"addartifacts --ipcServerMoniker {moniker.Id} --directory {directoryPath} --directoryId {fakeDirectoryId} --directoryDropPath {remoteDirectoryPath} --directoryFilter {filter}", new UnixParser()); var ipcResult = addArtifactsCommand.Command.ServerAction(addArtifactsCommand, daemon).GetAwaiter().GetResult(); XAssert.IsTrue(ipcResult.Succeeded, ipcResult.Payload); XAssert.AreSetsEqual(expectedDropPaths, dropPaths, expectedResult: true); }, bxlApiClient); return(Task.CompletedTask); }).GetAwaiter().GetResult(); }