예제 #1
0
        internal static ProcessPipExecutionPerformance Deserialize(BuildXLReader reader, PipExecutionLevel level, DateTime executionStart, DateTime executionStop, uint workerId)
        {
            var fingerprint = FingerprintUtilities.CreateFrom(reader);

            TimeSpan processExecutionTime = reader.ReadTimeSpan();
            FileMonitoringViolationCounters fileMonitoringViolations = ReadFileMonitoringViolationCounters(reader);
            IOCounters            ioCounters     = IOCounters.Deserialize(reader);
            TimeSpan              userTime       = reader.ReadTimeSpan();
            TimeSpan              kernelTime     = reader.ReadTimeSpan();
            ProcessMemoryCounters memoryCounters = ProcessMemoryCounters.Deserialize(reader);

            uint numberOfProcesses = reader.ReadUInt32Compact();

            return(new ProcessPipExecutionPerformance(
                       fingerprint: fingerprint,
                       level: level,
                       executionStart: executionStart,
                       executionStop: executionStop,
                       processExecutionTime: processExecutionTime,
                       fileMonitoringViolations: fileMonitoringViolations,
                       ioCounters: ioCounters,
                       userTime: userTime,
                       kernelTime: kernelTime,
                       memoryCounters: memoryCounters,
                       numberOfProcesses: numberOfProcesses,
                       workerId: workerId));
        }
예제 #2
0
        private void Test(string expected, string sampleContent)
        {
            var fingerprint = FingerprintUtilities.Hash(sampleContent);
            var actual      = FingerprintUtilities.FingerprintToFileName(fingerprint.ToByteArray());

            Assert.Equal(expected, actual);
        }
예제 #3
0
        /// <summary>
        /// Create a fingerprint from a content hash.
        /// </summary>
        public static Hash ToFingerprint(this CasHash casHash)
        {
            var hex         = casHash.ToString();
            var fingerprint = FingerprintUtilities.Hash(hex);

            return(new Hash(fingerprint));
        }
예제 #4
0
        private static ContentFingerprint CreateDownloadFingerprint(string baseText)
        {
            // In case something in the cached Bond data becomes incompatible, we must not match.
            const string VersionText = ", BondDataVersion=2;FingerprintVersion=1";
            var          fingerprint = FingerprintUtilities.Hash(baseText + VersionText);

            return(new ContentFingerprint(fingerprint));
        }
예제 #5
0
        public void TestFirstBitsAlwaysALetter(uint value)
        {
            var identifier = FingerprintUtilities.ToIdentifier(value);

            Assert.True(Char.IsLetter(identifier[0]));

            var identifierWithExtraBits = FingerprintUtilities.ToIdentifier(value, 7);

            Assert.True(Char.IsLetter(identifierWithExtraBits[0]));
        }
예제 #6
0
        private static (WeakContentFingerprint wf, StrongContentFingerprint sf) GetBuildManifestHashKey(ContentHash hash)
        {
            var hashBytes = hash.ToByteArray();

            Array.Resize(ref hashBytes, FingerprintUtilities.FingerprintLength);
            var wf = new WeakContentFingerprint(FingerprintUtilities.CreateFrom(hashBytes));
            var sf = new StrongContentFingerprint(wf.Hash);

            return(wf, sf);
        }
        private static Fingerprint CreateFakeFingerprint(byte seed)
        {
            byte[] b = new byte[FingerprintUtilities.FingerprintLength];
            for (int i = 0; i < b.Length; i++)
            {
                b[i] = seed;
            }

            return(FingerprintUtilities.CreateFrom(b));
        }
예제 #8
0
        private static Fingerprint TwiddleHashByte(Fingerprint fingerprint, int index)
        {
            Contract.Requires(index >= 0 && index < FingerprintUtilities.FingerprintLength);

            var buffer = new byte[FingerprintUtilities.FingerprintLength];

            fingerprint.Serialize(buffer);
            buffer[index] = unchecked ((byte)~buffer[index]);

            return(FingerprintUtilities.CreateFrom(buffer));
        }
예제 #9
0
        private void VerifyFingerprintText(Action <HashingHelper, PathTable> addStream, string expectedText)
        {
            // Need a trailing newline for even a single item.
            expectedText = expectedText + "\r\n";

            var pathTable = new PathTable();

            using (var withText = new HashingHelper(pathTable, recordFingerprintString: true))
            {
                addStream(withText, pathTable);

                Fingerprint actualHash = FingerprintUtilities.CreateFrom(withText.GenerateHash().ToByteArray());
                string      actualText = withText.FingerprintInputText;

                XAssert.AreEqual(expectedText, actualText, "Fingerprint text mismatched.");
            }
        }
예제 #10
0
        private Tuple <Fingerprint, string> ComputeTimestampBasedHashInternal(bool skipManifestCheckTestHook)
        {
            Stopwatch sw = Stopwatch.StartNew();

            // Computes a hash based on the paths and timestamps of all of the referenced files
            using (var wrapper = Pools.StringBuilderPool.GetInstance())
            {
                StringBuilder sb = wrapper.Instance;

                foreach (var file in GetRelevantRelativePaths(forServerDeployment: true))
                {
                    try
                    {
                        FileInfo fi = new FileInfo(Path.Combine(BaseDirectory, file));

                        sb.Append(fi.Name);
                        sb.Append(':');
                        sb.Append(fi.LastWriteTimeUtc.ToBinary());
                        sb.AppendLine();
                    }
#pragma warning disable ERP022 // TODO: This should really handle specific errors
                    catch
                    {
                        // noop for files that cannot be found. The manifest will include exteraneous files
                    }
#pragma warning restore ERP022 // Unobserved exception in generic exception handler
                }

                if (!skipManifestCheckTestHook)
                {
                    ContentHashingUtilities.SetDefaultHashType();
                    AddHashForManifestFile(sb);
                }

                if (sb.Length == 0)
                {
                    throw new BuildXLException("App Deployment hash could not be computed because no files from the deployment manifest could be accessed.");
                }

                string      text        = sb.ToString();
                Fingerprint fingerprint = FingerprintUtilities.Hash(text);
                ComputeTimestampBasedHashTime = sw.Elapsed;
                return(new Tuple <Fingerprint, string>(fingerprint, text));
            }
        }
예제 #11
0
        /// <summary>
        /// Tries to deserialize a graph fingerprint from the <paramref name="reader"/>.
        /// </summary>
        public static CompositeGraphFingerprint Deserialize(BinaryReader reader)
        {
            CompositeGraphFingerprint fingerprint = Zero;

            fingerprint.OverallFingerprint = new ContentFingerprint(reader);
            fingerprint.BuildEngineHash    = FingerprintUtilities.CreateFrom(reader);
            fingerprint.ConfigFileHash     = FingerprintUtilities.CreateFrom(reader);
            fingerprint.QualifierHash      = FingerprintUtilities.CreateFrom(reader);
            fingerprint.FilterHash         = FingerprintUtilities.CreateFrom(reader);

            bool filterExists = reader.ReadBoolean();

            if (filterExists)
            {
                fingerprint.EvaluationFilter = BuildXL.Pips.Filter.EvaluationFilter.Deserialize(reader);
            }

            return(fingerprint);
        }
