Example #1
0
        public void Log(CreateLogItemRequest createLogItemRequest)
        {
            if (StartTask == null)
            {
                var exp = new InsufficientExecutionStackException("The launch wasn't scheduled for starting to add log messages.");
                TraceLogger.Error(exp.ToString());
                throw (exp);
            }

            if (StartTask.IsFaulted || StartTask.IsCanceled)
            {
                return;
            }

            if (FinishTask == null)
            {
                lock (_lockObj)
                {
                    if (_logsReporter == null)
                    {
                        var logRequestAmender = new LaunchLogRequestAmender(this);
                        _logsReporter = new LogsReporter(this, _service, _extensionManager, _requestExecuter, logRequestAmender);
                    }
                }

                _logsReporter.Log(createLogItemRequest);
            }
        }
Example #2
0
        private bool HandleAddLogCommunicationAction(ITestReporter testReporter, AddLogCommunicationMessage message)
        {
            var logRequest = new CreateLogItemRequest
            {
                Level = message.Level,
                Time  = message.Time,
                Text  = message.Text
            };

            if (message.Attach != null)
            {
                logRequest.Attach = new Client.Abstractions.Responses.Attach
                {
                    Name     = message.Attach.Name,
                    MimeType = message.Attach.MimeType,
                    Data     = message.Attach.Data
                };
            }

            if (message.ParentScopeId != null)
            {
                testReporter = _nestedSteps[message.ParentScopeId];
            }

            testReporter.Log(logRequest);

            return(true);
        }
        public async Task <LogItemCreatedResponse> CreateAsync(CreateLogItemRequest request)
        {
            var uri = $"{ProjectName}/log";

            if (request.Attach == null)
            {
                return(await PostAsJsonAsync <LogItemCreatedResponse, CreateLogItemRequest>(uri, request));
            }
            else
            {
                var body = ModelSerializer.Serialize <List <CreateLogItemRequest> >(new List <CreateLogItemRequest> {
                    request
                });
                var multipartContent = new MultipartFormDataContent();

                var jsonContent = new StringContent(body, Encoding.UTF8, "application/json");
                multipartContent.Add(jsonContent, "json_request_part");

                var byteArrayContent = new ByteArrayContent(request.Attach.Data, 0, request.Attach.Data.Length);
                byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(request.Attach.MimeType);
                multipartContent.Add(byteArrayContent, "file", request.Attach.Name);

                var response = await HttpClient.PostAsync(uri, multipartContent).ConfigureAwait(false);

                response.VerifySuccessStatusCode();
                var c = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                return(ModelSerializer.Deserialize <Responses>(c).LogItems[0]);
            }
        }
Example #4
0
        public void ShouldSendAsSeparateRequestPerLogWithAttachmentIncludingWithoutAttachment()
        {
            var service = new MockServiceBuilder().Build();

            var logsReporter = new LogsReporter(_testReporter.Object, service.Object, _extensionManager, _requestExecuter, _logRequestAmender.Object);

            var withoutAttachment = new CreateLogItemRequest
            {
                Text = "a",
                Time = DateTime.UtcNow
            };
            var withAttachment = new CreateLogItemRequest
            {
                Text   = "a",
                Time   = DateTime.UtcNow,
                Attach = new LogItemAttach()
            };

            logsReporter.Log(withAttachment);
            logsReporter.Log(withoutAttachment);
            logsReporter.Log(withAttachment);
            logsReporter.Log(withoutAttachment);

            logsReporter.Sync();

            service.Verify(s => s.LogItem.CreateAsync(It.IsAny <CreateLogItemRequest[]>()), Times.Exactly(2));
        }
Example #5
0
        /// <inheritdoc/>
        public bool FormatLog(CreateLogItemRequest logRequest)
        {
            if (logRequest.Text != null)
            {
                var regex = new Regex("{rp#file#(.*)}");
                var match = regex.Match(logRequest.Text);
                if (match.Success)
                {
                    logRequest.Text = logRequest.Text.Replace(match.Value, "");

                    var filePath = match.Groups[1].Value;

                    try
                    {
                        var mimeType = MimeTypes.MimeTypeMap.GetMimeType(Path.GetExtension(filePath));

                        logRequest.Attach = new LogItemAttach(mimeType, File.ReadAllBytes(filePath));

                        return(true);
                    }
                    catch (Exception exp)
                    {
                        logRequest.Text += $"{Environment.NewLine}{Environment.NewLine}Cannot fetch data by `{filePath}` path.{Environment.NewLine}{exp}";
                    }
                }
            }
            return(false);
        }
Example #6
0
        public void Amend(CreateLogItemRequest request)
        {
            if (request.Time < _testReporter.Info.StartTime)
            {
                request.Time = _testReporter.Info.StartTime;
            }

            request.TestItemUuid = _testReporter.Info.Uuid;
        }
        public static CreateLogItemRequest ConvertToRequest(this ILogMessage logMessage)
        {
            if (logMessage == null)
            {
                throw new ArgumentNullException("Cannot convert nullable log message object.", nameof(logMessage));
            }

            LogLevel logLevel;

            switch (logMessage.Level)
            {
            case LogMessageLevel.Debug:
                logLevel = LogLevel.Debug;
                break;

            case LogMessageLevel.Error:
                logLevel = LogLevel.Error;
                break;

            case LogMessageLevel.Fatal:
                logLevel = LogLevel.Fatal;
                break;

            case LogMessageLevel.Info:
                logLevel = LogLevel.Info;
                break;

            case LogMessageLevel.Trace:
                logLevel = LogLevel.Trace;
                break;

            case LogMessageLevel.Warning:
                logLevel = LogLevel.Warning;
                break;

            default:
                throw new Exception(string.Format("Unknown {0} level of log message.", logMessage.Level));
            }

            var logRequest = new CreateLogItemRequest
            {
                Text  = logMessage.Message,
                Time  = logMessage.Time,
                Level = logLevel
            };

            if (logMessage.Attachment != null)
            {
                logRequest.Attach = new LogItemAttach
                {
                    MimeType = logMessage.Attachment.MimeType,
                    Data     = logMessage.Attachment.Data
                };
            }

            return(logRequest);
        }
Example #8
0
        public void Amend(CreateLogItemRequest request)
        {
            if (request.Time < _launchReporter.Info.StartTime)
            {
                request.Time = _launchReporter.Info.StartTime;
            }

            request.LaunchUuid = _launchReporter.Info.Uuid;
        }
        public void ShouldNotFormatNullBase64String()
        {
            var formatter = new Base64LogFormatter();

            var logRequest = new CreateLogItemRequest();

            var isHandled = formatter.FormatLog(logRequest);

            isHandled.Should().BeFalse();
        }
Example #10
0
        public void ShouldNotFormatEmptyString()
        {
            var formatter = new FileLogFormatter();

            var logRequest = new CreateLogItemRequest()
            {
                Text = ""
            };

            var isHandled = formatter.FormatLog(logRequest);

            isHandled.Should().BeFalse();
        }
        public void ShouldThrowFormatIncorrectBase64String()
        {
            var formatter = new Base64LogFormatter();

            var incorrectBase64 = "123";

            var logRequest = new CreateLogItemRequest()
            {
                Text = $"{{rp#base64#image/png#{incorrectBase64}}}"
            };

            formatter.Invoking(f => f.FormatLog(logRequest)).Should().Throw <Exception>();
        }
Example #12
0
        public void ShouldThrowFormatIncorrectFilePathString()
        {
            var formatter = new FileLogFormatter();

            var incorrectFilePath = "q.w";

            var logRequest = new CreateLogItemRequest()
            {
                Text = $"{{rp#file#{incorrectFilePath}}}"
            };

            formatter.FormatLog(logRequest);

            logRequest.Text.Should().Contain("Cannot");
        }
