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

Test fail when run using Visual Studio 15.7.5 and Resharper 2018.1.3 but not from build.cmd for net45 #421

Closed
ghost opened this issue Jul 14, 2018 · 19 comments
Milestone

Comments

@ghost
Copy link

ghost commented Jul 14, 2018

When running test inside Visual Studio using Resharper I noticed that 13 tests are failing. However when I run the test from build.cmd everything passes. I just updated my Visual Studio and Resharper today and noticed this to be the case.

image

image

@ghost ghost changed the title Test fail when run using Visual Studio 15.7.5 and Resharper 2018.1.3 but not from build.cmd Test fail when run using Visual Studio 15.7.5 and Resharper 2018.1.3 but not from build.cmd for net45 Jul 14, 2018
@ghost
Copy link
Author

ghost commented Jul 14, 2018

An example of a test that fails is:

[Test]
public void Disposable_singleton_dependency_of_transient_open_generic_is_disposed()
{
DisposableFoo.ResetDisposedCount();
Container.Register(
Component.For(typeof(GenericComponent<>)).LifeStyle.Transient,
Component.For<DisposableFoo>().LifeStyle.Singleton
);
var depender = Container.Resolve<GenericComponent<DisposableFoo>>();
var weak = new WeakReference(depender.Value);
depender = null;
Container.Dispose();
GC.Collect();
Assert.AreEqual(1, DisposableFoo.DisposedCount);
Assert.IsFalse(weak.IsAlive);
}

Assert.IsFalse(weak.IsAlive); appears to be having a problem.

@jonorossi
Copy link
Member

Did you have dotMemory and dotTrace installed before this started failing? I've run the tests with them installed before but maybe something has changed with their instrumentation that is causing the short lived objects not to get garbage collected when asked.

Could you try some of the suggestions in this StackOverflow thread to see what fixes it:
https://stackoverflow.com/questions/15205891/garbage-collection-should-have-removed-object-but-weakreference-isalive-still-re

@ghost
Copy link
Author

ghost commented Jul 25, 2018

@jonorossi You are right. Today I started profiling some integration tests on another project and file locks were kicking in and failing tests. I will re-post this on the JB issue tracker.

@ghost
Copy link
Author

ghost commented Aug 22, 2018

The answer is upgrade, and upgrade often. Works for ...

image

image

@ghost ghost closed this as completed Aug 22, 2018
@mario-d-s
Copy link

mario-d-s commented Aug 23, 2018