예제 #12
0
        /// <summary>
        /// This will do a build into the session with a given name
        /// and output count.
        /// </summary>
        /// <param name="session">The cache session to work with</param>
        /// <param name="pipName">Some text that acts as a base element in the output</param>
        /// <param name="pipSize">Number of elements in the output.  Must be enough to cover the variants</param>
        /// <param name="weakIndex">Variant with different weak index - defaults to 1</param>
        /// <param name="hashIndex">Variant with different hash index - defaults to 0</param>
        /// <param name="accessMethod">Method (File or stream) for how files are materialized from the cache</param>
        /// <param name="determinism">Determinism to provide for new build records</param>
        /// <returns>The FullCacheRecord of the build</returns>
        /// <remarks>
        /// This will do a "fake build" including a cache lookup via weak fingerprints
        /// and then return either the existing FullCacheRecord or add the build as a new
        /// one.  A new FullCacheRecord will have the StrongFingerprint.CacheId set to NewRecordCacheId
        /// </remarks>
        public static Task <FullCacheRecord> DoPipAsync(
            ICacheSession session,
            string pipName,
            int pipSize   = DefaultFakeBuildSize,
            int weakIndex = 1,
            int hashIndex = 0,
            CacheDeterminism determinism = default(CacheDeterminism),
            CasAccessMethod accessMethod = CasAccessMethod.Stream)
        {
            Contract.Requires(session != null);
            Contract.Requires(pipName != null);
            Contract.Requires(pipSize > 0);
            Contract.Requires(weakIndex >= 0 && weakIndex < pipSize);
            Contract.Requires(hashIndex >= 0 && hashIndex < pipSize);

            FakeBuild fake = new FakeBuild(pipName, pipSize);

            WeakFingerprintHash weak = new WeakFingerprintHash(FingerprintUtilities.Hash(fake.OutputHashes[weakIndex].ToString()).ToByteArray());
            Hash simpleHash          = new Hash(FingerprintUtilities.Hash(fake.OutputHashes[hashIndex].ToString()));

            return(DoPipAsyncImpl(session, weak, simpleHash, fake, determinism, accessMethod));
        }
예제 #13
0
        private static async Task <Possible <PublishedEntryRef, Failure> > AdaptPublishedEntry(Task <Possible <StrongFingerprint, Failure> > cacheCoreEntryPromise, PublishedEntryRefLocality locality)
        {
            Possible <StrongFingerprint, Failure> maybeFingerprint = await cacheCoreEntryPromise;

            if (maybeFingerprint.Succeeded)
            {
                StrongFingerprint fingerprint = maybeFingerprint.Result;

                if (fingerprint is StrongFingerprintSentinel)
                {
                    return(PublishedEntryRef.Ignore);
                }

                return(new PublishedEntryRef(
                           pathSetHash: ContentHashingUtilities.CreateFrom(fingerprint.CasElement.ToArray()),
                           strongFingerprint: new StrongContentFingerprint(FingerprintUtilities.CreateFrom(fingerprint.HashElement.ToArray())),
                           oringinatingCache: fingerprint.CacheId,
                           locality: locality));
            }

            return(maybeFingerprint.Failure);
        }
예제 #14
0
 private static StrongContentFingerprint CreateStrongFingerprint(string content)
 {
     return(new StrongContentFingerprint(FingerprintUtilities.Hash(content)));
 }
예제 #15
0
 private static WeakContentFingerprint CreateWeakFingerprint(string content)
 {
     return(new WeakContentFingerprint(FingerprintUtilities.Hash(content)));
 }
예제 #16
0
 /// <nodoc />
 public ContentFingerprint(BinaryReader reader)
 {
     Hash = FingerprintUtilities.CreateFrom(reader);
 }
예제 #17
0
        private void Test(string expected, params byte[] bytes)
        {
            var actual = FingerprintUtilities.FingerprintToFileName(bytes);

            Assert.Equal(expected, actual);
        }
예제 #18
0
        private static string Hash(string content)
        {
            var hashedBlob = FingerprintUtilities.Hash(content);

            return(FingerprintUtilities.FingerprintToFileName(hashedBlob));
        }
예제 #19
0
 /// <summary>
 /// Reads fingerprints.
 /// </summary>
 internal static ContentFingerprint ReadContentFingerprint(this BinaryReader reader, byte[] buffer)
 {
     Array.Clear(buffer, 0, buffer.Length);
     reader.Read(buffer, 0, FingerprintUtilities.FingerprintLength);
     return(new ContentFingerprint(FingerprintUtilities.CreateFrom(buffer)));
 }
예제 #20
0
 /// <summary>
 /// Create a random StrongFingerprint
 /// </summary>
 public static StrongFingerprint CreateRandomStrongFingerprint(string cacheId)
 {
     return(new StrongFingerprint(CreateRandomWeakFingerprintHash(), CreateRandomCasHash(), new Hash(FingerprintUtilities.CreateRandom()), cacheId));
 }
예제 #21
0
 public void TestSomeValues(uint value, string expected)
 {
     Assert.Equal(expected, FingerprintUtilities.ToIdentifier(value));
 }
