public void AssertCacheMissEventLogged(params string[] requiredMessages) { if (Configuration.Logging.CacheMissAnalysisOption.Mode == CacheMissAnalysisOption.LocalMode().Mode) { var messages = requiredMessages.Select((s) => ObservedInputConstants.ToExpandedString(s)); AssertLogContains(caseSensitive: false, requiredLogMessages: messages.ToArray()); } }
/// <summary> /// Describes diff with respect to other instance of <see cref="ObservedInputData"/>. /// </summary> /// <param name="data"></param> /// <returns></returns> public string DescribeDiffWithoutPath(ObservedInputData data) => string.Join( " | ", (new[] { Prefix(nameof(AccessType), ObservedInputConstants.ToExpandedString(AccessType)), Flags == data.Flags ? null : Prefix(nameof(Flags), Flags), Pattern == data.Pattern ? null : Prefix(nameof(Pattern), Pattern), Hash == data.Hash ? null : Prefix(nameof(Hash), Hash) }).Where(s => !string.IsNullOrEmpty(s)));
/// <summary> /// Checks <see cref="AnalyzerResult.FileOutput"/> for certain strings. /// Only the file output of the execution analyzer executable is checked. /// Use <see cref="AssertPipMiss(AnalyzerResult, Pip, PipCacheMissType, string[])"/> to additionally /// test runtime cache miss analysis output. /// </summary> /// <note> /// This is highly inefficient since it does a full pass over the /// output file for every assertion. /// </note> public static AnalyzerResult AssertAnalyzerOutput( this AnalyzerResult result, params string[] messages) { foreach (var message in messages) { XAssert.IsTrue(result.FileOutput.ToUpperInvariant().Contains(ObservedInputConstants.ToExpandedString(message).ToUpperInvariant()), "Expected message: \"{0}\" to appear in analyzer output: \"{1}\"", ObservedInputConstants.ToExpandedString(message), result.FileOutput); } return(result); }
/// <summary> /// Makes a tree that represents an observed input on a path into a subtree of /// a tree that represents the corresponding path in the pathset. /// /// <see cref="MergeStrongFingerprintAndPathSetTrees(JsonNode, JsonNode)"/> /// for numbering explanation. /// /// Converts /// [3] "E":"VSO0:E0C5007DC8CF2D331236F156F136C50CACE2A5D549CD132D9B44ABD1F13D50CC00" /// => /// [3'] "ObservedInput":"E:VSO0:E0C5007DC8CF2D331236F156F136C50CACE2A5D549CD132D9B44ABD1F13D50CC00" /// /// Reparent [3'] from /// [2] "ObservedInputs":"" /// to /// [5'] "B:/out/objects/n/x/qbkexxlc8je93wycw7yrlw0a305n7k/xunit-out/CacheMissAnaAD836B23/3/obj/readonly/src_0":"" /// /// Add /// [8] "Members":"[src_1, src_2]" /// to /// [5'] "B:/out/objects/n/x/qbkexxlc8je93wycw7yrlw0a305n7k/xunit-out/CacheMissAnaAD836B23/3/obj/readonly/src_0":"" /// </summary> /// <param name="observedInputNode"></param> /// <param name="pathSetNode"></param> private void ReparentObservedInput(JsonNode observedInputNode, JsonNode pathSetNode) { // Store values from // [3] "E":"VSO0:E0C5007DC8CF2D331236F156F136C50CACE2A5D549CD132D9B44ABD1F13D50CC00" // before manipulating the node var observedInputType = observedInputNode.Name; var observedInputHash = observedInputNode.Values[0]; var values = observedInputNode.Values; values.Clear(); string expandedType = ObservedInputConstants.ToExpandedString(observedInputType); switch (observedInputType) { case ObservedInputConstants.AbsentPathProbe: case ObservedInputConstants.ExistingFileProbe: case ObservedInputConstants.ExistingDirectoryProbe: values.Add(expandedType); break; case ObservedInputConstants.FileContentRead: values.Add($"{expandedType}:{observedInputHash}"); break; case ObservedInputConstants.DirectoryEnumeration: values.Add($"{expandedType}:{observedInputHash}"); // [8] "Members":"[src_1, src_2]" AddDirectoryMembershipBranch(observedInputHash, pathSetNode); break; } // [3'] "ObservedInput":"E:VSO0:E0C5007DC8CF2D331236F156F136C50CACE2A5D549CD132D9B44ABD1F13D50CC00" observedInputNode.Name = ObservedInputConstants.ObservedInputs; JsonTree.ReparentBranch(observedInputNode, pathSetNode); }