Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit Tests that test methods with Decompile fail while trying to calculate code coverage #15

Open
VenolVl opened this issue Sep 18, 2014 · 4 comments

Comments

@VenolVl
Copy link

VenolVl commented Sep 18, 2014

Hello, i have encountered an issue with DelegateDecompiler:
When i try to test methods that use Decompile(), those tests are passing when i just run them, but when i try to calculate code coverage i receive following error in every test that use Decompile():

System.AggregateException: One or more errors occurred. ---> System.InvalidCastException: Specified cast is not valid.
at DelegateDecompiler.Processor.Process(Instruction instruction, Instruction last)
at DelegateDecompiler.Processor.Process(Instruction instruction, Type returnType)
at DelegateDecompiler.MethodBodyDecompiler.Decompile()
at DelegateDecompiler.DecompileExtensions.<>c__DisplayClass1.b__0(MethodInfo m)
at DelegateDecompiler.Cache2.GetOrAdd(TKey key, Func2 func)
at DelegateDecompiler.DecompileExtensions.Decompile(MethodInfo method)
at DelegateDecompiler.DecompileExpressionVisitor.Decompile(MethodInfo method, Expression instance, IList1 arguments) at DelegateDecompiler.DecompileExpressionVisitor.VisitMember(MemberExpression node) at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node) at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node) at System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection1 nodes, Func2 elementVisitor) at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node) at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression1 node)
at System.Linq.Expressions.Expression1.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node) at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes) at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node) at DelegateDecompiler.DecompileExpressionVisitor.VisitMethodCall(MethodCallExpression node) at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at DelegateDecompiler.DecompileExtensions.Decompile[T](IQueryable1 self)
at IBCM.Models.Readers.TaskReader.d__6.MoveNext() in D:\dev\ibcm\src\Models\Readers\TaskReader.cs:line 41
--- End of stack trace from previous location where exception was thrown ---

I tried using nCrunch, dotCover and Visual Studio Coverage Analyzer, but tests are failing no matter which test engine i am using. As i said it happens only when i try to calculate code coverage, tests are working when i run them manually. Example of method with Decompile:

public async virtual Task<Tuple<IEnumerable<TodoInfo>, IEnumerable<MeetingInfo>>> GetPastTasksByContactId(Guid contactId)
        {
            var todoes = await taskService.GetPastTodoesByContactId(contactId).Project().To<TodoInfo>().Decompile().ToListAsync();
            var meetings = await appointmentService.GetPastMeetingsByContactId(contactId).Project().To<MeetingInfo>().Decompile().ToListAsync();

            return new Tuple<IEnumerable<TodoInfo>, IEnumerable<MeetingInfo>>(todoes, meetings);
        }
@mwillebrands
Copy link

Is probably fixed, #39

@BrettBock
Copy link

BrettBock commented May 5, 2021

Still seeing this issue in Visual Studio 2019 Enterprise 16.9.4, using EFCore 5.0.5. However the error I see now is as follows:

...
Test Outcome: Failed
Result StackTrace:
at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression arg0)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable1 arguments) at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression[] arguments) at DelegateDecompiler.Processor.BuildMethodCallExpression(MethodInfo m, Address instance, Expression[] arguments) at DelegateDecompiler.Processor.Call(ProcessorState state, MethodInfo m) at DelegateDecompiler.Processor.Process() at DelegateDecompiler.Processor.Process(VariableInfo[] locals, IList1 args, Instruction instruction, Type returnType)
at DelegateDecompiler.MethodBodyDecompiler.Decompile(MethodInfo method, Type declaringType)
at DelegateDecompiler.DecompileExtensions.<>c__DisplayClass6_0.<.cctor>b__1()
at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location where exception was thrown --- at System.Lazy1.CreateValue()
at System.Lazy1.get_Value() at DelegateDecompiler.DecompileExtensions.Decompile(MethodInfo method, Type declaringType) at DelegateDecompiler.DecompileExpressionVisitor.Decompile(MethodInfo method, Expression instance, IList1 arguments)
at DelegateDecompiler.DecompileExpressionVisitor.VisitMember(MemberExpression node)
at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression1 node) at System.Linq.Expressions.Expression1.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at DelegateDecompiler.DecompileExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at DelegateDecompiler.DecompileExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at DelegateDecompiler.DecompileExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at DelegateDecompiler.DecompileExpressionVisitor.Decompile(Expression expression)
at DelegateDecompiler.DecompiledQueryProvider.CreateQuery[TElement](Expression expression)
at DelegateDecompiler.DecompileExtensions.Decompile[T](IQueryable`1 self)
...
Result Message: System.ArgumentException : Expression of type 'System.Int64' cannot be used for parameter of type 'System.UInt64' of method 'Void 482083558__coverage_runtime_method__13811_20409__(UInt64)' (Parameter 'arg0')

@GravlLift
Copy link

GravlLift commented Apr 14, 2022

I'm encountering this as well in 0.30.0. dotnet test works just fine, as does dotnet test "--collect:XPlat Code Coverage". But dotnet test "--collect:Code Coverage" is problematic.

Stepped into it with the debugger. The instructions generated below are radically different depending on if --collect:Code Coverage is specified or not:

var locals = addresses.ToArray();
var instructions = method.GetInstructions();
var expression = Processor.Process(locals, args, instructions.First(), method.ReturnType);
var localParameters = locals

In my case, that results in a stack with a bunch of extraneous ints in it, crashing when it tries to call HasValue on an Int32 when it's supposed to be calling it on a nullable DateTimeOffset.

Good instructions:
image
Bad instructions:
image

Bad stack, after popping off an Int32 to throw an ArgumentException (correct target is item 1 in the stack):
image

Good stack, empty after correctly popping the nullable DateTimeOffset:
image

I guess the integers aren't really a problem, the real problem is why isn't instructions[10] on the top of the stack?

EDIT: First time working with IL, so this is taking me a bit, but it appears that the stloc instruction at index 3/9 pops whatevers on top of the stack into the local variable array at index 1. In the non-code coverage version of the code, that's the value that was just returned from 0002, the call to get that DateTimeOffset. In the code coverage version, that's instead the value 1, which was loaded onto the top of the stack by 001b.

Seems like DelegateDecompiler is interpreting these instructions correctly, it's just that the instructions themselves are garbled.

@GravlLift
Copy link

@hazzik, I've managed to put together a minimal reproduction for this one. It's very strange.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants