private XmlAnnotationFile ParseAnnotationFile( [NotNull] Type benchmarkType, [NotNull] string resourceFileName, [NotNull] IMessageLogger messageLogger) { var resourceKey = GetResourceKey(benchmarkType); var resourceChecksum = AnnotationHelpers.TryGetChecksum(resourceKey, ChecksumAlgorithm.Sha1); var fileChecksum = AnnotationHelpers.TryGetChecksum(resourceFileName, ChecksumAlgorithm.Sha1); if (!resourceChecksum.EqualsTo(fileChecksum)) { var expected = resourceChecksum.ToHexString(); var actual = fileChecksum.ToHexString(); messageLogger.WriteSetupErrorMessage( $"{ChecksumAlgorithm.Sha1} checksum validation failed. File '{resourceFileName}'." + $"{Environment.NewLine}\tActual: 0x{actual}" + $"{Environment.NewLine}\tExpected: 0x{expected}"); return(new XmlAnnotationFile(resourceFileName, null)); } var xmlAnnotationDoc = XmlAnnotationHelpers.TryParseXmlAnnotationDoc(resourceFileName, messageLogger); return(new XmlAnnotationFile(resourceFileName, xmlAnnotationDoc)); }
private static XDocument TryParseXmlAnnotationDoc( string resourcePath, IMessageLogger messageLogger) { try { using (var stream = File.OpenRead(resourcePath)) { return(XmlAnnotationHelpers.TryParseXmlAnnotationDoc( stream, $"XML annotation '{resourcePath}'", messageLogger)); } } catch (IOException ex) { messageLogger.WriteExceptionMessage( MessageSeverity.SetupError, $"Could not access file '{resourcePath}'.", ex); return(null); } catch (UnauthorizedAccessException ex) { messageLogger.WriteExceptionMessage( MessageSeverity.SetupError, $"Could not access file '{resourcePath}'.", ex); return(null); } }
/// <summary>Saves the document.</summary> protected override void SaveCore() { using (var fileStream = File.Create(Origin)) { // ReSharper disable once AssignNullToNotNullAttribute XmlAnnotationHelpers.Save(XmlAnnotationDoc, fileStream); } }
public static XDocument[] ReadXmlAnnotationDocsFromLog(string logUri, IMessageLogger messageLogger) { messageLogger.Logger.WriteVerbose($"Reading XML annotation documents from log '{logUri}'."); var xmlAnnotationDocs = XmlAnnotationHelpers.TryParseXmlAnnotationDocsFromLog(logUri, messageLogger); return(xmlAnnotationDocs ?? Array <XDocument> .Empty); }
/// <summary>Retrieves stored info for competition targets from XML annotation docs.</summary> /// <param name="competitionTargets">Competition targets the metrics are retrieved for.</param> /// <param name="xmlAnnotationDocs">The XML annotation docs.</param> /// <param name="analysis">State of the analysis.</param> /// <returns>Stored info for competition targets.</returns> public static bool TryFillCompetitionTargetsFromLog( IReadOnlyCollection <CompetitionTarget> competitionTargets, XDocument[] xmlAnnotationDocs, Analysis analysis) { analysis.Logger.WriteVerbose($"Parsing XML annotations ({xmlAnnotationDocs.Length} doc(s)) from log."); var updated = false; var targetsToFill = competitionTargets.Select(t => t.Target).ToArray(); var metrics = analysis.Config.GetMetrics().ToArray(); // TODO: common api to write message for multiple target + metrics. foreach (var doc in xmlAnnotationDocs) { var storedTargets = XmlAnnotationHelpers.TryGetStoredTargets( targetsToFill, metrics, doc, true, analysis); foreach (var competitionTarget in competitionTargets) { var storedTarget = storedTargets.GetValueOrDefault(competitionTarget.Target); if (storedTarget == null) { continue; } var parsedCompetitionTarget = ParseCompetitionTarget( competitionTarget.Target, metrics, storedTarget, analysis); var parsedMetrics = parsedCompetitionTarget.MetricValues.ToDictionary(m => m.Metric); var hasAnnotations = false; foreach (var metricValue in competitionTarget.MetricValues) { if (!parsedMetrics.TryGetValue(metricValue.Metric, out var parsedMetricValue)) { continue; } hasAnnotations = true; updated |= metricValue.UnionWith(parsedMetricValue, true); } if (!hasAnnotations && analysis.SafeToContinue && parsedMetrics.Any()) { analysis.WriteWarningMessage( $"No logged XML annotation for {competitionTarget.Target.MethodDisplayInfo} found. Check if the method was renamed."); } } } return(updated); }
/// <summary>Retrieves stored info for competition targets.</summary> /// <param name="targets">Competition targets the metrics are retrieved for.</param> /// <param name="analysis">State of the analysis.</param> /// <returns>Stored info for competition targets.</returns> protected override IReadOnlyDictionary <Target, StoredTargetInfo> GetStoredTargets( Target[] targets, Analysis analysis) { var resourceKey = GetResourceKey(analysis.RunState.BenchmarkType); var xmlAnnotationDoc = XmlAnnotationHelpers.TryParseXmlAnnotationDoc(resourceKey, analysis); if (xmlAnnotationDoc == null) { return(new Dictionary <Target, StoredTargetInfo>()); } var metrics = analysis.Config.GetMetrics(); var result = XmlAnnotationHelpers.TryGetStoredTargets( targets, metrics, xmlAnnotationDoc, UseFullTypeName, analysis); return(result); }
/// <summary>Writes xml annotation document for the competition targets to the log.</summary> /// <param name="competitionTargets">The competition targets to log.</param> /// <param name="messageLogger">The message logger.</param> public static void LogXmlAnnotationDoc( [NotNull] IReadOnlyCollection <CompetitionTarget> competitionTargets, [NotNull] IMessageLogger messageLogger) => XmlAnnotationHelpers.LogXmlAnnotationDoc(competitionTargets, messageLogger);
/// <summary>Saves stored metrics from competition targets.</summary> /// <param name="competitionTargets">Competition targets with metrics to save.</param> /// <param name="annotationContext">The annotation context.</param> /// <param name="analysis">State of the analysis.</param> /// <returns> /// <c>true</c>, if metrics were saved successfully. /// </returns> protected override CompetitionTarget[] TrySaveAnnotationsCore( IReadOnlyCollection <CompetitionTarget> competitionTargets, AnnotationContext annotationContext, Analysis analysis) { var benchmarkType = analysis.RunState.BenchmarkType; var targetKey = new AnnotationTargetKey(benchmarkType.TypeHandle); var annotationFile = annotationContext.TryGetDocument(targetKey); if (annotationFile == null) { var origin = TryGetAnnotationLocation(analysis.Summary, analysis); if (origin == null) { annotationFile = annotationContext.GetUnknownOriginDocument(); } else { annotationFile = annotationContext.TryGetDocument(origin); if (annotationFile == null) { annotationFile = ParseAnnotationFile(benchmarkType, origin, analysis); annotationContext.AddDocument(annotationFile); } } annotationContext.AddTargetKey(annotationFile, targetKey); } if (!annotationFile.Parsed) { analysis.WriteSetupErrorMessage( $"Could not find XML annotation file {annotationFile.Origin} for the benchmark. Annotations were not saved."); return(Array <CompetitionTarget> .Empty); } var result = new List <CompetitionTarget>(); var xmlAnnotationFile = (XmlAnnotationFile)annotationFile; foreach (var targetToAnnotate in competitionTargets) { var target = targetToAnnotate.Target; var metrics = targetToAnnotate.MetricValues.Where(m => m.HasUnsavedChanges).ToArray(); if (metrics.Length == 0) { continue; } result.Add(targetToAnnotate); foreach (var metricValue in metrics) { analysis.Logger.WriteVerbose( $"Method {target.MethodDisplayInfo}: updating metric {metricValue.Metric} {metricValue}."); } } analysis.Logger.WriteVerboseHint( $"Annotating resource file '{annotationFile.Origin}'."); XmlAnnotationHelpers.AddOrUpdateXmlAnnotation( // ReSharper disable once AssignNullToNotNullAttribute xmlAnnotationFile.XmlAnnotationDoc, result, analysis.RunState.BenchmarkType, UseFullTypeName); foreach (var targetToAnnotate in competitionTargets) { var target = targetToAnnotate.Target; var metrics = targetToAnnotate.MetricValues.Where(m => m.HasUnsavedChanges).ToArray(); foreach (var metricValue in metrics) { analysis.Logger.WriteVerboseHint( $"Method {target.MethodDisplayInfo}: metric {metricValue.Metric} {metricValue} updated."); } } return(result.ToArray()); }