Example #13
0
        public async Task <LogItemCreatedResponse> CreateAsync(CreateLogItemRequest request)
        {
            var uri = $"{ProjectName}/log";

            if (request.Attach == null)
            {
                return(await PostAsJsonAsync <LogItemCreatedResponse, CreateLogItemRequest>(uri, request));
            }
            else
            {
                var results = await CreateAsync(new CreateLogItemRequest[] { request });

                return(results.LogItems.First());
            }
        }
Example #14
0
        public void Test2()
        {
            var inputException = @"
System.AggregateException: One or more errors occurred. ---> System.Exception: Test
   at SomeMethod() in C:\some\file.cs:line 20
   at SomeMethod() in C:\some\file.cs:line 21
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
";
            var ext            = new SourceBackFormatter();
            var log            = new CreateLogItemRequest {
                Level = LogLevel.Error, Text = inputException
            };

            ext.FormatLog(log);
            StringAssert.Contains("AggregateException", log.Text);
        }
Example #15
0
        /// <summary>
        /// Sends log message to current test context.
        /// </summary>
        /// <param name="logRequest">Full model object for message</param>
        public static void Message(CreateLogItemRequest logRequest)
        {
            var message = new LogMessage(logRequest.Text);

            LogMessageLevel logLevel = LogMessageLevel.Info;

            switch (logRequest.Level)
            {
            case LogLevel.Debug:
                logLevel = LogMessageLevel.Debug;
                break;

            case LogLevel.Error:
                logLevel = LogMessageLevel.Error;
                break;

            case LogLevel.Fatal:
                logLevel = LogMessageLevel.Fatal;
                break;

            case LogLevel.Info:
                logLevel = LogMessageLevel.Info;
                break;

            case LogLevel.Trace:
                logLevel = LogMessageLevel.Trace;
                break;

            case LogLevel.Warning:
                logLevel = LogMessageLevel.Warning;
                break;
            }

            message.Level = logLevel;

            message.Time = logRequest.Time;

            if (logRequest.Attach != null)
            {
                message.Attachment = new LogMessageAttachment(logRequest.Attach.MimeType, logRequest.Attach.Data);
            }

            ActiveScope.Message(message);
        }
        public void ShouldFormatBase64String()
        {
            var formatter = new Base64LogFormatter();

            var data   = new byte[] { 1, 2, 3 };
            var base64 = Convert.ToBase64String(data);

            var logRequest = new CreateLogItemRequest()
            {
                Text = $"{{rp#base64#image/png#{base64}}}"
            };

            var isHandled = formatter.FormatLog(logRequest);

            isHandled.Should().BeTrue();
            logRequest.Attach.Should().NotBeNull();
            logRequest.Attach.MimeType.Should().Be("image/png");
            logRequest.Attach.Data.Should().BeEquivalentTo(data);
        }
        /// <inheritdoc/>
        public bool FormatLog(CreateLogItemRequest logRequest)
        {
            if (logRequest.Text != null)
            {
                var regex = new Regex("{rp#base64#(.*)#(.*)}");
                var match = regex.Match(logRequest.Text);
                if (match.Success)
                {
                    logRequest.Text = logRequest.Text.Replace(match.Value, "");

                    var mimeType = match.Groups[1].Value;
                    var bytes    = Convert.FromBase64String(match.Groups[2].Value);

                    logRequest.Attach = new LogItemAttach(mimeType, bytes);

                    return(true);
                }
            }
            return(false);
        }