@fir3pho3nixx I'm afraid it doesn't. Maybe related to some setting (in VS or R#), or installed components?

I have the exact same versions in any case.

@ghost
Copy link
Author

ghost commented Aug 23, 2018

Are you opening the solution with elevated privileges? Which tests are failing for you?

@ghost ghost reopened this Aug 23, 2018
@mario-d-s
Copy link

mario-d-s commented Aug 23, 2018

Are you opening the solution with elevated privileges?

I am. My Visual Studio is set to always run as Administrator. Now that I mention it: I am on 2017 Professional whereas you are using Community.

Which tests are failing for you?

13 tests, so assuming the same ones as did for you earlier.
TXT export of the failing tests here.

@ghost
Copy link
Author

ghost commented Aug 29, 2018

@mario-d-s

Have you taken the latest updates from Visual Studio? Quite a few got barreled out over the past few days.

@mario-d-s
Copy link

@fir3pho3nixx I just did, still 13 tests are failing. I'm thinking this must be related to the compiler. For example I have the .NET 4.7.2 SDK installed and these are the properties of CSC.exe:

CSC.exe properties

@ghost
Copy link
Author

ghost commented Sep 26, 2018

@mario-d-s can you please try with the latest VS/RS updates and tell me if anything changes? I have not seen any problems.

@ghost
Copy link
Author

ghost commented Oct 1, 2018

Marking this as abandoned. I don't have this issue at work or on BYOD.

@jnm2
Copy link
Contributor

jnm2 commented Oct 10, 2018

Reproing on VS 15.8.7 and ReSharper 2018.2.3 which are current as of today.

In every case, the problem is that the WeakReference the test creates is alive when the test expects it not to be.

In particular, this trivial test (which follows the same pattern that the real tests depend on) fails when run via ReSharper:

		[Test]
		public void SimpleRepro()
		{
			var weak = new WeakReference(new object());
			GC.Collect();
			Assert.IsFalse(weak.IsAlive);
		}

Therefore, all the real tests have some hidden assumptions about the timeframe in which GC will certainly happen. There should probably be a test helper which actually ensures GC.

@jnm2
Copy link
Contributor

jnm2 commented Oct 10, 2018

Discovered that the problem disappears when the solution configuration is switched to Release. In Debug, this test never completes. In Release, it completes instantly:

			var weak = new WeakReference(new object());

			while (weak.IsAlive)
			{
				GC.Collect();
			}

@jnm2
Copy link
Contributor

jnm2 commented Oct 10, 2018

ReSharper is behaving as you'd expect for a .NET assembly compiled in debug mode. You'd get the same behavior if the test was a console app. The oddball is VSTest; these tests wouldn't normally pass if the project is compiled in debug mode. ReSharper is making sure its runner is running with JIT/GC optimizations enabled/disabled to match the test assembly instead of always enabled like VSTest.

Good explanation in this answer: https://stackoverflow.com/questions/37462378/why-c-sharp-garbage-collection-behavior-differs-for-release-and-debug-executable

@jnm2
Copy link
Contributor

jnm2 commented Oct 10, 2018

What works is this pattern, never evaluating the expression that returns the tracked instance within the method but rather within a call that returns:

		[Test]
		public void Managed_externally_factory_component_transient_is_not_tracked_by_the_container()
		{
			Kernel.Register(Component.For<DisposableComponent>()
			                	.LifeStyle.Transient
			                	.UsingFactoryMethod(() => new DisposableComponent(), managedExternally: true));

			var weak = GetWeakReferenceForTesting(Kernel.Resolve<DisposableComponent>());
			GC.Collect();

			Assert.IsFalse(weak.IsAlive);
		}

		private static WeakReference GetWeakReferenceForTesting(Func<object> getInstanceToTrack)
		{
			return new WeakReference(getInstanceToTrack.Invoke());
		}

@jnm2
Copy link
Contributor

jnm2 commented Oct 11, 2018

Hey, while refactoring all the WeakReference tests to use a new helper API, I discovered that @ivan-danilov had run into (and documented) this exact same issue on a single test:

[Test]
public void Transient_depending_on_scoped_component_is_not_tracked_by_the_container()
{
Container.Register(Component.For<DisposableFoo>().LifeStyle.Scoped(),
Component.For<UsesDisposableFoo>().LifeStyle.Transient);
using (Container.BeginScope())
{
var weakUdt = GetWeakReferenceToDisposableFoo();
GC.Collect();
Assert.IsFalse(weakUdt.IsAlive);
}
}
// method is needed because since 4.6.x under debug configuration local variables are not
// considered for garbage collection; hence if method is inlined - test will fail
private WeakReference GetWeakReferenceToDisposableFoo()
{
var udf = Container.Resolve<UsesDisposableFoo>();
var weakUdt = new WeakReference(udf);
udf = null;
return weakUdt;
}

See #138 for that pull request.

@jnm2
Copy link
Contributor

jnm2 commented Oct 11, 2018

This exact issue was also discovered on two other tests by @alinapopa and discussed here: #235 (comment)

[Test]
#if DEBUG
[Ignore("This test fails in Debug / relies on GC.Collect to clean weak reference")]
#endif
public void CanResolveClientAssociatedWithChannelUsingSuppliedEndpoint()

[Test]
#if DEBUG
[Ignore("This test fails in Debug / relies on GC.Collect to clean weak reference")]
#endif
public void CanLazilyResolveClientAssociatedWithChannelUsingSuppliedEndpoint()

@jnm2
Copy link
Contributor

jnm2 commented Oct 11, 2018

Got all tests passing in ReSharper! #440

@jonorossi
Copy link
Member

This exact issue was also discovered on two other tests

@jnm2 I remember alinapopa coming across that one now. Great work getting this one sorted.

@jonorossi jonorossi added this to the v5.0 milestone Oct 14, 2018
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants