public void ContentHashListWithDeterminismProperty() { var contentHashListWithDeterminism = new ContentHashListWithDeterminism( ContentHashList.Random(), CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), CacheDeterminism.NeverExpires)); Assert.Equal(contentHashListWithDeterminism, new GetContentHashListResult(contentHashListWithDeterminism).ContentHashListWithDeterminism); }
public void ViaCacheRoundtrip() { var guid = CacheDeterminism.NewCacheGuid(); var determinism = CacheDeterminism.ViaCache(guid, DateTime.MaxValue); Assert.Equal(guid, determinism.EffectiveGuid); }
/// <nodoc /> public static ContentHashListWithDeterminism FromGrpc(this ContentHashListWithDeterminismData input) { ContentHashList contentHashList = input.ContentHashList.FromGrpc(); CacheDeterminism determinism = FromGrpc(input.CacheDeterminism); return(new ContentHashListWithDeterminism(contentHashList, determinism)); }
/// <nodoc /> public MemCache(CacheId cacheId, bool strictMetadataCasCoupling, bool isauthoritative) { m_cacheGuid = CacheDeterminism.NewCacheGuid(); m_cacheId = cacheId; IsAuthoritative = isauthoritative; m_strictMetadataCasCoupling = strictMetadataCasCoupling; }
/// <summary> /// Load value from the filesystem. /// </summary> public static Guid Load(IAbsFileSystem fileSystem, AbsolutePath filePath) { Guid guid; try { // First try reading the GUID file guid = Read(fileSystem, filePath); } catch (Exception e) when(e is CacheException || e is IOException) { // If that fails, we likely need to create a Guid guid = CacheDeterminism.NewCacheGuid(); try { fileSystem.CreateDirectory(filePath.Parent); // Write the Guid file fileSystem.WriteAllBytes(filePath, Encoding.UTF8.GetBytes(guid.ToString(SerializationFormat))); } catch (Exception ex) when(ex is IOException) { // If we failed to write the Guid file we may have just missed getting the guid in the first place, // so let us try to read it again. This failure we let go all the way out. guid = Read(fileSystem, filePath); } } return(guid); }
private static CacheDeterminism ReadDeterminism(byte[] determinismBytes, byte[] oldDeterminismBytes) { var determinism = CacheDeterminism.Deserialize(determinismBytes); var oldDeterminismGuid = new Guid(oldDeterminismBytes); // If the old guid was ToolDeterministic, we need to keep it that way. if (oldDeterminismGuid == CacheDeterminism.Tool.Guid) { return(CacheDeterminism.Tool); } // If the old guid was SinglePhaseNonDeterministic, we need to keep it that way. if (oldDeterminismGuid == CacheDeterminism.SinglePhaseNonDeterministic.Guid) { return(CacheDeterminism.SinglePhaseNonDeterministic); } // The newer code always sets the old "Determinism" column to the same determinism guid when it writes a new value, // so if we read here that the determinism from the old column is different from // the new "SerializedDeterminism" column's guid then the ContentHashList in this row was inserted by the // old code and the new column's Determinism value is no longer valid. In that case, we return None. return(oldDeterminismGuid == determinism.EffectiveGuid ? determinism : CacheDeterminism.None); }
public void EqualsFalseContentHashListMismatch() { var determinism = CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), CacheDeterminism.NeverExpires); var v1 = new GetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), determinism)); var v2 = new GetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), determinism)); Assert.False(v1.Equals(v2)); }
public void NewCacheGuidCreatesNonSpecialValue() { var guid = CacheDeterminism.NewCacheGuid(); Assert.NotEqual(CacheDeterminism.None.EffectiveGuid, guid); Assert.NotEqual(CacheDeterminism.Tool.EffectiveGuid, guid); Assert.NotEqual(CacheDeterminism.SinglePhaseNonDeterministic.EffectiveGuid, guid); }
/// <nodoc /> public static CacheDeterminismData ToGrpc(this CacheDeterminism determinism) { return(new CacheDeterminismData { ExpirationUtc = determinism.ExpirationUtc.Ticks, Guid = determinism.Guid.ToByteArray().ToByteString() }); }
public void GetHashCodeNotSameWhenNotEqual() { var v1 = new GetContentHashListResult(new ContentHashListWithDeterminism( ContentHashList.Random(), CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), CacheDeterminism.NeverExpires))); var v2 = new GetContentHashListResult(new ContentHashListWithDeterminism( ContentHashList.Random(), CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), CacheDeterminism.NeverExpires))); Assert.NotEqual(v1.GetHashCode(), v2.GetHashCode()); }
public void EqualsFalseDeterminismMismatch() { var v1 = new AddOrGetContentHashListResult( new ContentHashListWithDeterminism(null, CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), DateTime.MaxValue))); var v2 = new AddOrGetContentHashListResult( new ContentHashListWithDeterminism(null, CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), DateTime.MaxValue))); Assert.False(v1.Equals(v2)); }
public async Task Roundtrip() { var fileName = $"{Guid.NewGuid()}.json"; using (var directory = new DisposableDirectory(FileSystem)) { var sessionId = 42; var serializedConfig = "Foo"; var pat = Guid.NewGuid().ToString(); var numOperations = 3; var operations = Enumerable.Range(0, numOperations) .Select(_ => generateRandomOperation()) .ToList(); var sessionInfo = new HibernatedCacheSessionInfo(sessionId, serializedConfig, pat, operations); var sessions1 = new HibernatedSessions <HibernatedCacheSessionInfo>(new List <HibernatedCacheSessionInfo> { sessionInfo }); await sessions1.WriteAsync(FileSystem, directory.Path, fileName); FileSystem.HibernatedSessionsExists(directory.Path, fileName).Should().BeTrue(); var fileSize = FileSystem.GetFileSize(directory.Path / fileName); fileSize.Should().BeGreaterThan(0); var sessions2 = await FileSystem.ReadHibernatedSessionsAsync <HibernatedCacheSessionInfo>(directory.Path, fileName); sessions2.Sessions.Count.Should().Be(1); sessions2.Sessions[0].Id.Should().Be(sessionId); sessions2.Sessions[0].SerializedSessionConfiguration.Should().Be(serializedConfig); sessions2.Sessions[0].Pat.Should().Be(pat); sessions2.Sessions[0].PendingPublishingOperations.Should().BeEquivalentTo(operations); await FileSystem.DeleteHibernatedSessions(directory.Path, fileName); PublishingOperation generateRandomOperation() { var amountOfHashes = 3; var hashes = Enumerable.Range(0, amountOfHashes).Select(_ => ContentHash.Random()).ToArray(); var contentHashList = new ContentHashList(hashes); var determinism = CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), DateTime.UtcNow.AddMilliseconds(ThreadSafeRandom.Generator.Next())); var contentHashListWithDeterminism = new ContentHashListWithDeterminism(contentHashList, determinism); var fingerprint = new Fingerprint(ContentHash.Random().ToByteArray()); var selector = new Selector(ContentHash.Random()); var strongFingerprint = new StrongFingerprint(fingerprint, selector); return(new PublishingOperation { ContentHashListWithDeterminism = contentHashListWithDeterminism, StrongFingerprint = strongFingerprint }); } } }
private ICache CreateBackendCache(AbsolutePath rootPath) { var configuration = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1); var configurationModel = new ConfigurationModel(configuration); return(new OneLevelCache( () => new FileSystemContentStore(FileSystem, SystemClock.Instance, rootPath, configurationModel), () => new MemoryMemoizationStore(Logger), CacheDeterminism.NewCacheGuid())); }
public virtual async Task NonDeterministicContentRespectsDisconnect() { string testCacheId = "Disconnected"; ICache testCache = await InitializeCacheAsync(NewCache(testCacheId, false)).SuccessAsync(); VerticalCacheAggregator vertCache = testCache as VerticalCacheAggregator; XAssert.IsNotNull(vertCache); ICacheSession aggregatorSession = (await testCache.CreateSessionAsync()).Success(); ICacheSession localSession = (await vertCache.LocalCache.CreateSessionAsync()).Success(); ICacheSession remoteSession = (await vertCache.RemoteCache.CreateSessionAsync()).Success(); VerticalCacheAggregatorSession vertSession = aggregatorSession as VerticalCacheAggregatorSession; XAssert.IsNotNull(vertSession); CallbackCacheSessionWrapper wrappedSession = vertSession.RemoteSession as CallbackCacheSessionWrapper; XAssert.IsNotNull(wrappedSession); PoisonSession(wrappedSession); CacheDeterminism determinismSource = CacheDeterminism.None; const string PipName = "TestPip"; // Populate the remote cache with one set of outputs. FullCacheRecord remoteCacheRecord = await FakeBuild.DoNonDeterministicPipAsync(remoteSession, PipName); // And the local cache with a set forced to be unique. FullCacheRecord localCacheRecord = await FakeBuild.DoNonDeterministicPipAsync(localSession, PipName, generateVerifiablePip: true); PoisonAllRemoteSessions(testCache); DisconnectRemoteCache(testCache); // Now query each cache, and verify only the remote content is in each. // Make sure the content is in each cache. (Placing the aggregator cache first will cause backfill of the local cache) foreach (var currentCache in new Tuple <ICache, CacheDeterminism, string, int>[] { new Tuple <ICache, CacheDeterminism, string, int>(testCache, CacheDeterminism.None, vertCache.LocalCache.CacheId, 1), new Tuple <ICache, CacheDeterminism, string, int>(vertCache.LocalCache, CacheDeterminism.None, vertCache.LocalCache.CacheId, 1) }) { await VerticalAggregatorBaseTests.ValidateItemsInCacheAsync( currentCache.Item1, localCacheRecord.StrongFingerprint.WeakFingerprint, new List <CasHash>(localCacheRecord.CasEntries), currentCache.Item2, localCacheRecord.StrongFingerprint.CasElement, currentCache.Item3, currentCache.Item4); } XAssert.IsTrue((await testCache.ShutdownAsync()).Succeeded); }
/// <inheritdoc /> public async Task <Possible <CacheEntryPublishResult, Failure> > TryPublishCacheEntryAsync( WeakContentFingerprint weakFingerprint, ContentHash pathSetHash, StrongContentFingerprint strongFingerprint, CacheEntry entry, CacheEntryPublishMode publishMode = CacheEntryPublishMode.CreateNew, PublishCacheEntryOptions options = default) { // We can request semantics appropriate for CreateNewOrReplaceExisting via CacheDeterminism.SinglePhaseNonDeterministic // Note that conflict-rejections / failures may still occur. CacheDeterminism determinism = publishMode == CacheEntryPublishMode.CreateNewOrReplaceExisting ? CacheDeterminism.SinglePhaseNonDeterministic : default(CacheDeterminism); // N.B. this includes the metadata hash. CasEntries adaptedHashes = new CasEntries( entry.ToArray(h => new CasHash(new global::BuildXL.Cache.Interfaces.Hash(h))), determinism); Possible <FullCacheRecordWithDeterminism, Failure> maybePublished = await PerformFingerprintCacheOperationAsync( () => m_cache.AddOrGetAsync( weak: new WeakFingerprintHash(new Hash(weakFingerprint.Hash)), casElement: new CasHash(new Hash(pathSetHash)), hashElement: new Hash(strongFingerprint.Hash), hashes: adaptedHashes, urgencyHint: options.ShouldPublishAssociatedContent ? UrgencyHint.RegisterAssociatedContent : UrgencyHint.SkipRegisterContent), nameof(TryPublishCacheEntryAsync)); if (maybePublished.Succeeded) { if (maybePublished.Result.Record == null) { // Happy path: Entry accepted without an alternative. return(CacheEntryPublishResult.CreatePublishedResult()); } else { // Less happy path: The underlying store has an alternative entry that we need to use instead. Possible <CacheEntry, Failure> maybeConvertedConflictingEntry = TryConvertCasEntriesToCacheEntry(maybePublished.Result.Record.CasEntries, maybePublished.Result.Record.CacheId); if (maybeConvertedConflictingEntry.Succeeded) { return(CacheEntryPublishResult.CreateConflictResult(maybeConvertedConflictingEntry.Result)); } else { return(maybeConvertedConflictingEntry.Failure.Annotate( "The cache returned a conflicting entry (rejecting the proposed entry), but the conflicting entry is invalid.")); } } } else { return(maybePublished.Failure); } }
protected override ICache CreateCache(DisposableDirectory testDirectory) { var rootPath = testDirectory.Path; var configuration = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1); var configurationModel = new ConfigurationModel(configuration); return(new OneLevelCache( () => new FileSystemContentStore(FileSystem, SystemClock.Instance, rootPath, configurationModel), () => new MemoryMemoizationStore(Logger), CacheDeterminism.NewCacheGuid())); }
public void EqualsTrueNotReferenceEqualContentHashList() { var contentHashList = ContentHashList.Random(); var determinism = CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), CacheDeterminism.NeverExpires); var contentHashListWithDeterminism1 = new ContentHashListWithDeterminism(contentHashList, determinism); var contentHashListWithDeterminism2 = new ContentHashListWithDeterminism(contentHashList, determinism); var v1 = new GetContentHashListResult(contentHashListWithDeterminism1); var v2 = new GetContentHashListResult(contentHashListWithDeterminism2); Assert.True(v1.Equals(v2)); }
private ICache CreateBlockingPublishingCache(AbsolutePath path) { var configuration = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1); var configurationModel = new ConfigurationModel(configuration); var contentStore = new FileSystemContentStore(FileSystem, SystemClock.Instance, path, configurationModel); var localCache = new OneLevelCache( () => contentStore, () => new MemoryMemoizationStore(Logger), CacheDeterminism.NewCacheGuid()); return(new PublishingCacheToContentStore(new PublishingCache <OneLevelCache>(localCache, new BlockingPublishingStore(), Guid.NewGuid()))); }
private async Task AddToEmptyCacheAsync(bool contentIsDeterministic) { string testCacheId = "Disconnected"; ICache testCache = await InitializeCacheAsync(NewCache(testCacheId, false)).SuccessAsync(); VerticalCacheAggregator vertCache = testCache as VerticalCacheAggregator; XAssert.IsNotNull(vertCache); CacheDeterminism localDeterminism = CacheDeterminism.None; if (contentIsDeterministic) { localDeterminism = CacheDeterminism.Tool; } CacheDeterminism initialDeterminism = contentIsDeterministic ? CacheDeterminism.Tool : CacheDeterminism.None; ICacheSession session = (await testCache.CreateSessionAsync()).Success(); VerticalCacheAggregatorSession vertSession = session as VerticalCacheAggregatorSession; XAssert.IsNotNull(vertSession); CallbackCacheSessionWrapper wrappedSession = vertSession.RemoteSession as CallbackCacheSessionWrapper; XAssert.IsNotNull(wrappedSession); PoisonSession(wrappedSession); DisconnectRemoteCache(testCache); FullCacheRecord cacheRecord = await FakeBuild.DoPipAsync(session, "TestPip", determinism: initialDeterminism); await VerticalAggregatorBaseTests.ValidateItemsInCacheAsync( vertCache.LocalCache, cacheRecord.StrongFingerprint.WeakFingerprint, new List <CasHash>(cacheRecord.CasEntries), localDeterminism, cacheRecord.StrongFingerprint.CasElement, vertCache.LocalCache.CacheId, 1); await VerticalAggregatorBaseTests.ValidateItemsInCacheAsync( vertCache.RemoteCache, cacheRecord.StrongFingerprint.WeakFingerprint, new List <CasHash>(cacheRecord.CasEntries), localDeterminism, cacheRecord.StrongFingerprint.CasElement, vertCache.RemoteCache.CacheId, 0); XAssert.IsTrue((await testCache.ShutdownAsync()).Succeeded); }
protected static IEnumerable <object[]> BuildDeterminismMatrix() { for (int i = -1; i < determinisms.Length; i++) { int localIndex = Math.Max(0, i); CacheDeterminism startDeterminismLocal = determinisms[localIndex]; CacheDeterminism startDeterminismRemote = determinisms[Math.Max(localIndex, 1)]; CacheDeterminism endDetermismLocal = startDeterminismLocal.IsDeterministicTool || startDeterminismRemote.IsDeterministicTool ? CacheDeterminism.Tool : CacheDeterminism.ViaCache(RemoteReferenceGuild, CacheDeterminism.NeverExpires); CacheDeterminism endDeterminismRemote = startDeterminismRemote; yield return(new object[] { BackingStoreTestClass.Self, BackingStoreTestClass.Self, startDeterminismLocal, startDeterminismRemote, endDetermismLocal, endDeterminismRemote }); } }
/// <inheritdoc /> public ContentHashListWithDeterminism AsContentHashList(RedisValue value) { const int partCount = 5; var parts = value.ToString().Split(new[] { RedisValueSeparator }, partCount, StringSplitOptions.None); Contract.Assert(parts.Length == partCount); var determinism = CacheDeterminism.Deserialize(HexUtilities.HexToBytes(parts[0])); var payload = parts[3] == RedisValueExistsSemaphore?HexUtilities.HexToBytes(parts[4]) : null; var hashList = parts[1] == RedisValueExistsSemaphore?ContentHashList.Deserialize(parts[2], payload) : null; return(new ContentHashListWithDeterminism(hashList, determinism)); }
/// <summary> /// Simple constructor of a fake pip definition. /// </summary> /// <param name="pipName">Require pip name (used as data too)</param> /// <param name="pipSize">Number of outputs</param> /// <param name="weakIndex">Output index used to produce the weak fingerprint</param> /// <param name="hashIndex">Output index used to produce the hash</param> /// <param name="determinism">The determinism to claim for new records</param> public PipDefinition(string pipName, int pipSize = 3, int weakIndex = 1, int hashIndex = 0, CacheDeterminism determinism = default(CacheDeterminism)) { Contract.Requires(pipName != null); Contract.Requires(pipSize > 0); Contract.Requires(weakIndex >= 0 && weakIndex < pipSize); Contract.Requires(hashIndex >= 0 && hashIndex < pipSize); PipName = pipName; PipSize = pipSize; WeakIndex = weakIndex; HashIndex = hashIndex; Determinism = determinism; }
public async Task DisconnectMostRemoteCacheAddNewReconnect() { string cacheId = "MutlipleCacheRemote"; ICache testCache = await InitializeCacheAsync(NewCache(cacheId, true, false, true)).SuccessAsync(); VerticalCacheAggregator lowerVert = testCache as VerticalCacheAggregator; XAssert.IsNotNull(lowerVert); CallbackCacheWrapper callbackCache = lowerVert.RemoteCache as CallbackCacheWrapper; XAssert.IsNotNull(callbackCache); VerticalCacheAggregator upperVert = callbackCache.WrappedCache as VerticalCacheAggregator; XAssert.IsNotNull(upperVert); ICacheSession session = await testCache.CreateSessionAsync().SuccessAsync(); VerticalAggregatorDisconnectTests.DisconnectCache(upperVert.RemoteCache); FullCacheRecord cacheRecord = await FakeBuild.DoPipAsync(session, "Test Pip"); VerticalAggregatorDisconnectTests.ConnectCache(upperVert.RemoteCache); // Now query each cache, and verify only the remote content is in each. var aggregatorStats = new Dictionary <string, double>(); var remoteDeterminism = CacheDeterminism.ViaCache(upperVert.RemoteCache.CacheGuid, CacheDeterminism.NeverExpires); foreach (var currentCache in new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >[] { new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >(testCache, remoteDeterminism, lowerVert.LocalCache.CacheId, 3, aggregatorStats), new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >(lowerVert.LocalCache, remoteDeterminism, lowerVert.LocalCache.CacheId, 1, null), new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >(upperVert.LocalCache, remoteDeterminism, upperVert.LocalCache.CacheId, 1, null), new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >(upperVert.RemoteCache, remoteDeterminism, upperVert.RemoteCache.CacheId, 1, null) }) { await ValidateItemsInCacheAsync( currentCache.Item1, cacheRecord.StrongFingerprint.WeakFingerprint, new List <CasHash>(cacheRecord.CasEntries), currentCache.Item2, cacheRecord.StrongFingerprint.CasElement, currentCache.Item3, currentCache.Item4); } await testCache.ShutdownAsync().SuccessAsync(); }
public Task AddOrGetContentHashListPassThrough() { var context = new Context(Logger); var strongFingerprint = StrongFingerprint.Random(); var contentHashListWithDeterminism = new ContentHashListWithDeterminism( ContentHashList.Random(), CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), CacheDeterminism.NeverExpires)); return(RunMockSessionTestAsync(context, session => { session.AddOrGetContentHashListAsync(context, strongFingerprint, contentHashListWithDeterminism, Token, NonDefaultUrgencyHint).ConfigureAwait(false).GetAwaiter().GetResult().ShouldBeSuccess(); Assert.True(_mockMemoizationSession.AddOrGetContentHashListAsyncParams.Contains(new Tuple <StrongFingerprint, ContentHashListWithDeterminism>(strongFingerprint, contentHashListWithDeterminism))); return Task.FromResult(0); })); }
/// <inheritdoc /> protected async Task <AddOrGetContentHashListResult> AddOrGetContentHashListAsync( Context context, StrongFingerprint strongFingerprint, ContentHashListWithDeterminism contentHashListWithDeterminism, ContentAvailabilityGuarantee guarantee) { try { DateTime expirationUtc = FingerprintTracker.GenerateNewExpiration(); var valueToAdd = new ContentHashListWithCacheMetadata( contentHashListWithDeterminism, expirationUtc, guarantee); Tracer.Debug( context, $"Adding contentHashList=[{valueToAdd.ContentHashListWithDeterminism.ContentHashList}] determinism=[{valueToAdd.ContentHashListWithDeterminism.Determinism}] to VSTS with contentAvailabilityGuarantee=[{valueToAdd.ContentGuarantee}] and expirationUtc=[{expirationUtc}]"); var contentHashListResponseObject = await ContentHashListAdapter.AddContentHashListAsync(context, CacheNamespace, strongFingerprint, valueToAdd).ConfigureAwait(false); if (!contentHashListResponseObject.Succeeded) { return(new AddOrGetContentHashListResult(contentHashListResponseObject)); } var contentHashListResponse = contentHashListResponseObject.Data; var inconsistencyErrorMessage = CheckForResponseInconsistency(contentHashListResponse); if (inconsistencyErrorMessage != null) { return(new AddOrGetContentHashListResult(inconsistencyErrorMessage)); } ContentHashList contentHashListToReturn = UnpackContentHashListAfterAdd( contentHashListWithDeterminism.ContentHashList, contentHashListResponse); CacheDeterminism determinismToReturn = UnpackDeterminism(contentHashListResponse, CacheId); if (guarantee == ContentAvailabilityGuarantee.AllContentBackedByCache && !determinismToReturn.IsDeterministic) { return(new AddOrGetContentHashListResult( "Inconsistent BuildCache service response. Unbacked values should never override backed values.")); } FingerprintTracker.Track(strongFingerprint, contentHashListResponse.GetRawExpirationTimeUtc()); return(new AddOrGetContentHashListResult(new ContentHashListWithDeterminism(contentHashListToReturn, determinismToReturn))); } catch (Exception e) { return(new AddOrGetContentHashListResult(e)); } }
public override Task FetchingContentFromLocalCacheUpdatesLocalCacheForDeterministicContentPopulatedRemote( BackingStoreTestClass localTestClass, BackingStoreTestClass remoteTestClass, CacheDeterminism initialDeterminismLocal, CacheDeterminism initialDeterminismRemote, CacheDeterminism finalDeterminismLocal, CacheDeterminism finalDeterminismRemote) { return(base.FetchingContentFromLocalCacheUpdatesLocalCacheForDeterministicContentPopulatedRemote( localTestClass, remoteTestClass, initialDeterminismLocal, initialDeterminismRemote, finalDeterminismLocal, finalDeterminismRemote)); }
public Task AddExpiredDeterminism() { var strongFingerprint = StrongFingerprint.Random(); var expirationUtc = DateTime.UtcNow - TimeSpan.FromDays(7); var guid = CacheDeterminism.NewCacheGuid(); var determinism = CacheDeterminism.ViaCache(guid, expirationUtc); var contentHashListWithDeterminism = new ContentHashListWithDeterminism(ContentHashList.Random(), determinism); return(RunTest((context, contentLocationDatabase) => { contentLocationDatabase.AddOrGetContentHashList( context, strongFingerprint, contentHashListWithDeterminism).ShouldBeSuccess(); var result = contentLocationDatabase.GetContentHashList(context, strongFingerprint); Assert.Equal(CacheDeterminism.None.EffectiveGuid, result.ContentHashListWithDeterminism.Determinism.EffectiveGuid); })); }
/// <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="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> /// <param name="generateVerifiablePip">Indicates that the pip generated should be verfiiable by CheckContentAsync</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. /// /// The outputs of this pip will be unique for each call, but have the same strong fingerprint. /// /// The WeakFingerprint and input hash element are derived from the pipName. /// </remarks> public static Task <FullCacheRecord> DoNonDeterministicPipAsync( ICacheSession session, string pipName, bool generateVerifiablePip = false, int pipSize = DefaultFakeBuildSize, CacheDeterminism determinism = default(CacheDeterminism), CasAccessMethod accessMethod = CasAccessMethod.Stream) { Contract.Requires(session != null); Contract.Requires(pipName != null); Contract.Requires(pipSize > 0); FakeStrongFingerprint fakePrint = FakeStrongFingerprint.Create(pipName, generateVerifiablePip, pipSize); return(DoPipAsyncImpl(session, fakePrint.WeakFingerprint, fakePrint.HashElement, fakePrint.FakeBuild, determinism, accessMethod)); }
/// <summary> /// Determine the Determinism to return. /// </summary> protected static CacheDeterminism UnpackDeterminism(ContentHashListWithCacheMetadata cacheMetadata, Guid cacheId) { Contract.Assert(cacheMetadata != null); if (cacheMetadata.ContentHashListWithDeterminism.Determinism.Guid == CacheDeterminism.Tool.Guid) { // Value is Tool-deterministic return(CacheDeterminism.Tool); } var expirationUtc = cacheMetadata.GetEffectiveExpirationTimeUtc(); return(expirationUtc == null ? CacheDeterminism.None // Value is unbacked in VSTS : CacheDeterminism.ViaCache(cacheId, expirationUtc.Value)); // Value is backed in VSTS }
public override Task AddingFpReplacedWithExistingRORemote( BackingStoreTestClass localTestClass, BackingStoreTestClass remoteTestClass, CacheDeterminism initialDeterminismLocal, CacheDeterminism initialDeterminsimRemote, CacheDeterminism finalDeterminismLocal, CacheDeterminism finalDeterminismRemote) { return(base.AddingFpReplacedWithExistingRORemote( localTestClass, remoteTestClass, initialDeterminismLocal, initialDeterminsimRemote, finalDeterminismLocal, finalDeterminismRemote)); }