Example #18
0
        public async Task GetLogItem()
        {
            var addLogItemRequest = new CreateLogItemRequest
            {
                TestItemUuid = _fixture.TestUuid,
                Text         = "Log1",
                Time         = DateTime.UtcNow,
                Level        = LogLevel.Info
            };

            var log = await Service.LogItem.CreateAsync(addLogItemRequest);

            Assert.NotNull(log.Uuid);

            var gotLogItem = await Service.LogItem.GetAsync(log.Uuid);

            Assert.Equal(addLogItemRequest.Text, gotLogItem.Text);
            Assert.Equal(addLogItemRequest.Level, gotLogItem.Level);
            Assert.Equal(addLogItemRequest.Time, gotLogItem.Time);
        }
Example #19
0
        public void ShouldFormatFileString()
        {
            var formatter = new FileLogFormatter();

            var data     = "123";
            var filePath = Path.GetTempPath() + Path.GetRandomFileName();

            File.WriteAllText(filePath, data);

            var logRequest = new CreateLogItemRequest()
            {
                Text = $"{{rp#file#{filePath}}}"
            };

            var isHandled = formatter.FormatLog(logRequest);

            isHandled.Should().BeTrue();
            logRequest.Attach.Should().NotBeNull();
            logRequest.Attach.Data.Should().BeEquivalentTo(Encoding.UTF8.GetBytes(data));
        }
Example #20
0
        private void HandleAddLogCommunicationAction(ITestReporter testReporter, AddLogCommunicationMessage logMessage)
        {
            var logRequest = new CreateLogItemRequest
            {
                Text  = logMessage.Text,
                Time  = logMessage.Time,
                Level = logMessage.Level
            };

            if (logMessage.Attach != null)
            {
                logRequest.Attach = new LogItemAttach(logMessage.Attach.MimeType, logMessage.Attach.Data);
            }

            if (logMessage.ParentScopeId != null)
            {
                testReporter = _nestedScopes[logMessage.ParentScopeId];
            }

            testReporter.Log(logRequest);
        }
Example #21
0
        public void Log(CreateLogItemRequest logRequest)
        {
            lock (_syncObj)
            {
                _buffer.Enqueue(logRequest);

                var dependentTask = ProcessingTask ?? _reporter.StartTask;

                ProcessingTask = dependentTask.ContinueWith(async(dt) =>
                {
                    try
                    {
                        // only if parent reporter is succesfull
                        if (!_reporter.StartTask.IsFaulted && !_reporter.StartTask.IsCanceled)
                        {
                            var requests = GetBufferedLogRequests(batchCapacity: BatchCapacity);

                            if (requests.Count != 0)
                            {
                                foreach (var logItemRequest in requests)
                                {
                                    _logRequestAmender.Amend(logItemRequest);

                                    foreach (var formatter in _extensionManager.LogFormatters)
                                    {
                                        formatter.FormatLog(logItemRequest);
                                    }
                                }

                                await _requestExecuter.ExecuteAsync(() => _service.LogItem.CreateAsync(requests.ToArray()), null).ConfigureAwait(false);
                            }
                        }
                    }
                    catch (Exception exp)
                    {
                        _traceLogger.Error($"Unexpected error occurred while processing buffered log requests. {exp}");
                    }
                }, TaskContinuationOptions.PreferFairness).Unwrap();
            }
        }
Example #22
0
        public void Test1()
        {
            try
            {
                var tasks = new List <Task>();

                for (int i = 0; i < 10; i++)
                {
                    var t = Task.Run(() => { throw new Exception("Test"); });
                    tasks.Add(t);
                }

                Task.WaitAll(tasks.ToArray());
            }
            catch (Exception exp)
            {
                var ext = new SourceBackFormatter();
                var log = new CreateLogItemRequest {
                    Level = LogLevel.Error, Text = exp.ToString()
                };
                ext.FormatLog(log);
                StringAssert.Contains("throw new Exception", log.Text);
            }
        }
        public bool Handle(ILogScope logScope, CreateLogItemRequest logRequest)
        {
            var communicationMessage = new AddLogCommunicationMessage()
            {
                ParentScopeId = logScope?.Id,
                Time          = logRequest.Time,
                Text          = logRequest.Text,
                Level         = logRequest.Level
            };

            if (logRequest.Attach != null)
            {
                communicationMessage.Attach = new Attach
                {
                    Name     = logRequest.Attach.Name,
                    MimeType = logRequest.Attach.MimeType,
                    Data     = logRequest.Attach.Data
                };
            }

            Console.WriteLine(ModelSerializer.Serialize <AddLogCommunicationMessage>(communicationMessage));

            return(true);
        }
