예제 #1
0
        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);
            }
        }
예제 #2
0
        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());
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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 });
                }
            }
        }
예제 #6
0
        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);
        }