예제 #22
0
 private static void Write(this BinaryWriter writer, Fingerprint fingerprint)
 {
     FingerprintUtilities.WriteTo(fingerprint, writer);
 }
예제 #23
0
 /// <summary>
 /// Generates the final hash value for the whole fingerprint stream.
 /// </summary>
 public Fingerprint GenerateHash()
 {
     byte[] res = GenerateHashBytes();
     return(FingerprintUtilities.CreateFrom(res));
 }
예제 #24
0
 /// <summary>
 /// Returns a generic <see cref="ContentFingerprint"/> (not distinguished as strong or weak).
 /// TODO: The generic fingerprint type can go away as soon as we *only* do two-phase (weak -> strong) lookups;
 ///       as of writing we are transitioning.
 /// </summary>
 public ContentFingerprint ToGenericFingerprint()
 {
     return(new ContentFingerprint(FingerprintUtilities.CreateFrom(Hash.ToByteArray())));
 }
예제 #25
0
        public async Task TestHistoricMetadataPathStringRoundtrip()
        {
            LoggingContext loggingContext = CreateLoggingContextForTest();

            PipExecutionContext   context;
            HistoricMetadataCache cache = null;
            var hmcFolderName           = "hmc";

            for (int i = 0; i < 3; i++)
            {
                CreateHistoricCache(loggingContext, hmcFolderName, out context, out cache, out var memoryArtifactCache);

                var process1 = SchedulerTest.CreateDummyProcess(context, new PipId(1));
                var process2 = SchedulerTest.CreateDummyProcess(context, new PipId(2));

                var pathTable = context.PathTable;

                // Add some random paths to ensure path table indices are different after loading
                AbsolutePath.Create(pathTable, X("/H/aslj/sfas/832.stxt"));
                AbsolutePath.Create(pathTable, X("/R/f/s/Historic"));
                AbsolutePath.Create(pathTable, X("/M/hgf/sf4as/83afsd"));
                AbsolutePath.Create(pathTable, X("/Z/bd/sfas/Cache"));

                var abPath1 = AbsolutePath.Create(pathTable, X("/H/aslj/sfas/p1OUT.bin"));
                var abPath2 = AbsolutePath.Create(pathTable, X("/H/aslj/sfas/P2.txt"));

                var pathSet1 = ObservedPathSetTestUtilities.CreatePathSet(
                    pathTable,
                    X("/X/a/b/c"),
                    X("/X/d/e"),
                    X("/X/a/b/c/d"));

                PipCacheDescriptorV2Metadata metadata1 =
                    new PipCacheDescriptorV2Metadata
                {
                    StaticOutputHashes = new List <AbsolutePathFileMaterializationInfo>
                    {
                        new AbsolutePathFileMaterializationInfo
                        {
                            AbsolutePath = abPath1.GetName(pathTable).ToString(context.StringTable),
                            Info         = new BondFileMaterializationInfo {
                                FileName = "p1OUT.bin"
                            }
                        }
                    }
                };

                var storedPathSet1 = await cache.TryStorePathSetAsync(pathSet1, preservePathCasing : false);

                var storedMetadata1 = await cache.TryStoreMetadataAsync(metadata1);

                var weakFingerprint1   = new WeakContentFingerprint(FingerprintUtilities.CreateRandom());
                var strongFingerprint1 = new StrongContentFingerprint(FingerprintUtilities.CreateRandom());

                var cacheEntry = new CacheEntry(storedMetadata1.Result, nameof(HistoricMetadataCacheTests), ArrayView <ContentHash> .Empty);

                var publishedCacheEntry = await cache.TryPublishCacheEntryAsync(process1, weakFingerprint1, storedPathSet1.Result, strongFingerprint1, cacheEntry);

                var pathSet2 = ObservedPathSetTestUtilities.CreatePathSet(
                    pathTable,
                    X("/F/a/y/c"),
                    X("/B/d/e"),
                    X("/G/a/z/c/d"),
                    X("/B/a/b/c"));

                PipCacheDescriptorV2Metadata metadata2 =
                    new PipCacheDescriptorV2Metadata
                {
                    StaticOutputHashes = new List <AbsolutePathFileMaterializationInfo>
                    {
                        new AbsolutePathFileMaterializationInfo
                        {
                            AbsolutePath = abPath2.ToString(pathTable),
                            Info         = new BondFileMaterializationInfo {
                                FileName = abPath2.GetName(pathTable).ToString(context.StringTable)
                            }
                        }
                    },
                    DynamicOutputs = new List <List <RelativePathFileMaterializationInfo> >
                    {
                        new List <RelativePathFileMaterializationInfo>
                        {
                            new RelativePathFileMaterializationInfo
                            {
                                RelativePath = @"dir\P2Dynamic.txt",
                                Info         = new BondFileMaterializationInfo {
                                    FileName = "p2dynamic.txt"
                                }
                            },
                            new RelativePathFileMaterializationInfo
                            {
                                RelativePath = @"dir\P2dynout2.txt",
                                Info         = new BondFileMaterializationInfo {
                                    FileName = null
                                }
                            }
                        }
                    }
                };

                var storedPathSet2 = await cache.TryStorePathSetAsync(pathSet2, preservePathCasing : false);

                var storedMetadata2 = await cache.TryStoreMetadataAsync(metadata2);

                var cacheEntry2 = new CacheEntry(storedMetadata2.Result, nameof(HistoricMetadataCacheTests), ArrayView <ContentHash> .Empty);

                var strongFingerprint2 = new StrongContentFingerprint(FingerprintUtilities.CreateRandom());

                var publishedCacheEntry2 = await cache.TryPublishCacheEntryAsync(process1, weakFingerprint1, storedPathSet2.Result, strongFingerprint2, cacheEntry2);

                await cache.CloseAsync();

                memoryArtifactCache.Clear();

                PipExecutionContext   loadedContext;
                HistoricMetadataCache loadedCache;

                TaskSourceSlim <bool> loadCompletionSource = TaskSourceSlim.Create <bool>();
                TaskSourceSlim <bool> loadCalled           = TaskSourceSlim.Create <bool>();
                BoxRef <bool>         calledLoad           = new BoxRef <bool>();
                CreateHistoricCache(loggingContext, "hmc", out loadedContext, out loadedCache, out memoryArtifactCache, loadTask: async hmc =>
                {
                    loadCalled.SetResult(true);
                    await loadCompletionSource.Task;
                });

                var operationContext      = OperationContext.CreateUntracked(loggingContext);
                var retrievePathSet1Task  = loadedCache.TryRetrievePathSetAsync(operationContext, WeakContentFingerprint.Zero, storedPathSet1.Result);
                var retrievdMetadata1Task = loadedCache.TryRetrieveMetadataAsync(
                    process1,
                    WeakContentFingerprint.Zero,
                    StrongContentFingerprint.Zero,
                    storedMetadata1.Result,
                    storedPathSet1.Result);

                var getCacheEntry1Task = loadedCache.TryGetCacheEntryAsync(
                    process1,
                    weakFingerprint1,
                    storedPathSet1.Result,
                    strongFingerprint1);

                Assert.False(retrievePathSet1Task.IsCompleted, "Before load task completes. TryRetrievePathSetAsync operations should block");
                Assert.False(retrievdMetadata1Task.IsCompleted, "Before load task completes. TryRetrieveMetadataAsync operations should block");
                Assert.False(getCacheEntry1Task.IsCompleted, "Before load task completes. TryGetCacheEntryAsync operations should block");

                Assert.True(loadCalled.Task.Wait(TimeSpan.FromSeconds(10)) && loadCalled.Task.Result, "Load should have been called in as a result of querying");
                loadCompletionSource.SetResult(true);

                var maybeLoadedPathSet1    = await retrievePathSet1Task;
                var maybeLoadedMetadata1   = await retrievdMetadata1Task;
                var maybeLoadedCacheEntry1 = await getCacheEntry1Task;

                Assert.Equal(storedMetadata1.Result, maybeLoadedCacheEntry1.Result.Value.MetadataHash);

                var maybeLoadedPathSet2 = await loadedCache.TryRetrievePathSetAsync(operationContext, WeakContentFingerprint.Zero, storedPathSet2.Result);

                var maybeLoadedMetadata2 = await loadedCache.TryRetrieveMetadataAsync(
                    process2,
                    WeakContentFingerprint.Zero,
                    StrongContentFingerprint.Zero,
                    storedMetadata2.Result,
                    storedPathSet2.Result);

                AssertPathSetEquals(pathTable, pathSet1, loadedContext.PathTable, maybeLoadedPathSet1.Result);
                AssertPathSetEquals(pathTable, pathSet2, loadedContext.PathTable, maybeLoadedPathSet2.Result);
                AssertMetadataEquals(metadata1, maybeLoadedMetadata1.Result);
                AssertMetadataEquals(metadata2, maybeLoadedMetadata2.Result);

                await loadedCache.CloseAsync();
            }
        }