Example #24
0
 public async Task <LogItemCreatedResponse> CreateAsync(CreateLogItemRequest model)
 {
     return(await Task.FromResult(new LogItemCreatedResponse()));
 }
Example #25
0
        private void Events_TestResult(object sender, TestResultEventArgs e)
        {
            try
            {
                var innerResultsCountProperty = e.Result.Properties.FirstOrDefault(p => p.Id == "InnerResultsCount");
                if (innerResultsCountProperty == null || (innerResultsCountProperty != null && (int)e.Result.GetPropertyValue(innerResultsCountProperty) == 0))
                {
                    string className;
                    string testName;
                    var    fullName = e.Result.TestCase.FullyQualifiedName;
                    if (e.Result.TestCase.ExecutorUri.Host == "xunit")
                    {
                        var testMethodName = fullName.Split('.').Last();
                        var testClassName  = fullName.Substring(0, fullName.LastIndexOf('.'));
                        var displayName    = e.Result.TestCase.DisplayName;

                        testName = displayName == fullName
                            ? testMethodName
                            : displayName.Replace($"{testClassName}.", string.Empty);

                        className = testClassName;
                    }
                    else if (e.Result.TestCase.ExecutorUri.ToString().ToLower().Contains("mstest"))
                    {
                        testName = e.Result.DisplayName ?? e.Result.TestCase.DisplayName;

                        var classNameProperty = e.Result.TestCase.Properties.FirstOrDefault(p => p.Id == "MSTestDiscoverer.TestClassName");
                        if (classNameProperty != null)
                        {
                            className = e.Result.TestCase.GetPropertyValue(classNameProperty).ToString();
                        }
                        // else get classname from FQN (mstestadapter/v1)
                        else
                        {
                            // and temporary consider testname from TestCase object instead of from Result object
                            // Result.DisplayName: Test1 (Data Row 0)
                            // TestCase.DisplayName Test1
                            // the first name is better in report, but consider the second name to identify 'className'
                            testName  = e.Result.TestCase.DisplayName ?? e.Result.DisplayName;
                            className = fullName.Substring(0, fullName.Length - testName.Length - 1);
                            testName  = e.Result.DisplayName ?? e.Result.TestCase.DisplayName;
                        }
                    }
                    else
                    {
                        testName = e.Result.TestCase.DisplayName ?? fullName.Split('.').Last();

                        className = fullName.Substring(0, fullName.Length - testName.Length - 1);
                    }

                    TraceLogger.Info($"ClassName: {className}, TestName: {testName}");

                    var rootNamespaces = _config.GetValues <string>("rootNamespaces", null);
                    if (rootNamespaces != null)
                    {
                        var rootNamespace = rootNamespaces.FirstOrDefault(rns => className.StartsWith(rns));
                        if (rootNamespace != null)
                        {
                            className = className.Substring(rootNamespace.Length + 1);
                            TraceLogger.Verbose($"Cutting '{rootNamespace}'... New ClassName is '{className}'.");
                        }
                    }

                    var suiteReporter = GetOrStartSuiteNode(className, e.Result.StartTime.UtcDateTime);

                    // find description
                    var testDescription = e.Result.TestCase.Traits.FirstOrDefault(x => x.Name == "Description")?.Value;

                    if (e.Result.TestCase.ExecutorUri.ToString().ToLower().Contains("mstest"))
                    {
                        var testProperty = e.Result.TestCase.Properties.FirstOrDefault(p => p.Id == "Description");
                        if (testProperty != null)
                        {
                            testDescription = e.Result.TestCase.GetPropertyValue(testProperty).ToString();
                        }
                    }

                    // find categories
                    var testCategories = e.Result.TestCase.Traits.Where(t => t.Name.ToLower() == "Category".ToLower()).Select(x => x.Value).ToList();

                    if (e.Result.TestCase.ExecutorUri.ToString().ToLower().Contains("mstest"))
                    {
                        var testProperty = e.Result.TestCase.Properties.FirstOrDefault(p => p.Id == "MSTestDiscoverer.TestCategory");
                        if (testProperty != null)
                        {
                            testCategories.AddRange((string[])e.Result.TestCase.GetPropertyValue(testProperty));
                        }
                    }
                    else if (e.Result.TestCase.ExecutorUri.ToString().ToLower().Contains("nunit"))
                    {
                        var testProperty = e.Result.TestCase.Properties.FirstOrDefault(p => p.Id == "NUnit.TestCategory");
                        if (testProperty != null)
                        {
                            testCategories.AddRange((string[])e.Result.TestCase.GetPropertyValue(testProperty));
                        }
                    }

                    // start test node
                    var startTestRequest = new StartTestItemRequest
                    {
                        Name        = testName,
                        Description = testDescription,
                        Attributes  = testCategories.Select(tc => new ItemAttribute {
                            Value = tc
                        }).ToList(),
                        StartTime = e.Result.StartTime.UtcDateTime,
                        Type      = TestItemType.Step
                    };

                    var testReporter = suiteReporter.StartChildTestReporter(startTestRequest);

                    // add log messages
                    if (e.Result.Messages != null)
                    {
                        foreach (var message in e.Result.Messages)
                        {
                            if (message.Text == null)
                            {
                                continue;
                            }
                            foreach (var line in message.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
                            {
                                var handled = false;

                                var textMessage = line;

                                try
                                {
                                    // SpecRun adapter adds this for output messages, just trim it for internal text messages
                                    if (line.StartsWith("-> "))
                                    {
                                        textMessage = line.Substring(3);
                                    }

                                    var baseCommunicationMessage = Client.Converters.ModelSerializer.Deserialize <BaseCommunicationMessage>(textMessage);

                                    switch (baseCommunicationMessage.Action)
                                    {
                                    case CommunicationAction.AddLog:
                                        var addLogCommunicationMessage = Client.Converters.ModelSerializer.Deserialize <AddLogCommunicationMessage>(textMessage);
                                        handled = HandleAddLogCommunicationAction(testReporter, addLogCommunicationMessage);
                                        break;

                                    case CommunicationAction.BeginLogScope:
                                        var beginLogScopeCommunicationMessage = Client.Converters.ModelSerializer.Deserialize <BeginScopeCommunicationMessage>(textMessage);
                                        handled = HandleBeginLogScopeCommunicationAction(testReporter, beginLogScopeCommunicationMessage);
                                        break;

                                    case CommunicationAction.EndLogScope:
                                        var endLogScopeCommunicationMessage = Client.Converters.ModelSerializer.Deserialize <EndScopeCommunicationMessage>(textMessage);
                                        handled = HandleEndLogScopeCommunicationMessage(endLogScopeCommunicationMessage);
                                        break;
                                    }
                                }
                                catch (Exception)
                                {
                                }

                                if (!handled)
                                {
                                    // consider line output as usual user's log message

                                    testReporter.Log(new CreateLogItemRequest
                                    {
                                        Time  = DateTime.UtcNow,
                                        Level = LogLevel.Info,
                                        Text  = line
                                    });
                                }
                            }
                        }
                    }

                    if (e.Result.ErrorMessage != null)
                    {
                        testReporter.Log(new CreateLogItemRequest
                        {
                            Time  = e.Result.EndTime.UtcDateTime,
                            Level = LogLevel.Error,
                            Text  = e.Result.ErrorMessage + "\n" + e.Result.ErrorStackTrace
                        });
                    }

                    // add attachments
                    if (e.Result.Attachments != null)
                    {
                        foreach (var attachmentSet in e.Result.Attachments)
                        {
                            foreach (var attachmentData in attachmentSet.Attachments)
                            {
                                var filePath = attachmentData.Uri.LocalPath;

                                try
                                {
                                    var attachmentLogRequest = new CreateLogItemRequest
                                    {
                                        Level = LogLevel.Info,
                                        Text  = Path.GetFileName(filePath),
                                        Time  = e.Result.EndTime.UtcDateTime
                                    };

                                    var fileExtension = Path.GetExtension(filePath);

                                    byte[] bytes;

                                    using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read))
                                    {
                                        using (var memoryStream = new MemoryStream())
                                        {
                                            fileStream.CopyTo(memoryStream);
                                            bytes = memoryStream.ToArray();
                                        }
                                    }

                                    attachmentLogRequest.Attach = new Client.Abstractions.Responses.Attach(Path.GetFileName(filePath), Shared.MimeTypes.MimeTypeMap.GetMimeType(fileExtension), bytes);

                                    testReporter.Log(attachmentLogRequest);
                                }
                                catch (Exception exp)
                                {
                                    var error = $"Cannot read a content of '{filePath}' file: {exp.Message}";

                                    testReporter.Log(new CreateLogItemRequest
                                    {
                                        Level = LogLevel.Warning,
                                        Time  = e.Result.EndTime.UtcDateTime,
                                        Text  = error
                                    });

                                    TraceLogger.Error(error);
                                }
                            }
                        }
                    }

                    // finish test

                    var finishTestRequest = new FinishTestItemRequest
                    {
                        EndTime = e.Result.EndTime.UtcDateTime,
                        Status  = _statusMap[e.Result.Outcome]
                    };

                    testReporter.Finish(finishTestRequest);
                }
            }
            catch (Exception exp)
            {
                var error = $"Unexpected exception in {nameof(Events_TestResult)}: {exp}";
                TraceLogger.Error(error);
                Console.WriteLine(error);
            }
        }
