/// <inheritdoc /> public bool AddIpcPip(IpcPip ipcPip, PipId valuePip) { Contract.Requires(ipcPip != null, "Argument pip cannot be null"); ipcPip.PipId = GetPipId(); m_pips.Enqueue(ipcPip); return(true); }
/// <nodoc /> public bool TryAddIpc( IpcClientInfo ipcClientInfo, PipData arguments, FileArtifact outputFile, ReadOnlyArray <PipId> servicePipDependencies, ReadOnlyArray <FileArtifact> fileDependencies, ReadOnlyArray <DirectoryArtifact> directoryDependencies, ReadOnlyArray <FileOrDirectoryArtifact> skipMaterializationFor, bool isServiceFinalization, bool mustRunOnMaster, string[] tags, out IpcPip ipcPip) { ipcPip = new IpcPip( ipcClientInfo, arguments, outputFile: outputFile, servicePipDependencies: servicePipDependencies, fileDependencies: fileDependencies, directoryDependencies: directoryDependencies, skipMaterializationFor: skipMaterializationFor, isServiceFinalization: isServiceFinalization, mustRunOnMaster: mustRunOnMaster, tags: ToStringIds(tags), provenance: CreatePipProvenance(string.Empty) ); if (PipGraph != null) { var success = PipGraph.AddIpcPip(ipcPip, GetValuePipId()); return(success); } return(true); }
/// <inheritdoc /> public override bool AddIpcPip([NotNull] IpcPip ipcPip, PipId valuePip) { var result = base.AddIpcPip(ipcPip, valuePip); AddFileDependents(ipcPip.FileDependencies, ipcPip); AddDirectoryDependents(ipcPip.DirectoryDependencies, ipcPip); AddDependents(ipcPip.ServicePipDependencies, ipcPip); return(result); }
private static void SetIpcPipDetails(IpcPip pip, PipDetails result, PathTable pathTable) { result.Payload = pip.MessageBody.ToString(pathTable); result.PayloadFragments = ConvertArgumentsToStringArray(pip.MessageBody, pathTable); result.IsServiceFinalizer = pip.IsServiceFinalization; result.IpcConfig = JsonConvert.SerializeObject(pip.IpcInfo.IpcClientConfig); result.IpcMoniker = pip.IpcInfo.IpcMonikerId.ToString(pathTable.StringTable); result.Dependencies = pip.FileDependencies.Select(d => FileArtifactToFileDetails(d, pathTable)).OrderBy(d => d).ToList(); result.StandardOutput = new FileReference { Id = -1, Path = pip.OutputFile.Path.ToString(pathTable) }; }
/// <summary> /// Gets the outputs produced by a pip and calls an action /// </summary> public static bool ForEachOutput(Pip pip, Func <FileOrDirectoryArtifact, bool> outputAction, bool includeUncacheable) { bool result = true; switch (pip.PipType) { case PipType.CopyFile: CopyFile copyFile = (CopyFile)pip; result = outputAction(FileOrDirectoryArtifact.Create(copyFile.Destination)); break; case PipType.SealDirectory: SealDirectory sealDirectory = (SealDirectory)pip; result = outputAction(FileOrDirectoryArtifact.Create(sealDirectory.Directory)); break; case PipType.Process: Process process = (Process)pip; foreach (var output in process.FileOutputs) { if (includeUncacheable || output.CanBeReferencedOrCached()) { if (!outputAction(FileOrDirectoryArtifact.Create(output.ToFileArtifact()))) { return(false); } } } foreach (var output in process.DirectoryOutputs) { if (!outputAction(FileOrDirectoryArtifact.Create(output))) { return(false); } } break; case PipType.WriteFile: WriteFile writeFile = (WriteFile)pip; result = outputAction(FileOrDirectoryArtifact.Create(writeFile.Destination)); break; case PipType.Ipc: IpcPip ipcPip = (IpcPip)pip; result = outputAction(FileOrDirectoryArtifact.Create(ipcPip.OutputFile)); break; } return(result); }
/// <inheritdoc /> public override bool HasRealConsumers(IpcPip pip) { foreach (var outgoingEdge in m_pipGraph.DataflowGraph.GetOutgoingEdges(pip.PipId.ToNodeId())) { var otherPipId = outgoingEdge.OtherNode.ToPipId(); if (m_pipGraph.PipTable.GetServiceInfo(otherPipId).Kind == ServicePipKind.None) { return(true); } } return(false); }
private XElement GetIpcPipDetails(IpcPip pip) { return(m_html.CreateBlock( "IpcPip Details", m_html.CreateRow("Ipc MonikerInfo", pip.IpcInfo.IpcMonikerId), m_html.CreateRow("MessageBody", pip.MessageBody), m_html.CreateRow("OutputFile", pip.OutputFile), m_html.CreateRow("ServicePip Dependencies", pip.ServicePipDependencies), m_html.CreateRow("File Dependencies", pip.FileDependencies), m_html.CreateRow("LazilyMaterialized Dependencies", pip.LazilyMaterializedDependencies), m_html.CreateRow("IsServiceFinalization", pip.IsServiceFinalization), m_html.CreateRow("MustRunOnMaster", pip.MustRunOnMaster))); }
private XElement GetIpcPipDetails(IpcPip pip) { return(m_html.CreateBlock( "IpcPip Details", m_html.CreateRow("Ipc MonikerInfo", pip.IpcInfo.IpcMonikerId), m_html.CreateRow("MessageBody", pip.MessageBody), m_html.CreateRow("OutputFile", pip.OutputFile), m_html.CreateRow("ServicePip Dependencies", pip.ServicePipDependencies), m_html.CreateRow("File Dependencies", pip.FileDependencies), m_html.CreateRow("Directory Dependencies", pip.DirectoryDependencies), m_html.CreateRow("LazilyMaterialized File Dependencies", pip.LazilyMaterializedDependencies.Where(a => a.IsFile).Select(a => a.FileArtifact)), m_html.CreateRow("LazilyMaterialized Directory Dependencies", pip.LazilyMaterializedDependencies.Where(a => a.IsDirectory).Select(a => a.DirectoryArtifact)), m_html.CreateRow("IsServiceFinalization", pip.IsServiceFinalization), m_html.CreateRow("MustRunOnMaster", pip.MustRunOnMaster))); }
/// <summary> /// Creates a cacheable pip info for an ipc pip /// </summary> public static CacheablePipInfo GetIpcCacheInfo(IpcPip pip, PipExecutionContext context, bool omitLazilyMaterializedDependencies) { var dependencies = omitLazilyMaterializedDependencies && pip.LazilyMaterializedDependencies.Any() ? ReadOnlyArray <FileArtifact> .From(pip.FileDependencies.Except(pip.LazilyMaterializedDependencies)) : pip.FileDependencies; return(new CacheablePipInfo( pip: pip, context: context, allowPreserveOutputs: false, outputs: ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(pip.OutputFile.WithAttributes()), dependencies: dependencies, directoryOutputs: ReadOnlyArray <DirectoryArtifact> .Empty, directoryDependencies: ReadOnlyArray <DirectoryArtifact> .Empty)); }
private static IpcSpecificDetails CreateIpcSpecificDetails(IpcPip pip, PathTable pathTable, StringTable stringTable) { return(new IpcSpecificDetails { IpcMonikerId = CreateString(pip.IpcInfo.IpcMonikerId, stringTable), MessageBody = CreateString(pip.MessageBody, pathTable), OutputFile = CreateString(pip.OutputFile.Path, pathTable), ServicePipDependencies = CreateString(pip.ServicePipDependencies), FileDependencies = CreateString(pip.FileDependencies, pathTable), DirectoryDependencies = CreateString(pip.DirectoryDependencies, pathTable), LazilyMaterializedFileDependencies = pip.LazilyMaterializedDependencies.Where(a => a.IsFile && a.IsValid).Select(a => a.FileArtifact.Path.ToString(pathTable)).ToList(), LazilyMaterializedDirectoryDependencies = pip.LazilyMaterializedDependencies.Where(a => a.IsDirectory && a.IsValid).Select(a => a.DirectoryArtifact.Path.ToString(pathTable)).ToList(), IsServiceFinalization = pip.IsServiceFinalization, MustRunOnMaster = pip.MustRunOnMaster, }); }
private IExpression Generate(IpcPip pip) { var properties = new List <IObjectLiteralElement> { new PropertyAssignment("connectRetryDelayMillis", Generate((int)pip.IpcInfo.IpcClientConfig.ConnectRetryDelay.TotalMilliseconds)), new PropertyAssignment("maxConnectRetries", Generate(pip.IpcInfo.IpcClientConfig.MaxConnectRetries)), new PropertyAssignment("fileDependencies", new ArrayLiteralExpression(pip.FileDependencies.Select(Generate))), new PropertyAssignment("lazilyMaterializedDependencies", new ArrayLiteralExpression(pip.LazilyMaterializedDependencies.Select(Generate))), new PropertyAssignment("messageBody", Generate(pip.MessageBody)), new PropertyAssignment("outputFile", Generate(pip.OutputFile)), new PropertyAssignment("isServiceFinalization", Generate(pip.IsServiceFinalization)), new PropertyAssignment("mustRunOnMaster", Generate(pip.MustRunOnMaster)), }; return(new CallExpression( new PropertyAccessExpression("Transformer", "ipcSend"), new ObjectLiteralExpression(properties))); }
/// <summary> /// Generates the IpcPipDetails for a given Pip /// </summary> public IpcPipDetails GenerateIpcPipDetails(IpcPip pip) { IpcPipDetails ipcPipDetails = new IpcPipDetails { IpcMonikerId = pip.IpcInfo.IpcMonikerId.Value, MessageBody = pip.MessageBody.IsValid ? pip.MessageBody.ToString(PathTable) : null, OutputFile = pip.OutputFile.Path.ToString(PathTable), ServicePipDependencies = pip.ServicePipDependencies.Select(x => x.Value).ToList(), FileDependencies = pip.FileDependencies.Select(x => x.Path.ToString(PathTable)).ToList(), LazilyMaterializedDependencies = pip.LazilyMaterializedDependencies.Select(x => x.Path.ToString(PathTable)).ToList(), IsServiceFinalization = pip.IsServiceFinalization, MustRunOnMaster = pip.MustRunOnMaster }; ipcPipDetails.ServicePipDependencies = ipcPipDetails.ServicePipDependencies.Any() ? ipcPipDetails.ServicePipDependencies : null; ipcPipDetails.FileDependencies = ipcPipDetails.FileDependencies.Any() ? ipcPipDetails.FileDependencies : null; ipcPipDetails.LazilyMaterializedDependencies = ipcPipDetails.LazilyMaterializedDependencies.Any() ? ipcPipDetails.LazilyMaterializedDependencies : null; return(ipcPipDetails); }
/// <summary> /// Creates a cacheable pip info for an ipc pip /// </summary> public static CacheablePipInfo GetIpcCacheInfo(IpcPip pip, PipExecutionContext context, bool omitLazilyMaterializedDependencies) { var fileDependencies = omitLazilyMaterializedDependencies && pip.LazilyMaterializedDependencies.Any(a => a.IsFile) ? ReadOnlyArray <FileArtifact> .From( pip.FileDependencies.Except( pip.LazilyMaterializedDependencies.Where(a => a.IsFile).Select(a => a.FileArtifact))) : pip.FileDependencies; var directoryDependencies = omitLazilyMaterializedDependencies && pip.LazilyMaterializedDependencies.Any(a => a.IsDirectory) ? ReadOnlyArray <DirectoryArtifact> .From( pip.DirectoryDependencies.Except( pip.LazilyMaterializedDependencies.Where(a => a.IsDirectory).Select(a => a.DirectoryArtifact))) : pip.DirectoryDependencies; return(new CacheablePipInfo( pip: pip, context: context, outputs: ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(pip.OutputFile.WithAttributes()), dependencies: fileDependencies, directoryOutputs: ReadOnlyArray <DirectoryArtifact> .Empty, directoryDependencies: directoryDependencies)); }
/// <summary> /// Gets the outputs produced by a pip and calls an action /// </summary> protected static void ForEachOutput <TState>(TState state, Pip pip, Action <TState, FileOrDirectoryArtifact> outputAction) { switch (pip.PipType) { case PipType.CopyFile: CopyFile copyFile = (CopyFile)pip; outputAction(state, FileOrDirectoryArtifact.Create(copyFile.Destination)); break; case PipType.Process: Process process = (Process)pip; foreach (var output in process.FileOutputs) { outputAction(state, FileOrDirectoryArtifact.Create(output.ToFileArtifact())); } foreach (var output in process.DirectoryOutputs) { outputAction(state, FileOrDirectoryArtifact.Create(output)); } break; case PipType.WriteFile: WriteFile writeFile = (WriteFile)pip; outputAction(state, FileOrDirectoryArtifact.Create(writeFile.Destination)); break; case PipType.SealDirectory: SealDirectory sealDirectory = (SealDirectory)pip; outputAction(state, FileOrDirectoryArtifact.Create(sealDirectory.Directory)); break; case PipType.Ipc: IpcPip ipcPip = (IpcPip)pip; outputAction(state, FileOrDirectoryArtifact.Create(ipcPip.OutputFile)); break; } }
/// <inheritdoc /> public bool AddIpcPip(IpcPip ipcPip, PipId valuePip) { Contract.Requires(ipcPip != null, "Argument pip cannot be null"); return(PipAlreadyReloaded(ipcPip) || m_builder.AddIpcPip(ipcPip, valuePip)); }
/// <inheritdoc /> public bool AddIpcPip([NotNull] IpcPip ipcPip, PipId valuePip) => AddPip(ipcPip);
/// <summary> /// Gets the inputs consumed by a pip and calls an action /// </summary> public static bool ForEachInput( Pip pip, Func <FileOrDirectoryArtifact, bool> inputAction, bool includeLazyInputs, Func <FileOrDirectoryArtifact, bool> overrideLazyInputAction = null) { // NOTE: Lazy inputs must be processed AFTER regular inputs // This behavior is required by FileContentManager.PopulateDepdencies bool result = true; switch (pip.PipType) { case PipType.CopyFile: CopyFile copyFile = (CopyFile)pip; result = inputAction(FileOrDirectoryArtifact.Create(copyFile.Source)); break; case PipType.Process: Process process = (Process)pip; foreach (var input in process.Dependencies) { if (!inputAction(FileOrDirectoryArtifact.Create(input))) { return(false); } } foreach (var input in process.DirectoryDependencies) { if (!inputAction(FileOrDirectoryArtifact.Create(input))) { return(false); } } break; case PipType.SealDirectory: SealDirectory sealDirectory = (SealDirectory)pip; foreach (var input in sealDirectory.Contents) { if (!inputAction(FileOrDirectoryArtifact.Create(input))) { return(false); } } break; case PipType.Ipc: IpcPip ipcPip = (IpcPip)pip; foreach (var input in ipcPip.FileDependencies) { if (!inputAction(FileOrDirectoryArtifact.Create(input))) { return(false); } } foreach (var input in ipcPip.DirectoryDependencies) { if (!inputAction(FileOrDirectoryArtifact.Create(input))) { return(false); } } if (includeLazyInputs) { overrideLazyInputAction = overrideLazyInputAction ?? inputAction; foreach (var input in ipcPip.LazilyMaterializedDependencies) { if (!overrideLazyInputAction(input)) { return(false); } } } break; } return(result); }
public void TestIpcPipConsumptionFromOtherFragment() { // Create fragment 1: // // h -> R -> g -> Q -> f -> P -> e var fragment1 = CreatePipGraphFragmentTest(nameof(TestIpcPipConsumptionFromOtherFragment) + "1"); var processBuilderP = fragment1.GetProcessBuilder(); var argumentsBuilderP = new ArgumentsBuilder(processBuilderP); var f = fragment1.CreateOutputFile("f"); argumentsBuilderP .AddInputFileOption("/input:", fragment1.CreateSourceFile("e")) .AddOutputFileOption("/output:", f.Path) .Finish(); (Process processP, ProcessOutputs outputsP) = fragment1.ScheduleProcessBuilder(processBuilderP); var processBuilderQ = fragment1.GetProcessBuilder(); var argumentsBuilderQ = new ArgumentsBuilder(processBuilderQ); var g = fragment1.CreateOutputFile("g"); argumentsBuilderQ .AddInputFileOption("/input:", outputsP.TryGetOutputFile(f.Path, out var fAsOutput) ? fAsOutput : FileArtifact.Invalid) .AddOutputFileOption("/output:", g.Path) .Finish(); (Process processQ, ProcessOutputs outputsQ) = fragment1.ScheduleProcessBuilder(processBuilderQ); var processBuilderR = fragment1.GetProcessBuilder(); var argumentsBuilderR = new ArgumentsBuilder(processBuilderR); var h = fragment1.CreateOutputFile("h"); argumentsBuilderR .AddInputFileOption("/input:", outputsQ.TryGetOutputFile(g.Path, out var gAsOutput) ? gAsOutput : FileArtifact.Invalid) .AddOutputFileOption("/output:", h.Path) .Finish(); (Process processR, ProcessOutputs outputsR) = fragment1.ScheduleProcessBuilder(processBuilderR); // Create fragment 2: // // z -> C -> x -> A -> w // | // + -> y -> B -> v var fragment2 = CreatePipGraphFragmentTest(nameof(TestIpcPipConsumptionFromOtherFragment) + "2"); var processBuilderA = fragment2.GetProcessBuilder(); var argumentsBuilderA = new ArgumentsBuilder(processBuilderA); var x = fragment2.CreateOutputFile("x"); argumentsBuilderA .AddInputFileOption("/input:", fragment2.CreateSourceFile("w")) .AddOutputFileOption("/output:", x.Path) .Finish(); (Process processA, ProcessOutputs outputsA) = fragment2.ScheduleProcessBuilder(processBuilderA); var processBuilderB = fragment2.GetProcessBuilder(); var argumentsBuilderB = new ArgumentsBuilder(processBuilderB); var y = fragment2.CreateOutputFile("y"); argumentsBuilderB .AddInputFileOption("/input:", fragment2.CreateSourceFile("v")) .AddOutputFileOption("/output:", y.Path) .Finish(); (Process processB, ProcessOutputs outputsB) = fragment2.ScheduleProcessBuilder(processBuilderB); var processBuilderC = fragment2.GetProcessBuilder(); var argumentsBuilderC = new ArgumentsBuilder(processBuilderC); var z = fragment2.CreateOutputFile("z"); argumentsBuilderC .AddInputFileOption("/input:", outputsB.TryGetOutputFile(y.Path, out var yAsOutput) ? yAsOutput : FileArtifact.Invalid) .AddInputFileOption("/input:", outputsA.TryGetOutputFile(x.Path, out var xAsOutput) ? xAsOutput : FileArtifact.Invalid) .AddOutputFileOption("/output:", z.Path) .Finish(); (Process processC, ProcessOutputs outputsC) = fragment2.ScheduleProcessBuilder(processBuilderC); // Drop z and h in fragment 2. (IIpcMoniker moniker, PipId servicePipId) = TestPipGraphFragmentUtils.CreateService(fragment2); var addZBuilder = fragment2.GetIpcProcessBuilder(); new ArgumentsBuilder(addZBuilder) .AddStringOption("--command ", "addFile") .AddIpcMonikerOption("--ipcMoniker ", moniker) .AddInputFileOption("--file ", z) .Finish(); IpcPip ipcPipZ = fragment2.ScheduleIpcPip( moniker, servicePipId, addZBuilder, fragment2.CreateOutputFile("addZ"), false); var addHBuilder = fragment2.GetIpcProcessBuilder(); new ArgumentsBuilder(addHBuilder) .AddStringOption("--command ", "addFile") .AddIpcMonikerOption("--ipcMoniker ", moniker) .AddInputFileOption("--file ", fragment2.CreateOutputFile("h")) // h is created by fragment 1. .Finish(); IpcPip ipcPipH = fragment2.ScheduleIpcPip( moniker, servicePipId, addHBuilder, fragment2.CreateOutputFile("addH"), false); var graph = SerializeAndDeserializeFragments(fragment1, fragment2); VerifyGraphSuccessfullyConstructed(graph); }
public void TestAddingAndUnifyingIpcPip() { var fragment = CreatePipGraphFragmentTest(nameof(TestAddingAndUnifyingIpcPip)); (IIpcMoniker moniker, PipId servicePipId) = TestPipGraphFragmentUtils.CreateService(fragment); var processBuilder = fragment.GetProcessBuilder(); var argumentsBuilder = new ArgumentsBuilder(processBuilder); FileArtifact outputFileToVerify = fragment.CreateOutputFile("g"); AbsolutePath outputDirectoryToVerify = fragment.CreateOutputDirectory("d").Path; argumentsBuilder .AddInputFileOption("/input:", fragment.CreateSourceFile("f")) .AddOutputFileOption("/output:", outputFileToVerify.Path) .AddOutputDirectoryOption("/outputDir:", outputDirectoryToVerify) .Finish(); (Process process, ProcessOutputs processOutputs) = fragment.ScheduleProcessBuilder(processBuilder); XAssert.IsTrue(processOutputs.TryGetOutputDirectory(outputDirectoryToVerify, out var outputDirectory)); var addFileProcessBuilder = fragment.GetIpcProcessBuilder(); new ArgumentsBuilder(addFileProcessBuilder) .AddStringOption("--command ", "addFile") .AddIpcMonikerOption("--ipcMoniker ", moniker) .AddInputFileOption("--file ", outputFileToVerify) .AddInputDirectoryOption("--directory ", outputDirectory.Root) .AddFileIdOption("--fileId ", outputFileToVerify) .AddDirectoryIdOption("--directoryId ", outputDirectory.Root) .AddVsoHashOption("--vsoHash ", outputFileToVerify) .Finish(); FileArtifact ipcOutputFileToVerify; IpcPip ipcPip = fragment.ScheduleIpcPip( moniker, servicePipId, addFileProcessBuilder, ipcOutputFileToVerify = fragment.CreateOutputFile("add"), false); var graph = SerializeAndDeserializeIndependentFragments(fragment, fragment); VerifyGraphSuccessfullyConstructed(graph); VerifyProducerExists(graph, fragment, outputFileToVerify.Path); VerifyProducerExists(graph, fragment, outputDirectoryToVerify); VerifyProducerExists(graph, fragment, ipcOutputFileToVerify); var remappedOutputFile = FileArtifact.CreateOutputFile(RemapFragmentPath(fragment, outputFileToVerify.Path)); var remappedOutputDirectory = DirectoryArtifact.CreateWithZeroPartialSealId(RemapFragmentPath(fragment, outputDirectory.Root)); PipData expectedArguments = new ArgumentsDataBuilder(Context.StringTable) .AddStringOption("--command ", "addFile") .AddIpcMonikerOption("--ipcMoniker ", moniker) .AddPathOption("--file ", remappedOutputFile.Path) .AddPathOption("--directory ", remappedOutputDirectory.Path) .AddFileIdOption("--fileId ", remappedOutputFile) .AddDirectoryIdOption("--directoryId ", remappedOutputDirectory) .AddVsoHashOption("--vsoHash ", remappedOutputFile) .Finish(); VerifyResultingArguments(graph, fragment, ipcOutputFileToVerify, expectedArguments); }
/// <inheritdoc /> public bool AddIpcPip(IpcPip ipcPip, PipId valuePip) { Contract.Requires(ipcPip != null, "Argument pip cannot be null"); Tracing.Logger.Log.CannotAddCreatePipsDuringConfigOrModuleEvaluation(Events.StaticContext); return(false); }
public void TestTopSort() { // Create fragment : // // z -> C --------+----> x -> A -> w // | | // | | // + -> y -> B -> v var fragment = CreatePipGraphFragment(nameof(TestTopSort), useTopSort: true); var processBuilderA = fragment.GetProcessBuilder(); var argumentsBuilderA = new ArgumentsBuilder(processBuilderA); var x = fragment.CreateOutputFile("x"); argumentsBuilderA .AddInputFileOption("/input:", fragment.CreateSourceFile("w")) .AddOutputFileOption("/output:", x.Path) .Finish(); (Process processA, ProcessOutputs outputsA) = fragment.ScheduleProcessBuilder(processBuilderA); var processBuilderB = fragment.GetProcessBuilder(); var argumentsBuilderB = new ArgumentsBuilder(processBuilderB); var y = fragment.CreateOutputFile("y"); argumentsBuilderB .AddInputFileOption("/input:", fragment.CreateSourceFile("v")) .AddInputFileOption("/input:", outputsA.TryGetOutputFile(x.Path, out var xAsOutput) ? xAsOutput : FileArtifact.Invalid) .AddOutputFileOption("/output:", y.Path) .Finish(); (Process processB, ProcessOutputs outputsB) = fragment.ScheduleProcessBuilder(processBuilderB); var processBuilderC = fragment.GetProcessBuilder(); var argumentsBuilderC = new ArgumentsBuilder(processBuilderC); var z = fragment.CreateOutputFile("z"); argumentsBuilderC .AddInputFileOption("/input:", outputsB.TryGetOutputFile(y.Path, out var yAsOutput) ? yAsOutput : FileArtifact.Invalid) .AddInputFileOption("/input:", outputsA.TryGetOutputFile(x.Path, out var xAsOutput2) ? xAsOutput2 : FileArtifact.Invalid) .AddOutputFileOption("/output:", z.Path) .Finish(); (Process processC, ProcessOutputs outputsC) = fragment.ScheduleProcessBuilder(processBuilderC); // Drop z and y. var serviceRelatedPips = new TestPipGraphFragmentUtils.ServiceRelatedPips(); (IIpcMoniker moniker, PipId servicePipId) = TestPipGraphFragmentUtils.CreateService(fragment, serviceRelatedPips); var addZBuilder = fragment.GetIpcProcessBuilder(); new ArgumentsBuilder(addZBuilder) .AddStringOption("--command ", "addFile") .AddIpcMonikerOption("--ipcMoniker ", moniker) .AddInputFileOption("--file ", z) .Finish(); IpcPip ipcPipZ = fragment.ScheduleIpcPip( moniker, servicePipId, addZBuilder, fragment.CreateOutputFile("addZ"), false); var addYBuilder = fragment.GetIpcProcessBuilder(); new ArgumentsBuilder(addYBuilder) .AddStringOption("--command ", "addFile") .AddIpcMonikerOption("--ipcMoniker ", moniker) .AddInputFileOption("--file ", y) .Finish(); IpcPip ipcPipY = fragment.ScheduleIpcPip( moniker, servicePipId, addYBuilder, fragment.CreateOutputFile("addY"), false); var sortedPips = new PipGraphFragmentTopSort(fragment.PipGraph).Sort(); XAssert.AreEqual(10, sortedPips.Count); // There are ten layers. XAssert.IsTrue(sortedPips[0].All(p => p is ModulePip)); // 0th layer is module pips. XAssert.IsTrue(sortedPips[1].All(p => p is SpecFilePip)); // 1st layer is spec pips. XAssert.IsTrue(sortedPips[2].All(p => p is ValuePip)); // 2nd layer is value pips. for (int i = 3; i <= 5; ++i) { // 3rd, 4th, and 5th layer are service related pips. XAssert.AreEqual(1, sortedPips[i].Count); XAssert.IsTrue(ServicePipKindUtil.IsServiceStartShutdownOrFinalizationPip(sortedPips[i][0])); } // 6th layer contains pip A and create drop pip. XAssert.AreEqual(2, sortedPips[6].Count); XAssert.Contains(sortedPips[6], serviceRelatedPips.Create, processA); // 7th layer contains pip B. XAssert.AreEqual(1, sortedPips[7].Count); XAssert.Contains(sortedPips[7], processB); // 8th layer contains pip C and create drop pip y. XAssert.AreEqual(2, sortedPips[8].Count); XAssert.Contains(sortedPips[8], ipcPipY, processC); // 9th layer contains drop pip z. XAssert.AreEqual(1, sortedPips[9].Count); XAssert.Contains(sortedPips[9], ipcPipZ); }
/// <summary> /// Checks whether an IPC pip has a non-service pip dependent /// </summary> public virtual bool HasRealConsumers(IpcPip pip) { return(false); }
/// <inheritdoc /> public virtual bool AddIpcPip([NotNull] IpcPip ipcPip, PipId valuePip) { AddPip(ipcPip); FileProducers[ipcPip.OutputFile] = ipcPip.PipId; return(true); }