Beispiel #1
0
        private async Task <Possible <T> > ExecuteCommand <T>(Command <T> command)
        {
            try
            {
                IIpcOperation ipcOperation = new IpcOperation(Command.Serialize(command), waitForServerAck: true);
                IIpcResult    ipcResult    = await m_client.Send(ipcOperation);

                if (!ipcResult.Succeeded)
                {
                    return(new Failure <string>(ipcResult.ToString()));
                }

                T cmdResult;
                if (!command.TryParseResult(ipcResult.Payload, out cmdResult))
                {
                    return(new Failure <string>($"{ErrorCannotParseIpcResultMessage}: {ipcResult}"));
                }

                return(cmdResult);
            }
            catch (Exception ex)
            {
                return(new Failure <Exception>(ex).Annotate($"Executing {command.GetType().Name} command threw exception."));
            }
        }
Beispiel #2
0
        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());
            });
        }
Beispiel #3
0
        /// <nodoc/>
        public Response(int requestId, IIpcResult result)
        {
            Contract.Requires(result != null);

            RequestId = requestId;
            Result    = result;
        }
Beispiel #4
0
 /// <summary>
 /// The <see cref="Succeeded"/> property of the result is a conjunction of the
 /// corresponding properties of the arguments, and the <see cref="Payload"/>
 /// property of the result is a semicolon-separated concatenation of the corresponding
 /// properties of the arguments.
 /// </summary>
 public static IIpcResult Merge(IIpcResult lhs, IIpcResult rhs)
 {
     return(new IpcResult(
                MergeStatuses(lhs.ExitCode, rhs.ExitCode),
                lhs.Payload + Environment.NewLine + rhs.Payload,
                lhs.ActionDuration + rhs.ActionDuration));
 }
Beispiel #5
0
        /// <summary>
        /// Asynchronously serializes given <see cref="IIpcResult"/> to a stream writer.
        /// </summary>
        /// <remarks>
        /// Doesn't handle any exceptions.
        /// </remarks>
        public static async Task SerializeAsync(Stream stream, IIpcResult result, CancellationToken token)
        {
            await Utils.WriteByteAsync(stream, (byte)result.ExitCode, token);

            await Utils.WriteStringAsync(stream, result.Payload, token);

            await stream.FlushAsync(token);
        }
        private void UnblockPendingRequests(IIpcResult result)
        {
            foreach (var taskSource in m_pendingRequests.Values)
            {
                taskSource.TrySetResult(result);
            }

            m_pendingRequests.Clear();
        }
Beispiel #7
0
        /// <summary>
        /// The <see cref="Succeeded"/> property of the result is a conjunction of the
        /// corresponding properties of the arguments, and the <see cref="Payload"/>
        /// property of the result is a semicolon-separated concatenation of the corresponding
        /// properties of the arguments.
        /// </summary>
        public static IIpcResult Merge(IIpcResult lhs, IIpcResult rhs)
        {
            var mergedStatus =
                lhs.Succeeded && rhs.Succeeded ? IpcResultStatus.Success :
                lhs.Succeeded && !rhs.Succeeded ? rhs.ExitCode :
                !lhs.Succeeded && rhs.Succeeded ? lhs.ExitCode :
                IpcResultStatus.GenericError;

            return(new IpcResult(mergedStatus, lhs.Payload + Environment.NewLine + rhs.Payload, lhs.ActionDuration + rhs.ActionDuration));
        }
Beispiel #8
0
        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));
                });
            });
        }
