private static string?TryGetSourceFilePath(TestResult testResult, StackFrame?stackFrame)
        {
            // See if test runner provided it (never actually happens)
            if (!string.IsNullOrWhiteSpace(testResult.TestCase.CodeFilePath))
            {
                return(testResult.TestCase.CodeFilePath);
            }

            // Try to extract it from stack trace (works only if there was an exception)
            if (!string.IsNullOrWhiteSpace(stackFrame?.FilePath))
            {
                return(stackFrame.FilePath);
            }

            // Get the project file path instead (not ideal, but the best we can do)
            if (!string.IsNullOrWhiteSpace(testResult.TestCase.Source))
            {
                var projectFilePath = TryGetProjectFilePath(testResult.TestCase.Source);
                if (!string.IsNullOrWhiteSpace(projectFilePath))
                {
                    return(projectFilePath);
                }
            }

            return(null);
        }
Example #2
0
 public StackFrameInfo(int lineNumber, string?filePath, StackFrame?stackFrame, MethodDisplayInfo?methodDisplayInfo)
 {
     LineNumber        = lineNumber;
     FilePath          = filePath;
     StackFrame        = stackFrame;
     MethodDisplayInfo = methodDisplayInfo;
 }
Example #3
0
        internal static bool TryParseChrome(string line, out StackFrame?frame)
        {
            frame = null;

            var match = ChromeRe.Match(line);

            if (!match.Success)
            {
                return(false);
            }

            var isNative = match.Groups[2].Value?.IndexOf("native", StringComparison.Ordinal) == 0;
            var isEval   = match.Groups[2].Value?.IndexOf("eval", StringComparison.Ordinal) == 0;

            frame = new StackFrame
            {
                File         = !isNative ? match.Groups[2].Value : null,
                Method       = !string.IsNullOrEmpty(match.Groups[1]?.Value) ? match.Groups[1].Value : null,
                Arguments    = isNative ? new[] { match.Groups[2].Value } : Array.Empty <string>(),
                LineNumber   = !string.IsNullOrEmpty(match.Groups[3].Value) ? int.Parse(match.Groups[3].Value) : (int?)null,
                ColumnNumber = !string.IsNullOrEmpty(match.Groups[4].Value) ? int.Parse(match.Groups[4].Value) : (int?)null
            };

            var submatch = ChromeEvalRe.Match(match.Groups[2].Value);

            if (isEval && submatch.Success)
            {
                frame.File         = !isNative ? submatch.Groups[1].Value : null;
                frame.LineNumber   = !string.IsNullOrEmpty(submatch.Groups[2].Value) ? int.Parse(submatch.Groups[2].Value) : (int?)null;
                frame.ColumnNumber = !string.IsNullOrEmpty(submatch.Groups[3].Value) ? int.Parse(submatch.Groups[3].Value) : (int?)null;
            }

            return(true);
        }
Example #4
0
        internal static bool TryParseGecko(string line, out StackFrame?frame)
        {
            frame = null;

            var match = GeckoRe.Match(line);

            if (!match.Success)
            {
                return(false);
            }

            var isEval = match.Groups[3].Value.IndexOf("> eval", StringComparison.Ordinal) > -1;

            frame = new StackFrame
            {
                File         = match.Groups[3].Value,
                Method       = !string.IsNullOrEmpty(match.Groups[1]?.Value) ? match.Groups[1].Value : null,
                Arguments    = !string.IsNullOrEmpty(match.Groups[2].Value) ? match.Groups[2].Value.Split(',') : Array.Empty <string>(),
                LineNumber   = !string.IsNullOrEmpty(match.Groups[4].Value) ? int.Parse(match.Groups[4].Value) : (int?)null,
                ColumnNumber = !string.IsNullOrEmpty(match.Groups[5].Value) ? int.Parse(match.Groups[5].Value) : (int?)null,
            };

            var submatch = GeckoEvalRe.Match(line);

            if (isEval && submatch.Success)
            {
                frame.File         = submatch.Groups[1].Value;
                frame.LineNumber   = int.Parse(submatch.Groups[2].Value);
                frame.ColumnNumber = null;
            }

            return(true);
        }
