internal static CacheEntry CreateFromStream(BinaryReader reader) { CacheEntryTypes entryType = (CacheEntryTypes)reader.ReadByte(); CacheEntry entry = null; switch (entryType) { case CacheEntryTypes.BuildItem: entry = new BuildItemCacheEntry(); break; case CacheEntryTypes.BuildResult: entry = new BuildResultCacheEntry(); break; case CacheEntryTypes.Property: entry = new PropertyCacheEntry(); break; default: ErrorUtilities.VerifyThrow(false, "Should not get to the default of CacheEntryCustomSerializer CreateFromStream"); break; } entry.CreateFromStream(reader); return(entry); }
public void CacheEntryGettersDefaultConstructors() { BuildItem[] buildItems = new BuildItem[2] { null, null }; BuildItemCacheEntry tice = new BuildItemCacheEntry(); Assertion.AssertEquals(null, tice.Name); Assertion.AssertEquals(null, tice.BuildItems); tice.Name = "tice"; tice.BuildItems = buildItems; Assertion.AssertEquals("tice", tice.Name); Assertion.AssertEquals(buildItems, tice.BuildItems); PropertyCacheEntry pce = new PropertyCacheEntry(); Assertion.AssertEquals(null, pce.Name); Assertion.AssertEquals(null, pce.Value); pce.Name = "pce"; pce.Value = "propertyValue"; Assertion.AssertEquals("pce", pce.Name); Assertion.AssertEquals("propertyValue", pce.Value); BuildResultCacheEntry brce = new BuildResultCacheEntry(); Assertion.AssertEquals(null, brce.Name); Assertion.AssertEquals(null, brce.BuildItems); Assertion.AssertEquals(default(bool), brce.BuildResult); brce.Name = "brce"; brce.BuildItems = buildItems; brce.BuildResult = false; Assertion.AssertEquals("brce", brce.Name); Assertion.AssertEquals(buildItems, brce.BuildItems); Assertion.AssertEquals(false, brce.BuildResult); }
public void IsEquivalentProperty() { PropertyCacheEntry e = new PropertyCacheEntry("name", "value"); Assert.IsFalse(e.IsEquivalent(null)); Assert.IsFalse(e.IsEquivalent(new BuildItemCacheEntry())); Assert.IsFalse(e.IsEquivalent(new PropertyCacheEntry())); Assert.IsFalse(e.IsEquivalent(new PropertyCacheEntry("naame", "value"))); Assert.IsFalse(e.IsEquivalent(new PropertyCacheEntry("name", "valuue"))); Assert.IsTrue(e.IsEquivalent(new PropertyCacheEntry("name", "value"))); }
/// <summary> /// Returns true if the given cache entry contains equivalent contents /// </summary> /// <param name="other"></param> /// <returns></returns> internal override bool IsEquivalent(CacheEntry other) { if ((other == null) || (other.GetType() != this.GetType())) { return(false); } PropertyCacheEntry otherEntry = (PropertyCacheEntry)other; if (this.Name != otherEntry.Name) { return(false); } return(this.Value == otherEntry.Value); }
public void CacheEntryGetters() { BuildItem[] buildItems = new BuildItem[2] { null, null }; BuildItemCacheEntry tice = new BuildItemCacheEntry("tice", buildItems); Assertion.AssertEquals("tice", tice.Name); Assertion.AssertEquals(buildItems, tice.BuildItems); PropertyCacheEntry pce = new PropertyCacheEntry("pce", "propertyValue"); Assertion.AssertEquals("pce", pce.Name); Assertion.AssertEquals("propertyValue", pce.Value); BuildResultCacheEntry brce = new BuildResultCacheEntry("brce", buildItems, true); Assertion.AssertEquals("brce", brce.Name); Assertion.AssertEquals(buildItems, brce.BuildItems); Assertion.AssertEquals(true, brce.BuildResult); }
internal static CacheEntry CreateFromStream(BinaryReader reader) { CacheEntryTypes entryType = (CacheEntryTypes) reader.ReadByte(); CacheEntry entry = null; switch (entryType) { case CacheEntryTypes.BuildItem: entry = new BuildItemCacheEntry(); break; case CacheEntryTypes.BuildResult: entry = new BuildResultCacheEntry(); break; case CacheEntryTypes.Property: entry = new PropertyCacheEntry(); break; default: ErrorUtilities.VerifyThrow(false, "Should not get to the default of CacheEntryCustomSerializer CreateFromStream"); break; } entry.CreateFromStream(reader); return entry; }
public void TestCacheEntryCustomSerialization() { // Stream, writer and reader where the events will be serialized and deserialized from MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); BinaryReader reader = new BinaryReader(stream); try { BuildItem buildItem1 = new BuildItem("BuildItem1", "Item1"); BuildItem buildItem2 = new BuildItem("BuildItem2", "Item2"); buildItem1.Include = "TestInclude1"; buildItem2.Include = "TestInclude2"; BuildItem[] buildItems = new BuildItem[2]; buildItems[0] = buildItem1; buildItems[1] = buildItem2; BuildItemCacheEntry buildItemEntry = new BuildItemCacheEntry("Badger", buildItems); BuildResultCacheEntry buildResultEntry = new BuildResultCacheEntry("Koi", buildItems, true); PropertyCacheEntry propertyEntry = new PropertyCacheEntry("Seagull", "bread"); stream.Position = 0; // Serialize buildItemEntry.WriteToStream(writer); // Get position of stream after write so it can be compared to the position after read long streamWriteEndPosition = stream.Position; // Deserialize and Verify stream.Position = 0; BuildItemCacheEntry newCacheEntry = new BuildItemCacheEntry(); newCacheEntry.CreateFromStream(reader); long streamReadEndPosition = stream.Position; Assert.IsTrue(streamWriteEndPosition == streamReadEndPosition, "Stream End Positions Should Match"); Assert.IsTrue(string.Compare(newCacheEntry.Name, buildItemEntry.Name, StringComparison.OrdinalIgnoreCase) == 0); BuildItem[] buildItemArray = newCacheEntry.BuildItems; Assert.IsTrue(buildItemArray.Length == 2); Assert.IsTrue(string.Compare(buildItemArray[0].Include, buildItem1.Include, StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(buildItemArray[1].Include, buildItem2.Include, StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(buildItemArray[1].Name, buildItem2.Name, StringComparison.OrdinalIgnoreCase) == 0); stream.Position = 0; // Serialize buildResultEntry.WriteToStream(writer); // Get position of stream after write so it can be compared to the position after read streamWriteEndPosition = stream.Position; // Deserialize and Verify stream.Position = 0; BuildResultCacheEntry newCacheEntryBuildResult = new BuildResultCacheEntry(); newCacheEntryBuildResult.CreateFromStream(reader); streamReadEndPosition = stream.Position; Assert.IsTrue(streamWriteEndPosition == streamReadEndPosition, "Stream End Positions Should Match"); Assert.IsTrue(string.Compare(newCacheEntryBuildResult.Name, buildResultEntry.Name, StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(buildResultEntry.BuildResult == newCacheEntryBuildResult.BuildResult); buildItemArray = newCacheEntryBuildResult.BuildItems; Assert.IsTrue(buildItemArray.Length == 2); Assert.IsTrue(string.Compare(buildItemArray[0].Include, buildItem1.Include, StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(buildItemArray[1].Include, buildItem2.Include, StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(buildItemArray[1].Name, buildItem2.Name, StringComparison.OrdinalIgnoreCase) == 0); stream.Position = 0; // Serialize propertyEntry.WriteToStream(writer); // Get position of stream after write so it can be compared to the position after read streamWriteEndPosition = stream.Position; // Deserialize and Verify stream.Position = 0; PropertyCacheEntry newPropertyCacheEntry = new PropertyCacheEntry(); newPropertyCacheEntry.CreateFromStream(reader); streamReadEndPosition = stream.Position; Assert.IsTrue(streamWriteEndPosition == streamReadEndPosition, "Stream End Positions Should Match"); Assert.IsTrue(string.Compare(newPropertyCacheEntry.Name, propertyEntry.Name, StringComparison.OrdinalIgnoreCase) == 0); Assert.IsTrue(string.Compare(newPropertyCacheEntry.Value, propertyEntry.Value, StringComparison.OrdinalIgnoreCase) == 0); } finally { // Close will close the writer/reader and the underlying stream writer.Close(); reader.Close(); reader = null; stream = null; writer = null; } }
/// <summary> /// This method adds cached results for each target results for which are contained inside /// the build result. This method is thread safe. /// </summary> internal void AddCacheEntryForBuildResults(BuildResult buildResult) { ErrorUtilities.VerifyThrow(buildResult != null, "Expect a non-null build result"); // Don't cache results if they are marked as uncacheable if (!buildResult.UseResultCache) { return; } cacheScopeReaderWriterLock.AcquireWriterLock(Timeout.Infinite); try { if (!ContainsCacheEntry(Constants.defaultTargetCacheName)) { // If the project file is malformed the build may fail without initializing the initialtargets or // the default targests fields. The retrieval code expects non-null values // so it is necessary to replace null with empty string ErrorUtilities.VerifyThrow(!buildResult.EvaluationResult || (buildResult.InitialTargets != null && buildResult.DefaultTargets != null), "Expect initial targets to be non-null for successful builds"); string defaultTargets = buildResult.DefaultTargets ?? String.Empty; PropertyCacheEntry defaultTargetsCacheEntry = new PropertyCacheEntry(Constants.defaultTargetCacheName, defaultTargets); AddCacheEntryInternal(defaultTargetsCacheEntry); string initialTargets = buildResult.InitialTargets ?? String.Empty; PropertyCacheEntry initialTargetsCacheEntry = new PropertyCacheEntry(Constants.initialTargetCacheName, initialTargets); AddCacheEntryInternal(initialTargetsCacheEntry); } if (!ContainsCacheEntry(Constants.projectIdCacheName)) { PropertyCacheEntry projectIdCacheEntry = new PropertyCacheEntry(Constants.projectIdCacheName, buildResult.ProjectId.ToString(CultureInfo.InvariantCulture)); AddCacheEntryInternal(projectIdCacheEntry); } IDictionary outputsByTargetName = buildResult.OutputsByTarget; //Create single entry for each target in the request foreach (DictionaryEntry entry in buildResult.ResultByTarget) { Target.BuildState buildState = (Target.BuildState)entry.Value; // Only cache successful and failed targets if ((buildState == Target.BuildState.CompletedSuccessfully) || (buildState == Target.BuildState.CompletedUnsuccessfully)) { BuildItem[] targetOutputs = null; // Only cache output items for successful targets if (buildState == Target.BuildState.CompletedSuccessfully) { ErrorUtilities.VerifyThrow(buildResult.OutputsByTarget.Contains(entry.Key), "We must have build results for successful targets"); BuildItem[] outputItems = (BuildItem[])buildResult.OutputsByTarget[entry.Key]; // It's essential that we clear out any pointers to the project from the BuildItem; // otherwise the cache will hold onto the project, and not save any memory. if (outputItems != null) { for (int i = 0; i < outputItems.Length; i++) { outputItems[i] = outputItems[i].VirtualClone(true /* remove references to minimise transitive size */); } } targetOutputs = (BuildItem[])buildResult.OutputsByTarget[entry.Key]; } BuildResultCacheEntry cacheEntry = new BuildResultCacheEntry((string)entry.Key, targetOutputs, buildState == Target.BuildState.CompletedSuccessfully); if (Engine.debugMode) { Console.WriteLine("+++Adding cache entry for " + (string)entry.Key + " in " + this.ScopeName + " result: " + (buildState == Target.BuildState.CompletedSuccessfully)); } AddCacheEntryInternal(cacheEntry); } } } finally { cacheScopeReaderWriterLock.ReleaseWriterLock(); } }
private static CacheEntry[] CreateCacheEntries() { CacheEntry[] entries = new CacheEntry[3]; BuildItem buildItem1 = new BuildItem("BuildItem1", "Item1"); BuildItem buildItem2 = new BuildItem("BuildItem2", "Item2"); buildItem1.Include = "TestInclude1"; buildItem2.Include = "TestInclude2"; BuildItem[] buildItems = new BuildItem[2]; buildItems[0] = buildItem1; buildItems[1] = buildItem2; entries[0] = new BuildItemCacheEntry("Badger", buildItems); entries[1] = new BuildResultCacheEntry("Koi", buildItems, true); entries[2] = new PropertyCacheEntry("Seagull", "bread"); return entries; }
/// <summary> /// This method adds cached results for each target results for which are contained inside /// the build result. This method is thread safe. /// </summary> internal void AddCacheEntryForBuildResults(BuildResult buildResult) { ErrorUtilities.VerifyThrow(buildResult != null, "Expect a non-null build result"); // Don't cache results if they are marked as uncacheable if (!buildResult.UseResultCache) { return; } cacheScopeReaderWriterLock.AcquireWriterLock(Timeout.Infinite); try { if (!ContainsCacheEntry(Constants.defaultTargetCacheName)) { // If the project file is malformed the build may fail without initializing the initialtargets or // the default targests fields. The retrieval code expects non-null values // so it is necessary to replace null with empty string ErrorUtilities.VerifyThrow(buildResult.EvaluationResult == false || buildResult.InitialTargets != null && buildResult.DefaultTargets != null , "Expect initial targets to be non-null for successful builds"); string defaultTargets = buildResult.DefaultTargets == null ? String.Empty : buildResult.DefaultTargets; PropertyCacheEntry defaultTargetsCacheEntry = new PropertyCacheEntry(Constants.defaultTargetCacheName, defaultTargets); AddCacheEntryInternal(defaultTargetsCacheEntry); string initialTargets = buildResult.InitialTargets == null ? String.Empty : buildResult.InitialTargets; PropertyCacheEntry initialTargetsCacheEntry = new PropertyCacheEntry(Constants.initialTargetCacheName, initialTargets ); AddCacheEntryInternal(initialTargetsCacheEntry); } if (!ContainsCacheEntry(Constants.projectIdCacheName)) { PropertyCacheEntry projectIdCacheEntry = new PropertyCacheEntry(Constants.projectIdCacheName, buildResult.ProjectId.ToString(CultureInfo.InvariantCulture)); AddCacheEntryInternal(projectIdCacheEntry); } IDictionary outputsByTargetName = buildResult.OutputsByTarget; //Create single entry for each target in the request foreach (DictionaryEntry entry in buildResult.ResultByTarget) { Target.BuildState buildState = (Target.BuildState)entry.Value; // Only cache successful and failed targets if ((buildState == Target.BuildState.CompletedSuccessfully) || (buildState == Target.BuildState.CompletedUnsuccessfully)) { BuildItem[] targetOutputs = null; // Only cache output items for successful targets if (buildState == Target.BuildState.CompletedSuccessfully) { ErrorUtilities.VerifyThrow(buildResult.OutputsByTarget.Contains(entry.Key), "We must have build results for successful targets"); BuildItem[] outputItems = (BuildItem[])buildResult.OutputsByTarget[entry.Key]; // It's essential that we clear out any pointers to the project from the BuildItem; // otherwise the cache will hold onto the project, and not save any memory. if (outputItems != null) { for (int i = 0; i < outputItems.Length; i++) { outputItems[i] = outputItems[i].VirtualClone(true /* remove references to minimise transitive size */); } } targetOutputs = (BuildItem[])buildResult.OutputsByTarget[entry.Key]; } BuildResultCacheEntry cacheEntry = new BuildResultCacheEntry((string)entry.Key, targetOutputs, (buildState == Target.BuildState.CompletedSuccessfully)); if (Engine.debugMode) { Console.WriteLine("+++Adding cache entry for " + (string)entry.Key + " in " + this.ScopeName + " result: " + (buildState == Target.BuildState.CompletedSuccessfully)); } AddCacheEntryInternal(cacheEntry); } } } finally { cacheScopeReaderWriterLock.ReleaseWriterLock(); } }