Beispiel #9
0
        /// <summary>
        /// Compute the hashes for file stored in Cache. Required for Build Manifest generation.
        /// </summary>
        private async Task <Possible <IReadOnlyList <ContentHash> > > ComputeBuildManifestHashFromCacheAsync(BuildManifestEntry buildManifestEntry, IList <HashType> requestedTypes)
        {
            // Ensure that the file is materialized.
            MaterializeFileCommand materializeCommand = new MaterializeFileCommand(buildManifestEntry.Artifact, buildManifestEntry.FullFilePath);
            IIpcResult             materializeResult  = await ExecuteMaterializeFileAsync(materializeCommand);

            if (!materializeResult.Succeeded)
            {
                return(new Failure <string>($"Unable to materialize file: '{buildManifestEntry.FullFilePath}' with hash: '{buildManifestEntry.Hash.Serialize()}'. Failure: {materializeResult.Payload}"));
            }

            return(await TryGetBuildManifestHashFromLocalFileAsync(buildManifestEntry.FullFilePath, buildManifestEntry.Hash, requestedTypes));
        }
Beispiel #10
0
        /// <summary>
        /// 1. deserializes an <see cref="IIpcOperation"/> from a given <paramref name="stream"/>;
        /// 2. executes the operation (via <paramref name="executor"/>);
        /// 3. serializes and sends back the result via <paramref name="stream"/>.
        ///
        /// If executing the operation (via <paramref name="executor"/>) fails, the <see cref="IIpcResult.ExitCode"/>
        /// of the result is <see cref="IpcResultStatus.ExecutionError"/>
        /// </summary>
        internal static async Task <IIpcResult> ReceiveOperationAndExecuteLocallyAsync(Stream stream, IIpcOperationExecutor executor, CancellationToken token)
        {
            IIpcOperation operation = await IpcOperation.DeserializeAsync(stream, token);

            IIpcResult result = await HandleExceptionsAsync(IpcResultStatus.ExecutionError, () => executor.ExecuteAsync(operation));

            if (operation.ShouldWaitForServerAck)
            {
                await IpcResult.SerializeAsync(stream, result, token);
            }

            return(result);
        }
Beispiel #11
0
        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);
                });
            });
        }
Beispiel #12
0
        private async Task <Possible <T> > ExecuteCommand <T>(Command <T> command)
        {
            IIpcOperation ipcOperation = new IpcOperation(Command.Serialize(command), waitForServerAck: true);
            IIpcResult    ipcResult    = await m_client.Send(ipcOperation);

            if (!ipcResult.Succeeded)
            {
                return(new Failure <string>(ipcResult.ToString()));
            }

            T cmdResult;

            if (!command.TryParseResult(ipcResult.Payload, out cmdResult))
            {
                return(new Failure <string>("Cannot parse IPC result: " + ipcResult.ToString()));
            }

            return(cmdResult);
        }
Beispiel #13
0
        /// <summary>
        /// Compute the SHA-256 hash for file stored in Cache. Required for Build Manifets generation.
        /// </summary>
        private async Task <Possible <ContentHash> > ComputeBuildManifestHashFromCacheAsync(BuildManifestEntry buildManifestEntry)
        {
            if (!File.Exists(buildManifestEntry.FullFilePath))
            {
                // Ensure file is materialized locally
                if (!AbsolutePath.TryCreate(m_context.PathTable, buildManifestEntry.FullFilePath, out AbsolutePath path))
                {
                    return(new Failure <string>($"Invalid absolute path: '{buildManifestEntry.FullFilePath}'"));
                }

                MaterializeFileCommand materializeCommand = new MaterializeFileCommand(FileArtifact.CreateOutputFile(path), buildManifestEntry.FullFilePath);
                IIpcResult             materializeResult  = await ExecuteMaterializeFileAsync(materializeCommand);

                if (!materializeResult.Succeeded)
                {
                    return(new Failure <string>($"Unable to materialize file: '{buildManifestEntry.FullFilePath}' with hash: '{buildManifestEntry.Hash.Serialize()}'. Failure: {materializeResult.Payload}"));
                }
            }

            return(await TryGetBuildManifestHashFromLocalFileAsync(buildManifestEntry.FullFilePath));
        }
Beispiel #14
0
 private void AssertRpcResult(bool shouldSucceed, IIpcResult rpcResult)
 {
     Assert.NotNull(rpcResult);
     Assert.Equal(shouldSucceed, rpcResult.Succeeded);
 }