Example #5
0
        private void RunScriptChecked(UpgradeScript script)
        {
            try
            {
                script.Method.Invoke();
            }
            catch (Exception e)
            {
                int line = 0;

                StackTrace stack = new StackTrace(e, true);
                for (int frameIndex = 0; frameIndex < stack.FrameCount; frameIndex++)
                {
                    StackFrame?frame  = stack.GetFrame(frameIndex);
                    MethodBase?method = frame?.GetMethod();
                    if (method is null)
                    {
                        continue;
                    }

                    VersionAttribute?attr = method.GetCustomAttribute <VersionAttribute>();
                    if (attr is not null)
                    {
                        line = frame?.GetFileLineNumber() ?? 0;
                        break;
                    }
                }

                throw new InvalidOperationException($"Error in script version {script.Major}.{script.Minor}.{script.Patch}, line {line} -> {e.Message}", e);
            }
        }
Example #6
0
    public static string GetTypeName()
    {
        StackTrace trace = new StackTrace();
        StackFrame?frame = trace.GetFrame(3);

        if (frame is null)
        {
            return(string.Empty);
        }
        MethodBase?method = frame.GetMethod();

        if (method is null)
        {
            return(string.Empty);
        }
        Type?declaringType = method.DeclaringType;

        if (declaringType is null)
        {
            return(string.Empty);
        }
        string?name = declaringType.ReflectedType?.FullName;

        if (string.IsNullOrEmpty(name))
        {
            return(declaringType.FullName ?? string.Empty);
        }
        return(name);
    }
Example #7
0
        public List <string> FirstNonWrappedTraceStack(Type typeToIgnore, Exception ex, int fromLevel)
        {
#if WINDOWS_UWP
            List <string> stackFrames = new List <string>();
            stackFrames.Add(Environment.StackTrace);
            return(stackFrames);
#else
            try {
                List <string> stackFrames     = new();
                StackTrace    trace           = new(ex, fromLevel, true);
                bool          firstNonWrapErr = false;
                string        ignoreTypeName  = typeToIgnore.Name;

                for (int i = 0; i < trace.FrameCount; i++)
                {
                    StackFrame?sf = trace.GetFrame(i);
                    if (sf == null)
                    {
                        return(stackFrames);
                    }
                    string frameClass = ClassName(sf);

                    // Skip over all entries until you hit the first not to ignore
                    if (!firstNonWrapErr)
                    {
                        if (frameClass != ignoreTypeName && !IsInternalClass(frameClass))
                        {
                            firstNonWrapErr = true;
                        }
                        else
                        {
                            continue;
                        }
                    }

                    if (frameClass != ignoreTypeName && !IsInternalClass(frameClass))
                    {
                        stackFrames.Add(
                            // Also ignore all instances of type to ignore
                            String.Format("     {0} : Line:{1} - {2}.{3}",
                                          FileName(sf),
                                          Line(sf),
                                          frameClass,
                                          MethodName(sf)));
                    }
                }
                return(stackFrames);
            }
            catch (Exception) {
                List <string> stackFrames = new();
                stackFrames.Add("BLAH");
                return(stackFrames);
            }
#endif
        }
        private static int?TryGetSourceLine(TestResult testResult, StackFrame?stackFrame)
        {
            // See if test runner provided it (never actually happens)
            if (testResult.TestCase.LineNumber > 0)
            {
                return(testResult.TestCase.LineNumber);
            }

            // Try to extract it from stack trace (works only if there was an exception)
            return(stackFrame?.Line);
        }
Example #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Frame"/> class.
        /// </summary>
        /// <param name="frame">The frame.</param>
        public Frame(StackFrame?frame)
        {
            if (frame == null)
            {
                return;
            }

            Method   = GetMethod(frame);
            FileName = GetFileName(frame);
            LineNo   = GetLineNumber(frame);
            ColNo    = LineNo.HasValue ? GetFileColumnNumber(frame) : null;
        }
Example #10
0
        /// <summary>
        /// Walk through stack until you encounter the first class that is not to be ignored and
        /// whose method does not have the <>
        /// </summary>
        /// <param name="typeToIgnore">Type to ignore as you travel the stack</param>
        /// <returns>The class containing class and method information</returns>
        public ErrorLocation FirstNonWrappedMethod(Type typeToIgnore)
        {
#if WINDOWS_UWP
            // remove if when Windows universal implements the default constructor on StackTrace
            return(new ErrorLocation());
#else
            // Go at least one up to ignore this method.
            int        index = 1;
            StackTrace st    = new();

            MethodBase?mb = st.GetFrame(index)?.GetMethod();
            if (mb != null)
            {
                while (true)
                {
                    Type?declaringType = mb.DeclaringType;
                    if (declaringType == null)
                    {
                        return(new ErrorLocation());
                    }

                    if ((typeToIgnore == null) ||
                        (declaringType.Name != typeToIgnore.Name && !IsInternalClass(declaringType.Name)) && !mb.Name.Contains('<'))
                    {
                        return(new ErrorLocation(declaringType.Name, mb.Name));
                    }

                    ++index;
                    StackFrame?sf = st.GetFrame(index);
                    if (sf == null)
                    {
                        return(new ErrorLocation(declaringType.Name, mb.Name));
                    }

                    MethodBase?tmp = sf.GetMethod();
                    if (tmp == null)
                    {
                        return(new ErrorLocation(declaringType.Name, mb.Name));
                    }
                    mb = tmp;
                }
            }
            else
            {
                return(new ErrorLocation());
            }
#endif
        }
Example #11
0
 private static void _Log(LogLevel level, string message, int stackFrameIndex = 2)
 {
     if (LogFunction != null)
     {
         StackTrace?stackTrace = new StackTrace();
         StackFrame?stackFrame = stackTrace.GetFrame(stackFrameIndex);
         if (stackFrame != null)
         {
             System.Reflection.MethodBase?method = stackFrame.GetMethod();
             if (method != null)
             {
                 Type?type = method.DeclaringType;
                 if (type != null)
                 {
                     LogFunction(type, level, message);
                 }
             }
         }
     }
 }
Example #12
0
        internal static bool TryParseJsc(string line, out StackFrame?frame)
        {
            frame = null;

            var match = JscRe.Match(line);

            if (!match.Success)
            {
                return(false);
            }

            frame = new StackFrame
            {
                File         = match.Groups[3].Value,
                Method       = !string.IsNullOrEmpty(match.Groups[1].Value) ? match.Groups[1].Value : null,
                Arguments    = Array.Empty <string>(),
                LineNumber   = int.Parse(match.Groups[4].Value),
                ColumnNumber = !string.IsNullOrEmpty(match.Groups[5].Value) ? int.Parse(match.Groups[5].Value) : (int?)null
            };

            return(true);
        }