예제 #26
0
        public void TestProcessExecutionResultSerialization()
        {
            var reportedAccess = CreateRandomReportedFileAccess();

            Fingerprint fingerprint = FingerprintUtilities.CreateRandom();

            var processExecutionResult = ExecutionResult.CreateSealed(
                result: PipResultStatus.Succeeded,
                numberOfWarnings: 12,
                outputContent: ReadOnlyArray <(FileArtifact, FileMaterializationInfo, PipOutputOrigin)> .FromWithoutCopy(CreateRandomOutputContent(), CreateRandomOutputContent()),
                directoryOutputs: ReadOnlyArray <(DirectoryArtifact, ReadOnlyArray <FileArtifact>)> .FromWithoutCopy(CreateRandomOutputDirectory(), CreateRandomOutputDirectory()),
                performanceInformation: new ProcessPipExecutionPerformance(
                    PipExecutionLevel.Executed,
                    DateTime.UtcNow,
                    DateTime.UtcNow + TimeSpan.FromMinutes(2),
                    FingerprintUtilities.ZeroFingerprint,
                    TimeSpan.FromMinutes(2),
                    new FileMonitoringViolationCounters(2, 3, 4),
                    default(IOCounters),
                    TimeSpan.FromMinutes(3),
                    TimeSpan.FromMinutes(3),
                    ProcessMemoryCounters.CreateFromBytes(12324, 12325, 12326, 12326),
                    33,
                    7,
                    0),
                fingerprint: new WeakContentFingerprint(fingerprint),
                fileAccessViolationsNotAllowlisted: new[]
            {
                reportedAccess,
                CreateRandomReportedFileAccess(),

                // Create reported file access that uses the same process to test deduplication during deserialization
                CreateRandomReportedFileAccess(reportedAccess.Process),
            },
                allowlistedFileAccessViolations: new ReportedFileAccess[0],
                mustBeConsideredPerpetuallyDirty: true,
                dynamicallyObservedFiles: ReadOnlyArray <AbsolutePath> .FromWithoutCopy(
                    CreateSourceFile().Path,
                    CreateSourceFile().Path
                    ),
                dynamicallyProbedFiles: ReadOnlyArray <AbsolutePath> .FromWithoutCopy(
                    CreateSourceFile().Path,
                    CreateSourceFile().Path,
                    CreateSourceFile().Path
                    ),
                dynamicallyObservedEnumerations: ReadOnlyArray <AbsolutePath> .FromWithoutCopy(
                    CreateSourceFile().Path
                    ),
                allowedUndeclaredSourceReads: new ReadOnlyHashSet <AbsolutePath> {
                CreateSourceFile().Path,
                CreateSourceFile().Path
            },
                absentPathProbesUnderOutputDirectories: new ReadOnlyHashSet <AbsolutePath> {
                CreateSourceFile().Path,
                CreateSourceFile().Path
            },
                twoPhaseCachingInfo: new TwoPhaseCachingInfo(
                    new WeakContentFingerprint(Fingerprint.Random(FingerprintUtilities.FingerprintLength)),
                    ContentHashingUtilities.CreateRandom(),
                    new StrongContentFingerprint(Fingerprint.Random(FingerprintUtilities.FingerprintLength)),
                    new CacheEntry(ContentHashingUtilities.CreateRandom(), null, CreateRandomContentHashArray())),
                pipCacheDescriptorV2Metadata: null,
                converged: true,
                pathSet: null,
                cacheLookupStepDurations: null,
                pipProperties: new Dictionary <string, int> {
                { "Foo", 1 }, { "Bar", 9 }
            },
                hasUserRetries: true);

            ExecutionResultSerializer serializer = new ExecutionResultSerializer(0, Context);

            ExecutionResult deserializedProcessExecutionResult;

            using (var stream = new MemoryStream())
                using (var writer = new BuildXLWriter(false, stream, true, false))
                    using (var reader = new BuildXLReader(false, stream, true))
                    {
                        serializer.Serialize(writer, processExecutionResult, preservePathCasing: false);

                        stream.Position = 0;

                        deserializedProcessExecutionResult = serializer.Deserialize(reader,
                                                                                    processExecutionResult.PerformanceInformation.WorkerId);
                    }

            // Ensure successful pip result is changed to not materialized.
            XAssert.AreEqual(PipResultStatus.NotMaterialized, deserializedProcessExecutionResult.Result);

            AssertEqual(processExecutionResult, deserializedProcessExecutionResult,
                        r => r.NumberOfWarnings,
                        r => r.Converged,

                        r => r.OutputContent.Length,
                        r => r.DirectoryOutputs.Length,

                        r => r.PerformanceInformation.ExecutionLevel,
                        r => r.PerformanceInformation.ExecutionStop,
                        r => r.PerformanceInformation.ExecutionStart,
                        r => r.PerformanceInformation.ProcessExecutionTime,
                        r => r.PerformanceInformation.FileMonitoringViolations.NumFileAccessViolationsNotAllowlisted,
                        r => r.PerformanceInformation.FileMonitoringViolations.NumFileAccessesAllowlistedAndCacheable,
                        r => r.PerformanceInformation.FileMonitoringViolations.NumFileAccessesAllowlistedButNotCacheable,
                        r => r.PerformanceInformation.UserTime,
                        r => r.PerformanceInformation.KernelTime,
                        r => r.PerformanceInformation.MemoryCounters.PeakWorkingSetMb,
                        r => r.PerformanceInformation.MemoryCounters.AverageWorkingSetMb,
                        r => r.PerformanceInformation.MemoryCounters.PeakCommitSizeMb,
                        r => r.PerformanceInformation.MemoryCounters.AverageCommitSizeMb,

                        r => r.PerformanceInformation.NumberOfProcesses,

                        r => r.FileAccessViolationsNotAllowlisted.Count,
                        r => r.MustBeConsideredPerpetuallyDirty,
                        r => r.DynamicallyObservedFiles.Length,
                        r => r.DynamicallyProbedFiles.Length,
                        r => r.DynamicallyObservedEnumerations.Length,
                        r => r.AllowedUndeclaredReads.Count,

                        r => r.TwoPhaseCachingInfo.WeakFingerprint,
                        r => r.TwoPhaseCachingInfo.StrongFingerprint,
                        r => r.TwoPhaseCachingInfo.PathSetHash,
                        r => r.TwoPhaseCachingInfo.CacheEntry.MetadataHash,
                        r => r.TwoPhaseCachingInfo.CacheEntry.OriginatingCache,
                        r => r.TwoPhaseCachingInfo.CacheEntry.ReferencedContent.Length,

                        r => r.PipProperties.Count,
                        r => r.HasUserRetries,
                        r => r.RetryInfo
                        );

            for (int i = 0; i < processExecutionResult.OutputContent.Length; i++)
            {
                int j = i;
                AssertEqual(processExecutionResult, deserializedProcessExecutionResult,
                            r => r.OutputContent[j].Item1,
                            r => r.OutputContent[j].Item2
                            );

                // Ensure that output origin from deserialzed output content is changed to not materialized.
                XAssert.AreEqual(PipOutputOrigin.NotMaterialized, deserializedProcessExecutionResult.OutputContent[i].Item3);
            }

            for (int i = 0; i < processExecutionResult.DirectoryOutputs.Length; i++)
            {
                var expected = processExecutionResult.DirectoryOutputs[i];
                var result   = deserializedProcessExecutionResult.DirectoryOutputs[i];
                XAssert.AreEqual(expected.Item1, result.Item1);
                XAssert.AreEqual(expected.Item2.Length, result.Item2.Length);

                for (int j = 0; j < expected.Item2.Length; j++)
                {
                    XAssert.AreEqual(expected.Item2[j], result.Item2[j]);
                }
            }

            for (int i = 0; i < processExecutionResult.FileAccessViolationsNotAllowlisted.Count; i++)
            {
                // Compare individual fields for ReportedFileAccess since it uses reference
                // equality for reported process which would not work for serialization/deserialization
                AssertEqual(processExecutionResult.FileAccessViolationsNotAllowlisted[i], deserializedProcessExecutionResult.FileAccessViolationsNotAllowlisted[i]);
            }

            // Ensure that reported process instances are deduplicated.
            XAssert.AreSame(deserializedProcessExecutionResult.FileAccessViolationsNotAllowlisted[0].Process,
                            deserializedProcessExecutionResult.FileAccessViolationsNotAllowlisted[2].Process);

            for (int i = 0; i < processExecutionResult.DynamicallyObservedFiles.Length; i++)
            {
                AssertEqual(processExecutionResult.DynamicallyObservedFiles[i], deserializedProcessExecutionResult.DynamicallyObservedFiles[i]);
            }

            for (int i = 0; i < processExecutionResult.DynamicallyProbedFiles.Length; i++)
            {
                AssertEqual(processExecutionResult.DynamicallyProbedFiles[i], deserializedProcessExecutionResult.DynamicallyProbedFiles[i]);
            }

            for (int i = 0; i < processExecutionResult.DynamicallyObservedEnumerations.Length; i++)
            {
                AssertEqual(processExecutionResult.DynamicallyObservedEnumerations[i], deserializedProcessExecutionResult.DynamicallyObservedEnumerations[i]);
            }

            XAssert.AreSetsEqual(processExecutionResult.AllowedUndeclaredReads, deserializedProcessExecutionResult.AllowedUndeclaredReads, expectedResult: true);

            var referencedContentLength = processExecutionResult.TwoPhaseCachingInfo.CacheEntry.ReferencedContent.Length;

            for (int i = 0; i < referencedContentLength; i++)
            {
                XAssert.AreEqual(
                    processExecutionResult.TwoPhaseCachingInfo.CacheEntry.ReferencedContent[i],
                    deserializedProcessExecutionResult.TwoPhaseCachingInfo.CacheEntry.ReferencedContent[i]);
            }

            XAssert.AreEqual(9, deserializedProcessExecutionResult.PipProperties["Bar"]);
        }
