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

.NET Native causing NullReferenceException in CallerIdentity class #1149

Closed
borrrden opened this issue Sep 24, 2019 · 4 comments
Closed

.NET Native causing NullReferenceException in CallerIdentity class #1149

borrrden opened this issue Sep 24, 2019 · 4 comments
Labels
bug

Comments

@borrrden
Copy link

@borrrden borrrden commented Sep 24, 2019

Description

When using certain functions in UWP tests, null reference exceptions occur only when compiling with .NET Native (which is a requirement for the Windows Store).

Complete minimal example reproducing the issue

Complete means the code snippet can be copied into a unit test method in a fresh C# project and run.
Minimal means it is stripped from code not related to reproducing the issue.

E.g.

var arr1 = new[] {1, 2, 3, 4, 5};
var arr2 = new[] {1, 2, 3, 4, 5, 6};
arr1.Should().NotBeEquivalentTo(arr2);

Expected behavior:

The assertion should pass

Actual behavior:

Message: Test method ... threw exception:
System.NullReferenceException: Object reference not set to an instance of an object.

Test Name: TestReKey
Test FullName: Test.DatabaseEncryptionTest.TestReKey
Test Source: C:\Development\couchbase-lite-net-ee\couchbase-lite-net\src\Couchbase.Lite.Tests.Shared\DatabaseEncryptionTest.cs : line 169
Test Outcome: Failed
Test Duration: 0:00:00.2356786

Result StackTrace:

at FluentAssertions.CallerIdentifier.DetermineCallerIdentity()
   at FluentAssertions.Execution.AssertionScope.<>c__DisplayClass30_0.<FailWith>b__0()
   at FluentAssertions.Execution.AssertionScope.FailWith(Func<System.String> failReasonFunc)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func<FluentAssertions.Execution.FailReason> failReasonFunc)
   at FluentAssertions.Execution.AssertionScope.FailWith(String message, Object[] args)
   at Continuation FluentAssertions.Equivalency.EnumerableEquivalencyValidatorExtensions.AssertCollectionHasEnoughItems[T](IAssertionScope, ICollection`1, ICollection`1) + 0x100
   at Continuation FluentAssertions.Equivalency.EnumerableEquivalencyValidator.AssertCollectionsHaveSameCount[T](ICollection`1, ICollection`1) + 0xe8
   at Void FluentAssertions.Equivalency.EnumerableEquivalencyValidator.Execute[T](Object[], T[]) + 0x90
   at FluentAssertions.Equivalency.EnumerableEquivalencyStep.Handle(Equivalency.IEquivalencyValidationContext context, Equivalency.IEquivalencyValidator parent, Equivalency.IEquivalencyAssertionOptions config)
   at FluentAssertions.Equivalency.EquivalencyValidator.RunStepsUntilEquivalencyIsProven(Equivalency.IEquivalencyValidationContext context)
   at FluentAssertions.Equivalency.EquivalencyValidator.AssertEqualityUsing(Equivalency.IEquivalencyValidationContext context)
   at FluentAssertions.Equivalency.EquivalencyValidator.AssertEquality(Equivalency.EquivalencyValidationContext context)
   at AndConstraint`1 FluentAssertions.Collections.CollectionAssertions`2.BeEquivalentTo(IEnumerable, Func`2, String, Object[]) + 0x14e
   at AndConstraint`1 FluentAssertions.Collections.CollectionAssertions`2.BeEquivalentTo(IEnumerable, String, Object[]) + 0x97
   at AndConstraint`1 FluentAssertions.Collections.CollectionAssertions`2.NotBeEquivalentTo(IEnumerable, String, Object[]) + 0x2ed

Stack trace remainder omitted (no more FA frames)

Versions

Fluent Assertions 5.9.0
UWP 6.0.6 with .NET Native Compiler enabled

Additional Information

This is probably due to native frames being passed through instead of C# ones as the result of the native compilation. Debug builds, without .NET Native enabled, work as expected. I recently upgraded from 4.x to 5.9 and I don't remember this happening in 4.x. I've confirmed this happens because each StackFrame in StackTrace returns null from GetMethod(). I feel like this method DetermineCallerIdentity should be used quite a bit so I'm not sure why it would only fail from certain conditions.

@borrrden

This comment has been minimized.

Copy link
Author

@borrrden borrrden commented Sep 24, 2019

On second thought, why is this trying to fail? The assertion should pass and have no reason to go through FailWith in the first place...

This seems to only have with NotBeEquivalentTo and not BeEquivalentTo

borrrden added a commit to couchbase/couchbase-lite-net that referenced this issue Sep 24, 2019
Unable to run this test without crashing due to fluentassertions/fluentassertions#1149
@dennisdoomen

This comment has been minimized.

Copy link
Member

@dennisdoomen dennisdoomen commented Sep 24, 2019

When comparing collections by equivalency, it's trying to find a combination that as equivalent as possible and report that. Because of its recursive nature, it relies on the internal comparison to throw a failure. So we really have two bugs here.

@dennisdoomen dennisdoomen added the bug label Sep 24, 2019
jnyrup added a commit to jnyrup/fluentassertions that referenced this issue Oct 25, 2019
Apparently when compiling an UWP project with .NET Native
`StackFrame.GetMethod` can return `null`. As determination
of caller identity is just a nice-to-have and not a need-to-have
I think we should wrap it in a `try/catch` instead of throwing
exceptions.
Related to fluentassertions#1149
@dennisdoomen

This comment has been minimized.

Copy link
Member

@dennisdoomen dennisdoomen commented Jan 1, 2020

This is fixed, right?

@jnyrup

This comment has been minimized.

Copy link
Collaborator

@jnyrup jnyrup commented Jan 1, 2020

Yes should be. We null check GetMethod and catch exceptions in any case. So I'll close this for now.
Feel free to reopen if the issue hasn't been fixed.
Could be nice with a regression test to verify the fix though

@jnyrup jnyrup closed this Jan 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.