Example #13
0
        internal void ToString(TraceFormat traceFormat, StringBuilder sb)
        {
            // Passing a default string for "at" in case SR.UsingResourceKeys() is true
            // as this is a special case and we don't want to have "Word_At" on stack traces.
            string word_At = SR.GetResourceString(nameof(SR.Word_At), defaultString: "at");
            // We also want to pass in a default for inFileLineNumber.
            string inFileLineNum = SR.GetResourceString(nameof(SR.StackTrace_InFileLineNumber), defaultString: "in {0}:line {1}");
            bool   fFirstFrame   = true;

            for (int iFrameIndex = 0; iFrameIndex < _numOfFrames; iFrameIndex++)
            {
                StackFrame?sf = GetFrame(iFrameIndex);
                MethodBase?mb = sf?.GetMethod();
                if (mb != null && (ShowInStackTrace(mb) ||
                                   (iFrameIndex == _numOfFrames - 1))) // Don't filter last frame
                {
                    // We want a newline at the end of every line except for the last
                    if (fFirstFrame)
                    {
                        fFirstFrame = false;
                    }
                    else
                    {
                        sb.AppendLine();
                    }

                    sb.AppendFormat(CultureInfo.InvariantCulture, "   {0} ", word_At);

                    bool   isAsync       = false;
                    Type?  declaringType = mb.DeclaringType;
                    string methodName    = mb.Name;
                    bool   methodChanged = false;
                    if (declaringType != null && declaringType.IsDefined(typeof(CompilerGeneratedAttribute), inherit: false))
                    {
                        isAsync = typeof(IAsyncStateMachine).IsAssignableFrom(declaringType);
                        if (isAsync || typeof(IEnumerator).IsAssignableFrom(declaringType))
                        {
                            methodChanged = TryResolveStateMachineMethod(ref mb, out declaringType);
                        }
                    }

                    // if there is a type (non global method) print it
                    // ResolveStateMachineMethod may have set declaringType to null
                    if (declaringType != null)
                    {
                        // Append t.FullName, replacing '+' with '.'
                        string fullName = declaringType.FullName !;
                        for (int i = 0; i < fullName.Length; i++)
                        {
                            char ch = fullName[i];
                            sb.Append(ch == '+' ? '.' : ch);
                        }
                        sb.Append('.');
                    }
                    sb.Append(mb.Name);

                    // deal with the generic portion of the method
                    if (mb is MethodInfo mi && mi.IsGenericMethod)
                    {
                        Type[] typars = mi.GetGenericArguments();
                        sb.Append('[');
                        int  k             = 0;
                        bool fFirstTyParam = true;
                        while (k < typars.Length)
                        {
                            if (!fFirstTyParam)
                            {
                                sb.Append(',');
                            }
                            else
                            {
                                fFirstTyParam = false;
                            }

                            sb.Append(typars[k].Name);
                            k++;
                        }
                        sb.Append(']');
                    }

                    ParameterInfo[]? pi = null;
                    try
                    {
                        pi = mb.GetParameters();
                    }
                    catch
                    {
                        // The parameter info cannot be loaded, so we don't
                        // append the parameter list.
                    }
                    if (pi != null)
                    {
                        // arguments printing
                        sb.Append('(');
                        bool fFirstParam = true;
                        for (int j = 0; j < pi.Length; j++)
                        {
                            if (!fFirstParam)
                            {
                                sb.Append(", ");
                            }
                            else
                            {
                                fFirstParam = false;
                            }

                            string typeName = "<UnknownType>";
                            if (pi[j].ParameterType != null)
                            {
                                typeName = pi[j].ParameterType.Name;
                            }
                            sb.Append(typeName);
                            sb.Append(' ');
                            sb.Append(pi[j].Name);
                        }
                        sb.Append(')');
                    }

                    if (methodChanged)
                    {
                        // Append original method name e.g. +MoveNext()
                        sb.Append('+');
                        sb.Append(methodName);
                        sb.Append('(').Append(')');
                    }

                    // source location printing
                    if (sf !.GetILOffset() != -1)
                    {
                        // If we don't have a PDB or PDB-reading is disabled for the module,
                        // then the file name will be null.
                        string?fileName = sf.GetFileName();

                        if (fileName != null)
                        {
                            // tack on " in c:\tmp\MyFile.cs:line 5"
                            sb.Append(' ');
                            sb.AppendFormat(CultureInfo.InvariantCulture, inFileLineNum, fileName, sf.GetFileLineNumber());
                        }
                    }

                    // Skip EDI boundary for async
                    if (sf.IsLastFrameFromForeignExceptionStackTrace && !isAsync)
                    {
                        sb.AppendLine();
                        // Passing default for Exception_EndStackTraceFromPreviousThrow in case SR.UsingResourceKeys is set.
                        sb.Append(SR.GetResourceString(nameof(SR.Exception_EndStackTraceFromPreviousThrow),
                                                       defaultString: "--- End of stack trace from previous location ---"));
                    }
                }
            }

            if (traceFormat == TraceFormat.TrailingNewLine)
            {
                sb.AppendLine();
            }
        }