예제 #27
0
 private static Fingerprint ReadFingerprint(this BinaryReader reader)
 {
     return(FingerprintUtilities.CreateFrom(reader));
 }
예제 #28
0
        public async Task DisconnectedCacheNotQueriedForStrongFingerprints()
        {
            string testCacheId = "Disconnected";
            ICache testCache   = await InitializeCacheAsync(NewCache(testCacheId, false)).SuccessAsync();

            PoisonAllRemoteSessions(testCache);

            ICacheReadOnlySession roSession = await testCache.CreateReadOnlySessionAsync().SuccessAsync();

            DisconnectRemoteCache(testCache);

            FakeBuild fb = new FakeBuild("test", 1);

            foreach (var fingerprint in roSession.EnumerateStrongFingerprints(new WeakFingerprintHash(FingerprintUtilities.Hash("fingerprint").ToByteArray())))
            {
                // Just run the enumerator, should all return.
            }
        }
예제 #29
0
        private static string Hash(string content)
        {
            var murmurHash = MurmurHash3.Create(Encoding.UTF8.GetBytes(content));

            return(FingerprintUtilities.FingerprintToFileName(murmurHash.ToByteArray()));
        }
예제 #30
0
 private static Fingerprint GetHashForString(string target)
 {
     return(FingerprintUtilities.Hash(target));
 }