private void Roundtrip <T>(T args, params Func <T, string>[] fieldsToCompare) where T : BuildEventArgs { var memoryStream = new MemoryStream(); var binaryWriter = new BinaryWriter(memoryStream); var buildEventArgsWriter = new BuildEventArgsWriter(binaryWriter); buildEventArgsWriter.Write(args); long length = memoryStream.Length; memoryStream.Position = 0; var binaryReader = new BinaryReader(memoryStream); var buildEventArgsReader = new BuildEventArgsReader(binaryReader, BinaryLogger.FileFormatVersion); var deserializedArgs = (T)buildEventArgsReader.Read(); Assert.Equal(length, memoryStream.Position); Assert.NotNull(deserializedArgs); Assert.Equal(args.GetType(), deserializedArgs.GetType()); foreach (var field in fieldsToCompare) { var expected = field(args); var actual = field(deserializedArgs); Assert.Equal(expected, actual); } }
public void ReadingCorruptedStreamThrows() { var memoryStream = new MemoryStream(); var binaryWriter = new BinaryWriter(memoryStream); var buildEventArgsWriter = new BuildEventArgsWriter(binaryWriter); var args = new BuildStartedEventArgs( "Message", "HelpKeyword", DateTime.Parse("3/1/2017 11:11:56 AM")); buildEventArgsWriter.Write(args); long length = memoryStream.Length; for (long i = length - 1; i >= 0; i--) // try all possible places where a stream might end abruptly { memoryStream.SetLength(i); // pretend that the stream abruptly ends memoryStream.Position = 0; var binaryReader = new BinaryReader(memoryStream); var buildEventArgsReader = new BuildEventArgsReader(binaryReader, BinaryLogger.FileFormatVersion); Assert.Throws <EndOfStreamException>(() => buildEventArgsReader.Read()); } }
double GetDurationFromBinLog(ProjectBuilder builder) { var duration = TimeSpan.Zero; var binlog = Path.Combine(Root, builder.ProjectDirectory, "msbuild.binlog"); FileAssert.Exists(binlog); using (var fileStream = File.OpenRead(binlog)) using (var gzip = new GZipStream(fileStream, CompressionMode.Decompress)) using (var binaryReader = new BinaryReader(gzip)) { int fileFormatVersion = binaryReader.ReadInt32(); var buildReader = new BuildEventArgsReader(binaryReader, fileFormatVersion); BuildEventArgs args; var started = new Stack <DateTime> (); while ((args = buildReader.Read()) != null) { if (args is ProjectStartedEventArgs projectStarted) { started.Push(projectStarted.Timestamp); } else if (args is ProjectFinishedEventArgs projectFinished) { duration += projectFinished.Timestamp - started.Pop(); } } } if (duration == TimeSpan.Zero) { throw new InvalidDataException($"No project build duration found in {binlog}"); } return(duration.TotalMilliseconds); }
public IEnumerable <BuildEventArgs> ReadEvents() { if (_buildEvents != null) { return(_buildEvents); } var buildEventArgsReader = new BuildEventArgsReader(_binaryReader, _fileFormatVersion); var buildEvents = new List <BuildEventArgs>(); while (true) { var buildEventArgs = buildEventArgsReader.Read(); if (buildEventArgs == null) { break; } buildEvents.Add(buildEventArgs); } _buildEvents = buildEvents; return(_buildEvents); }
private void ReaderThread(object obj) { if (!(obj is Tuple <NamedPipeServerStream, SolutionItem> tuple)) { return; } NamedPipeServerStream npServerStream = tuple.Item1; SolutionItem solutionItem = tuple.Item2; GZipStream gzipStream = new GZipStream(npServerStream, CompressionMode.Decompress); BinaryReader binaryReader = new BinaryReader(gzipStream); int fileFormatVersion = binaryReader.ReadInt32(); if (fileFormatVersion > FileFormatVersion) { throw new NotSupportedException($"Unsupported log file format {fileFormatVersion}/{FileFormatVersion}"); } BuildEventArgsReader reader = new BuildEventArgsReader(binaryReader, fileFormatVersion); while (true) { BuildEventArgs instance = reader.Read(); if (instance == null) { break; } Type instanceType = instance.GetType(); string instanceTypeName = instanceType.Name; if (!instanceTypeName.EndsWith("EventArgs")) { Trace.WriteLine($"Invalid build event: {instance}"); continue; } string handlerName = $"On{instanceTypeName.Substring(0, instanceTypeName.Length - 9)}"; if (!EventHandlers.TryGetValue(handlerName, out MethodInfo handler)) { handler = EventHandlers[handlerName] = GetType().GetMethod( handlerName, BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(SolutionItem), instanceType }, null); if (handler == null) { Trace.WriteLine($"#Missing handler: public void {handlerName}(SolutionItem solutionItem, {instanceTypeName} e)"); } } if (handler != null) { handler.Invoke(this, new object[] { solutionItem, instance }); } } }
double GetDurationFromBinLog(ProjectBuilder builder) { //TODO: BuildEventArgsReader.Read() returns null in .NET 6 Preview 2 // See: https://github.com/dotnet/msbuild/issues/6225 if (Builder.UseDotNet) { Assert.Ignore("Cannot currently parse .binlog files in .NET 6 Preview 2"); } var duration = TimeSpan.Zero; var binlog = Path.Combine(Root, builder.ProjectDirectory, "msbuild.binlog"); FileAssert.Exists(binlog); using (var fileStream = File.OpenRead(binlog)) using (var gzip = new GZipStream(fileStream, CompressionMode.Decompress)) using (var binaryReader = new BinaryReader(gzip)) { int fileFormatVersion = binaryReader.ReadInt32(); var buildReader = new BuildEventArgsReader(binaryReader, fileFormatVersion); BuildEventArgs args; var started = new Stack <DateTime> (); while ((args = buildReader.Read()) != null) { if (args is ProjectStartedEventArgs projectStarted) { started.Push(projectStarted.Timestamp); } else if (args is ProjectFinishedEventArgs projectFinished) { duration += projectFinished.Timestamp - started.Pop(); } } } if (duration == TimeSpan.Zero) { throw new InvalidDataException($"No project build duration found in {binlog}"); } return(duration.TotalMilliseconds); }