Example #14
0
        /// <summary>
        /// Run selected cases.
        /// </summary>
        /// <param name="which">List of names of test cases to run. If the test case names begin with these values they will run.</param>
        public void RunSuites(string[] which)
        {
            // Locate the test cases.
            Dictionary <string, TestSuite> suites = new();

            foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
            {
                if (t.BaseType is not null && t.BaseType.Name.Contains("TestSuite"))
                {
                    // It's a test suite. Is it requested?
                    foreach (string ssuite in which)
                    {
                        if (t.Name.StartsWith(ssuite))
                        {
                            object?o = Activator.CreateInstance(t);
                            if (o is not null)
                            {
                                suites.Add(t.Name, (TestSuite)o);
                            }
                            else
                            {
                                Context.OutputLines.Add($"Couldn't create {t.BaseType.Name}");
                            }
                        }
                    }
                }
            }

            DateTime startTime = DateTime.Now;

            // Run through to execute suites.
            foreach (string ss in suites.Keys)
            {
                Context.CurrentSuiteId = ss;
                TestSuite tc = suites[ss];
                tc.Context = Context;
                Context.CurrentSuitePass = true;
                Context.CurrentCasePass  = true;
                Context.PropertyLines.Clear();

                // Document the start of the suite.
                switch (Context.Format)
                {
                case OutputFormat.Xml:
                    tc.RecordVerbatim($"    <testsuite name = {ss}>");
                    break;

                case OutputFormat.Readable:
                    tc.RecordVerbatim($"Suite {ss}");
                    break;
                }

                try
                {
                    // Run the suite.
                    tc.RunSuite();
                }
                catch (AssertException ex)
                {
                    // Deliberate exception.
                    tc.RecordResult(false, ex.Message, ex.File, ex.Line);
                }
                catch (Exception ex)
                {
                    // Out of scope exception. Top frame contains the cause.
                    StackTrace st    = new(ex, true);
                    StackFrame?frame = st.GetFrame(0);

                    if (frame is not null)
                    {
                        int    line = frame.GetFileLineNumber();
                        string fn   = Path.GetFileName(frame !.GetFileName() !);
                        string msg  = $"{ex.Message} ({fn}:{line})";
                        tc.RecordResult(false, msg, fn, line);
                    }
                }

                // Completed the suite, update the counts.
                Context.NumSuitesRun++;
                Context.NumCasesRun    += tc.CaseCnt;
                Context.NumCasesFailed += tc.CaseFailCnt;

                switch (Context.Format)
                {
                case OutputFormat.Xml:
                    // Any properties?
                    if (Context.PropertyLines.Count > 0)
                    {
                        tc.RecordVerbatim($"        <properties>");
                        Context.PropertyLines.ForEach(l => tc.RecordVerbatim(l));
                        tc.RecordVerbatim($"        </properties>");
                    }

                    tc.RecordVerbatim($"    </testsuite>");
                    break;

                case OutputFormat.Readable:
                    Context.OutputLines.Add($"");
                    break;
                }
            }

            // Finished the test run, prepare the summary.
            DateTime      endTime  = DateTime.Now;
            TimeSpan      dur      = endTime - startTime;
            string        sdur     = dur.ToString(TIME_FORMAT);
            List <string> preamble = new();

            switch (Context.Format)
            {
            case OutputFormat.Xml:
                preamble.Add($"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                preamble.Add($"<testsuites tests={Context.NumCasesRun} failures={Context.NumCasesFailed} time={sdur} >");
                break;

            case OutputFormat.Readable:
                string pass = Context.NumCasesFailed > 0 ? "Fail" : "Pass";

                preamble.Add($"#------------------------------------------------------------------");
                preamble.Add($"# Unit Test Report");
                preamble.Add($"# Start Time: {startTime.ToString(DATE_TIME_FORMAT_MSEC)}");
                preamble.Add($"# Duration: {sdur}");
                //preamble.Add($"# Suites Run: {Context.NumSuitesRun}");
                //preamble.Add($"# Suites Failed: {Context.NumSuitesFailed}");
                preamble.Add($"# Cases Run: {Context.NumCasesRun}");
                preamble.Add($"# Cases Failed: {Context.NumCasesFailed}");
                preamble.Add($"# Test Result: {pass}");
                preamble.Add($"#------------------------------------------------------------------");
                break;
            }

            Context.OutputLines.InsertRange(0, preamble);
            if (Context.Format == OutputFormat.Xml)
            {
                Context.OutputLines.Add($"</testsuites>");
            }

            Context.OutputLines.ForEach(l => Console.WriteLine(l));
        }
Example #15
0
        private static string GetStackTrace(Exception exception)
        {
            // Output stacktrace in custom format (very similar to Exception.StackTrace property on English systems).
            // Include filenames where available, but no paths.
            StackTrace stackTrace = new StackTrace(exception,
                                                   true);

            StringBuilder b = new StringBuilder();

            for (int i = 0; i < stackTrace.FrameCount; i++)
            {
                StackFrame?frame  = stackTrace.GetFrame(i);
                MethodBase?method = frame?.GetMethod();

                if (method == null)
                {
                    continue;
                }

                if (b.Length > 0)
                {
                    b.AppendLine();
                }

                b.Append("   at ");
                Type?declaringType = method.DeclaringType;

                if (declaringType != null)
                {
                    b.Append(declaringType.FullName.Replace('+',
                                                            '.'));

                    b.Append('.');
                }

                b.Append(method.Name);

                // output type parameters, if any
                if (method is MethodInfo && ((MethodInfo)method).IsGenericMethod)
                {
                    Type[] genericArguments = ((MethodInfo)method).GetGenericArguments();
                    b.Append('[');

                    for (int j = 0; j < genericArguments.Length; j++)
                    {
                        if (j > 0)
                        {
                            b.Append(',');
                        }

                        b.Append(genericArguments[j].Name);
                    }

                    b.Append(']');
                }

                // output parameters, if any
                b.Append('(');
                ParameterInfo[] parameters = method.GetParameters();

                for (int j = 0; j < parameters.Length; j++)
                {
                    if (j > 0)
                    {
                        b.Append(", ");
                    }

                    if (parameters[j].ParameterType != null)
                    {
                        b.Append(parameters[j].ParameterType.Name);
                    }
                    else
                    {
                        b.Append('?');
                    }

                    if (!string.IsNullOrEmpty(parameters[j].Name))
                    {
                        b.Append(' ');
                        b.Append(parameters[j].Name);
                    }
                }

                b.Append(')');

                // source location
                if (frame is not null && frame.GetILOffset() >= 0)
                {
                    string?filename = null;

                    try
                    {
                        string fullpath = frame.GetFileName();

                        if (fullpath != null)
                        {
                            filename = Path.GetFileName(fullpath);
                        }
                    }
                    catch (SecurityException)
                    {
                        // StackFrame.GetFileName requires PathDiscovery permission
                    }
                    catch (ArgumentException)
                    {
                        // Path.GetFileName might throw on paths with invalid chars
                    }

                    b.Append(" in ");

                    if (filename != null)
                    {
                        b.Append(filename);
                        b.Append(":line ");
                        b.Append(frame.GetFileLineNumber());
                    }
                    else
                    {
                        b.Append("offset ");
                        b.Append(frame.GetILOffset());
                    }
                }
            }

            return(b.ToString());
        }
Example #16
0
        /// <summary>
        /// Walk through stack until you encounter the first class that is not to be ignored and
        /// whose method does not have the
        /// </summary>
        /// <param name="typeToIgnore">Type to ignore as you travel the stack</param>
        /// <returns>The class containing class and method information</returns>
        public ErrorLocation FirstNonWrappedMethod(Type[] typesToIgnore)
        {
#if WINDOWS_UWP
            return(new ErrorLocation());
#else
            // Go at least one up to ignore this method.
            int        index = 1;
            StackTrace st    = new();

            MethodBase?mb = st.GetFrame(index)?.GetMethod();
            if (mb != null)
            {
                while (true)
                {
                    Type?declaringType = mb.DeclaringType;
                    if (declaringType == null)
                    {
                        return(new ErrorLocation());
                    }

                    if ((typesToIgnore == null))
                    {
                        return(new ErrorLocation(declaringType.Name, mb.Name));
                    }

                    // It must not be equal to any of the ignore types to be the correct level
                    bool matchAny = false;
                    foreach (Type t in typesToIgnore)
                    {
                        if (declaringType.Name == t.Name || mb.Name.Contains('<'))
                        {
                            matchAny = true;
                            break;
                        }
                    }

                    if (!matchAny)
                    {
                        return(new ErrorLocation(declaringType.Name, mb.Name));
                    }

                    ++index;
                    StackFrame?sf = st.GetFrame(index);
                    if (sf == null)
                    {
                        return(new ErrorLocation(declaringType.Name, mb.Name));
                    }

                    MethodBase?tmp = sf.GetMethod();
                    if (tmp == null)
                    {
                        return(new ErrorLocation(declaringType.Name, mb.Name));
                    }
                    mb = tmp;
                }
            }
            else
            {
                return(new ErrorLocation());
            }
#endif
        }