Example #26
0
        public void FormatLog(CreateLogItemRequest logRequest)
        {
            _traceLogger.Verbose("Received a log request to format.");

            var handled = false;

            var fullMessageBuilder = Config.GetValue("Extensions:SourceBack:WithMarkdownPrefix", false) ? new StringBuilder("!!!MARKDOWN_MODE!!!") : new StringBuilder();

            if (logRequest.Level == LogLevel.Error || logRequest.Level == LogLevel.Fatal)
            {
                _traceLogger.Info($"Parsing exception stacktrace in log message with {logRequest.Level} level...");

                foreach (var line in logRequest.Text.Split(new string[] { Environment.NewLine, "\n" }, StringSplitOptions.None))
                {
                    _traceLogger.Verbose("Parsing line as stacktrace frame:" + Environment.NewLine + line);

                    var lineWithoutMarkdown = line.Replace("`", @"\`").Replace("__", @"\__");

                    var match = Regex.Match(line, @"\s+\w+\s.*\s\w+\s(.*):\w+\s(\d+)");

                    if (match.Success)
                    {
                        var sourcePath = match.Groups[1].Value;
                        var lineIndex  = int.Parse(match.Groups[2].Value) - 1;

                        _traceLogger.Info($"It matches stacktrace. SourcePath: {sourcePath} - LineIndex: {lineIndex}");

                        var sectionBuilder = new StringBuilder();

                        try
                        {
                            lock (_pdbsLock)
                            {
                                if (_pdbs == null)
                                {
                                    _pdbs = new List <PdbFileInfo>();

                                    var currentDirectory = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).FullName;

                                    _traceLogger.Verbose($"Exploring {currentDirectory} directory for PDB files");

                                    var pdbFilePaths = DirectoryScanner.FindPdbPaths(currentDirectory);

                                    foreach (var pdbFilePath in pdbFilePaths)
                                    {
                                        var pdbFileInfo = new PdbFileInfo(pdbFilePath);

                                        try
                                        {
                                            pdbFileInfo.LoadSourceLinks();
                                        }
                                        catch (NotSupportedException exp)
                                        {
                                            _traceLogger.Warn($"{pdbFilePath} format is not supported. Try to change it to 'portable' or 'embedded'. {Environment.NewLine}{exp}");
                                        }

                                        _pdbs.Add(pdbFileInfo);
                                    }
                                }
                            }

                            var pdb = _pdbs.FirstOrDefault(p => p.SourceLinks.ContainsKey(sourcePath));

                            // if defined
                            if (pdb != null)
                            {
                                var content = pdb.GetSourceLinkContent(sourcePath);

                                // if available
                                if (content != null)
                                {
                                    var contentLines = content.Replace("\r\n", "\n").Split(new string[] { "\n" }, StringSplitOptions.None);

                                    // up
                                    var offsetUp             = Config.GetValue("Extensions:SourceBack:OffsetUp", 4);
                                    var takeFromIndex        = lineIndex - offsetUp;
                                    var missingTopLinesCount = 0;
                                    if (takeFromIndex < 0)
                                    {
                                        missingTopLinesCount = Math.Abs(takeFromIndex);
                                        takeFromIndex        = 0;
                                    }

                                    // down
                                    var offsetDown  = Config.GetValue("Extensions:SourceBack:OffsetDown", 2);
                                    var takeToIndex = lineIndex + offsetDown;
                                    if (takeToIndex > contentLines.Length - 1)
                                    {
                                        takeToIndex = contentLines.Length - 1;
                                    }

                                    // and add whitespace to replace it with ►
                                    var frameContentLines = contentLines.Skip(takeFromIndex + 1).Take(takeToIndex - takeFromIndex).Select(l => " " + l).ToList();

                                    var hightlightFrameLineIndex = offsetUp - missingTopLinesCount - 1;
                                    frameContentLines[hightlightFrameLineIndex] = "►" + frameContentLines[hightlightFrameLineIndex].Remove(0, 1);
                                    var frameContent = string.Join(Environment.NewLine, frameContentLines);

                                    sectionBuilder.AppendLine($"```{Environment.NewLine}{frameContent}{Environment.NewLine}```");
                                }
                            }
                        }
                        catch (Exception exp)
                        {
                            sectionBuilder.AppendLine($"```{Environment.NewLine}SourceBack error: {exp}{Environment.NewLine}```");
                        }

                        handled = true;

                        if (!string.IsNullOrEmpty(sectionBuilder.ToString()))
                        {
                            var sourceFileName   = Path.GetFileName(sourcePath);
                            var lineWithEditLink = lineWithoutMarkdown.Replace("\\" + sourceFileName, $"\\\\**{sourceFileName}**");
                            lineWithEditLink = lineWithEditLink.Remove(lineWithEditLink.Length - match.Groups[2].Value.Length);

                            var openWith = Config.GetValue("Extensions:SourceBack:OpenWith", "vscode");
                            switch (openWith.ToLowerInvariant())
                            {
                            case "vscode":
                                lineWithEditLink += $"[{match.Groups[2].Value}](vscode://file/{sourcePath.Replace("\\", "/")}:{lineIndex + 1})";
                                break;
                            }

                            fullMessageBuilder.AppendLine($"{lineWithEditLink}{Environment.NewLine}{sectionBuilder}");
                        }
                        else
                        {
                            fullMessageBuilder.AppendLine(lineWithoutMarkdown);
                        }
                    }
                    else
                    {
                        fullMessageBuilder.AppendLine(lineWithoutMarkdown);
                    }
                }
            }

            if (handled)
            {
                logRequest.Text = fullMessageBuilder.ToString();
            }
        }