Running Unit Tests containing Microsoft.Fakes Via Reflection - c#

I am trying to produce my own Test Runner that accesses unit test methods via reflection and runs them inside a separate AppDomain.
object instance = Activator.CreateInstance(targetType);
foreach (MethodInfo method in methods)
{
method.Invoke(instance, null);
}
This works perfectly until one of the tests uses Microsoft.Fakes at which point when the method attempts to create the ShimsContext it throws this exception:
System.Reflection.TargetInvocationException was unhandled
HResult=-2146232828
Message=Exception has been thrown by the target of an invocation.
Source=mscorlib
StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
...
InnerException:
HResult=-2146233088
Message=Failed to resolve profiler path from COR_PROFILER_PATH and COR_PROFILER environment variables.
Source=Microsoft.QualityTools.Testing.Fakes
StackTrace:
at Microsoft.QualityTools.Testing.Fakes.UnitTestIsolation.IntelliTraceInstrumentationProvider.ResolveProfilerPath()
at Microsoft.QualityTools.Testing.Fakes.UnitTestIsolation.IntelliTraceInstrumentationProvider.Initialize()
at Microsoft.QualityTools.Testing.Fakes.UnitTestIsolation.UnitTestIsolationRuntime.InitializeUnitTestIsolationInstrumentationProvider()
at Microsoft.QualityTools.Testing.Fakes.Shims.ShimRuntime.CreateContext()
at Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create()
at UnitTests.TestRunnerTests.Builders.AppDomainBuilderTests.AppDomainBuilderBuildsAppDomainsWithPermissionStateNone() in c:\VS\UnitTests\TestRunnerTests\Builders\AppDomainBuilderTests.cs:line 130
InnerException:
While trying to run this test, I am able to successfully call the TestInitialise Method, but it throws this exception during the TestMethod which looks like this...
/// <summary>
/// A test to ensure that the Application domain builder builds an
/// application domains with permission state none.
/// </summary>
[TestMethod]
public void AppDomainBuilderBuildsAppDomainsWithPermissionStateNone()
{
// Arrange
using (ShimsContext.Create())
{
bool wasCalledCorrectly = false;
PermissionState expected = PermissionState.None;
ShimPermissionSet.ConstructorPermissionState = (permisionSet, actual) =>
{
if (expected == actual)
{
wasCalledCorrectly = true;
}
};
AppDomainBuilder target = new AppDomainBuilder();
// Act
target.Build(this.defaultInput);
// Assert
Assert.IsTrue(wasCalledCorrectly);
}
}
Having looked into the exception details, it appears to be because the tests can't access the Intellisense Profiler via the environment variables. I was wondering if anybody would have any experience in injecting this object into the AppDomain so that the Fakes can be successfully generated?
Or do I need to include the VSTest.ExecutionEngine in the AppDomain and invoke it somehow?
Any help on shining some light on this would be highly appreciated as being able to support Microsoft.Fakes without having to call out to the VSTest.Console.Exe would be highly desirable.
Thanks

Related

Reflectively call constructor which throws an exception

I'm trying to create an instance of System.RuntimeType which has a very annoying constructor:
internal class RuntimeType
{
internal RuntimeType()
{
throw new NotSupportedException();
}
}
Normally you could just try/catch it and the object will have been constructed, even though the exception was thrown. However, being internal, I have to use reflection to call these, and the exception will get wrapped into a TargetInvocationException and the object thrown away:
System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
----> System.NotSupportedException : Specified method is not supported.
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
at Application.Util.Constructor.RuntimeType() in C:\Work\Application\src\Application\Util\Constructor.cs:line 300
at Tests._4._5.Util.ConstructorTests.RuntimeType() in C:\Work\Application\src\Tests\Tests.4.5\Util\ConstructorTests.cs:line 159
--NotSupportedException
at System.RuntimeType..ctor()
System.RuntimeMethodHandle.InvokeMethod() is marked extern so I can't see how exactly it works to reverse-engineer it without the wrapping. Is there any way to get this type constructed?
The FormatterServices.GetUninitializedObject method can create objects without invoke a constructor:
Return Type: System.Object
A zeroed object of the specified type.
https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject(v=vs.110).aspx

Unit test is failing when ContinueWith is used with System.Threading.Tasks.Task

I am trying to add unit-tests for my code where I am using Task from TPL to update values into a database. For unit-test, I am using NUnit and Moq. Here are some code snippets from my project.
*//service*
public interface IServiceFacade{
Task SynchronizeDataset (string datasetName);
}
*//The method call I want to test*
_ServiceFacade.SynchronizeDataset(DATASET_NAME);
*//In my test, I want to verify if this method is called*
mock_IServicesFacade.Setup(sf => sf.SynchronizeDataset(It.IsAny<string>())).Returns(It.IsAny<Task>());
presenter.InitializeView();
mock_IServicesFacade.Verify(sf => sf.SynchronizeDataset(NSUserUtilStrings.DATASET_ACHIEVEMENT), Times.Once());
This is working. But when I add ContinueWith with the service method call like this...
_ServiceFacade.SynchronizeDataset(DATASET_NAME).ContinueWith(t =>
{
if (t.IsFaulted)
{
//do something
}
});
this test code is not working.Test is failed and it shows this error...
System.NullReferenceException : Object reference not set to an
instance of an object
Stacktrace:
atPresenters.UnitTests.DeviceCategoryPresenterTest.InitializeView_Called
() [0x00241] in DeviceCategoryPresenterTest.cs:56
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke
(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder
binder, System.Object[] parameters, System.Globalization.CultureInfo
culture) [0x00038] in
/private/tmp/source-mono-4.8.0/bockbuild-mono-4.8.0-branch/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/corlib/System.Reflection/MonoMethod.cs:305
and I am not sure how can I fix it. Please help. Thanks in advance.
The fact here is that you are skipping your continuation by passing the valid task instead of It.IsAny<Task>. The one example is to do something like this
.NET < v4.6
mock_IServicesFacade
.Setup(sf => sf.SynchronizeDataset(It.IsAny<string>()))
.Returns(Task.FromResult(true)))
.NET >= v4.6
mock_IServicesFacade
.Setup(sf => sf.SynchronizeDataset(It.IsAny<string>()))
.Returns(Task.CompletedTask))
You can even try to make your continuation with option TaskContinuationOptions.OnlyOnFaulted because you are only interested in IsFaulted scenario.
Be aware that you are not testing continuation part only skipping it. If you really want to test\verify continuation part be careful with it. It seems that your logic is service side logic so there TaskScheduler will use default SynchronizationContext and schedule continuation on the ThreadPool thread. Of course this is executed within unit test runner context which is the same. Basically your tests could finish even before continuation task is executed.
In your setup you set up the function to return null. You already stated this in a comment, It.IsAny<Task>() returns null.
Setup(sf => sf.SynchronizeDataset(It.IsAny<string>()))
.Returns(It.IsAny<Task>());
So if we break this down:
_ServiceFacade.SynchronizeDataset(DATASET_NAME).ContinueWith(t =>
{
if (t.IsFaulted)
{
//do something
}
});
... equals
// This works, but returns null, so testing anything from this point is limited.
var myNullTask = _ServiceFacade.SynchronizeDataset(DATASET_NAME);
myNullTask.ContinueWith(t => ... ); // This yields NullReferenceException
((Task)null).ContinueWith(t => ... ); // Equivalent to line above
Seems like you are writing an integration test which does not apply to your code (if your actual code does assume non-null as return). If this is the case, I suggest changing your setup to something like:
Setup(sf => sf.SynchronizeDataset(It.IsAny<string>()))
.Returns(Task.CompletedTask);

out of memory when repeatedly initializing Clearscript V8 engine (GC issue?)

I have created a basic, default ASP.NET 5 project. I have a controller that creates
var engine = new V8ScriptEngine();
and returns some mock json. When I refresh page certain amount of times I get
Fatal error in heap setup
Allocation failed - process out of memory
And following stack trace
Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at V8Isolate.Create(StdString* , V8IsolateConstraints* , Boolean , Int32 )
at Microsoft.ClearScript.V8.V8IsolateProxyImpl..ctor(String gcName, V8RuntimeConstraints gcConstraints, Boolean enableDebugging, Int32 debugPort)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, Object[] args)
at Microsoft.ClearScript.V8.V8Proxy.CreateImpl[T](Object[] args)
at Microsoft.ClearScript.V8.V8IsolateProxy.Create(String name, V8RuntimeConstraints constraints, Boolean enableDebugging, Int32 debugPort)
at Microsoft.ClearScript.V8.V8Runtime..ctor(String name, V8RuntimeConstraints constraints, V8RuntimeFlags flags, Int32 debugPort)
at Microsoft.ClearScript.V8.V8ScriptEngine..ctor(V8Runtime runtime, String name, V8RuntimeConstraints constraints, V8ScriptEngineFlags flags, Int32 debugPort)
at Microsoft.ClearScript.V8.V8ScriptEngine..ctor()
I tried to look at the memory with dotMemory. Each time I refresh page, an engine is created, and adds like 2MB of ram to unmanaged memory. When it hits certain limit it crashes as explained above. As long as I click force GC before I hit the limit the memory goes down and I can use the page again.
My question is: why does GC not handle this in the first place? After each request the object can be disposed, if I force GC it does. I would asume that if I am almost out of memory but I can reclaim it with GC it would do so.
How can I resolve this? Maybe adding more memory would help but I don't know how to do this either. If GC will never clean those objects it will break anyway.
Same happens when I run Kestrel (dnx web) and with IIS.
I have framework set to "dnx46"
Here is my dnx version
$ dnx --version
Microsoft .NET Execution environment
Version: 1.0.0-rc1-16231
Type: Clr
Architecture: x86
OS Name: Windows
OS Version: 10.0
Runtime Id: win10-x86
ClearScript version is "ClearScript.V8": "5.4.3"
The short version: You need to dispose each script engine when you're done with it. A convenient way is to use the using statement:
using (var engine = new V8ScriptEngine()) {
// do stuff
}
Longer version: Each V8 instance reserves a large block of address space. These don't show up as used memory, but in a 32-bit process you can run out of address space with just a few dozen instances. The managed GC would eventually clean it all up, but because it can't track V8's address space reservations, it's in no hurry to do so, since it doesn't detect any memory pressure. Eventually you get to a point where your memory usage is still low, but V8 can no longer reserve a large-enough block of address space, and so it fails.

Simple injector: Registering a dynamically created delegate

The Goal:
I am trying to dynamically register delegates for creating objects in simple injector container. Basically I want to be able not only to get actual instances from DI container but also a methods that could be used to create those instances. This could be useful for lazy object creation. For example if I have a service with a lot of dependencies, I don't want them to be created on service object creation but only when those specific dependencies need to be used.
The Problem:
When I usecontainer.Register<T> method I can successfully register delegates:
container.Register<Func<IRepository>>(() => container.GetInstance<IRepository>);
The problem is when I want to register those kind of delegates dynamically when the type is known only at runtime:
Here is my code:
private static void RegisterFunctions(Container container)
{
var types = container.GetCurrentRegistrations()
.Where(r => r.ServiceType.IsInterface && r.ServiceType != typeof(Func<>))
.Select(r => r.ServiceType);
var typesList = types as IList<Type> ?? types.ToList();
foreach (var t in typesList)
{
var typeToRegister = typeof(Func<>).MakeGenericType(t);
//This needs to be replaced:
container.Register(typeToRegister, () => container.GetInstance(t));
}
}
The problem is in container.Register(typeToRegister, () => container.GetInstance(t)); I assumed that it's behavior will be the same as container.Register<T> method but I was wrong.
When I run this code for the following scenario:
public interface IProductService
{
}
public class ProductService : IProductService
{
public ProductService(Func<IProductRepository> getRepositoryFunc)
{
this.ProductRepositoryFunc = getRepositoryFunc;
}
}
I am getting an System.InvalidCastException:
[InvalidCastException: Unable to cast object of type 'XXX.ProductRepository' to type
'System.Func'1[XXX.IProductRepository]'.]
lambda_method(Closure ) +83
lambda_method(Closure ) +179
SimpleInjector.Scope.CreateAndCacheInstance(ScopedRegistration'2
registration) +74
SimpleInjector.Scope.GetInstance(ScopedRegistration'2 registration)
+260 SimpleInjector.Scope.GetInstance(ScopedRegistration'2 registration, Scope scope) +207
SimpleInjector.Advanced.Internal.LazyScopedRegistration'2.GetInstance(Scope
scope) +241 lambda_method(Closure ) +310
SimpleInjector.InstanceProducer.GetInstance() +117
[ActivationException: The registered delegate for type
ProductController threw an exception. Unable to cast object
of type 'XXX.ProductRepository' to type
'System.Func'1[XXX.IProductRepository]'.]
SimpleInjector.InstanceProducer.GetInstance() +222
SimpleInjector.Container.GetInstance(Type serviceType) +148
SimpleInjector.Integration.Web.Mvc.SimpleInjectorDependencyResolver.GetService(Type
serviceType) +137
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext
requestContext, Type controllerType) +87
[InvalidOperationException: An error occurred when trying to create a
controller of type
'YYY.ProductController'.
Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext
requestContext, Type controllerType) +247
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext
requestContext, Type controllerType) +438
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext
requestContext, String controllerName) +257
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase
httpContext, IController& controller, IControllerFactory& factory)
+326 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +157
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext,
AsyncCallback callback, Object state) +88
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext
context, AsyncCallback cb, Object extraData) +50
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
+301 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
I understand the exception and the issue that causes it but I am struggling to find a correct way to implement the described functionality.
So if I summarize my question:
Is there a way to perform a registration similar to:
container.Register<Func<IRepository>>(() => container.GetInstance<IRepository>)
for a dynamic type that that resolved in runtime, something like
container.Register<Func<T>>(() => container.GetInstance<T>)
The problem here is that you are using the wrong Register overload. You do this:
container.Register(typeToRegister, () => container.GetInstance(t));
Because of the way C# overload resolution works, the following overload is selected:
Register(Type serviceType, Func<object> instanceCreator)
This overload however, expects that the returned value from the supplied Func<object> is of type serviceType. But this is not the case in your case, because you want to register the delegate itself. There are a few ways to solve this.
For instance, you can supply this overload with a Func<object> that returns the actual delegate as follows:
Func<object> func = () => container.GetInstance(t);
container.Register(typeToRegister, () => func);
But since the delegate that you register itself is a singleton, it's better to do it as follows:
Func<object> func = () => container.GetInstance(t);
container.RegisterSingleton(typeToRegister, () => func);
This is better, because this prevents the Diagnostic Services from reporting Lifestyle Mismatches on the consumers of your Func<T> registrations.
But since all you want to do is register a single instance (the delegate), you can also use the RegisterSingleton(Type, object) overload as follows:
Func<object> func = () => container.GetInstance(t);
container.RegisterSingleton(typeToRegister, (object)func);
The effect is the same, but this is a bit cleaner IMO.
Do note however that none of the given solutions actually work. They don't work because we're constructing a Func<object>, while trying to register a Func<SomethingElse>, and a Func<object> can't be casted and this will cause either the registration to fail, or the application to fail when resolving or injecting such instance.
So the real solution is to construct the exact Func<T> type and register that. And this is exactly what the example in the example in the register factory delegates section of the documentation does:
container.ResolveUnregisteredType += (s, e) =>
{
var type = e.UnregisteredServiceType;
if (!type.IsGenericType ||
type.GetGenericTypeDefinition() != typeof(Func<>))
return;
Type serviceType = type.GetGenericArguments().First();
InstanceProducer producer = container.GetRegistration(serviceType, true);
Type funcType = typeof(Func<>).MakeGenericType(serviceType);
var factoryDelegate =
Expression.Lambda(funcType, producer.BuildExpression()).Compile();
e.Register(Expression.Constant(factoryDelegate));
};
Here unregistered type resolution is used to build Func<T> delegates on the fly in the background. The effect is about the same as what you are doing with the manual calls to Register, but the behaviour is more deterministic, because your RegisterFunctions must be called last before all other registrations, while the timing for this method does not matter. It also prevents your DI configuration to be 'polluted' with Func<T> registrations that are never used. This makes it somewhat easier to browse through the registrations and see how your real configuration looks like.
This all said though, the following worries me:
For example if I have a service with a lot of dependencies, I don't
want them to be created on service object creation but only when those
specific dependencies need to be used.
Even a moderately fast container, will be able to build up object graphs at a speed that the size of the object graph should hardly ever be a problem. Simple Injector on the other hand is extremely fast. Delaying the building of part of your object graph using Func<T> for performance is useless and only pollutes your code base. Using a Func<T> as abstraction is in a sense a Leaky Abstraction (a violation of the Dependency Inversion Principle), because the dependency now tells the consumer something about the implementation; that it is heavy to create. But this is an implementation detail and the consumer should not be bottered with that. It makes code harder to read, and the consumer harder to test.
If however you have trouble with the time it takes to construct object graphs, there might be a problem in your application. Injection constructors should be simple and fast. Letting a constructor do more than just storing the incoming dependencies is violation of the SRP.
It's because of this that Simple Injector does not build Func<T> delegates for you out of the box.

Windows Forms Threads are losing their culture

We have a .net 3.5 multi-threaded windows forms application. Is is launching 4-5 background workers/ async calls to retrieve data. About 1 in 10 times, one of the threads throws the following error. Sometimes the error is a null exception instead but the same exact call stack. We have tracked the issue down to the thread somehow losing its CultureInfo. Anyone else ran into this?
System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
at System.Globalization.CultureTableRecord.GetCultureTableRecord(String name, Boolean useUserOverride)
at System.Globalization.CultureTableRecord.GetCultureTableRecord(Int32 cultureId, Boolean useUserOverride)
at System.Globalization.CultureInfo..ctor(Int32 culture, Boolean useUserOverride)
at System.Globalization.CultureInfo.GetCultureByLCIDOrName(Int32 preferLCID, String fallbackToString)
at System.Globalization.CultureInfo.InitUserDefaultUICulture()
at System.Globalization.CultureInfo.get_UserDefaultUICulture()
at System.Threading.Thread.get_CurrentUICulture()
at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
at System.Environment.ResourceHelper.GetResourceStringCode(Object userDataIn)
at System.Environment.GetResourceFromDefault(String key)
at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat)
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.IO.StreamWriter.Init(Stream stream, Encoding encoding, Int32 bufferSize)
at System.IO.StreamWriter..ctor(Stream stream, Encoding encoding, Int32 bufferSize)
at System.Web.Services.Protocols.SoapHttpClientProtocol.GetWriterForMessage(SoapClientMessage message, Int32 bufferSize)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Serialize(SoapClientMessage message)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
Try playing with default culture for entire domain using CultureInfo.DefaultThreadCurrentCulture and/or CultureInfo.DefaultThreadCurrentUICulture and see if that helps. All in all, you'll be able to ensure whether it's related to thread's culture
UPD: that specific exception may be thrown when using sync methods like lock, Monitor, etc on value types, calls to sync methods will box value, creating new one every time. I doubt it could be such serios bug in framework.
Can you check your synchronization code?
UPD2: ok, let's try to debug.
First off, turn on break on every exception thrown
Next, enable .NET Framework debugging that will help you to
locate an error
After that, there is a high chance for a workaround/solution for you problem
From just looking at the call stack, this appears to be a framework bug (of sorts). It seems that the StreamWriter constructor is performing a non-thread-safe operation (accessing GetCultureTableRecord) through a complex series of calls. My recommendation would be to serialize your calls to the StreamWriter constructor:
// Put this somewhere convenient
public static Object swConstructorLock = new Object();
then, when you create your StreamWriters:
// Lock this constructor because it does something that isnt thread-safe as per http://stackoverflow.com/questions/16113366/windows-forms-threads-are-losing-their-culture
StreamWriter myStreamWriter;
lock (swConstructorLock) {
myStreamWriter = new StreamWriter(theStreamToWrite);
}
I found that CultureInfo.ClearCachedData was being called on every web request :/ Removing that fixed the issue. There seems that Culture still needs some sort of lock since thread A calls ClearCachedData and thread B requests the data and it throws a null exception.
I got this exception (once, out of a blue), also in a .NET 3.5 app:
System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
at System.Globalization.CultureTableRecord.GetCultureTableRecord(String name, Boolean useUserOverride)
at System.Globalization.CultureTableRecord.GetCultureTableRecord(Int32 cultureId, Boolean useUserOverride)
at System.Globalization.CultureInfo..ctor(Int32 culture, Boolean useUserOverride)
at System.Globalization.CultureInfo.GetCultureByLCIDOrName(Int32 preferLCID, String fallbackToString)
at System.Globalization.CultureInfo.InitUserDefaultCulture()
at System.Globalization.CultureInfo.get_UserDefaultCulture()
at System.Threading.Thread.get_CurrentCulture()
at System.Globalization.DateTimeFormatInfo.get_CurrentInfo()
at System.DateTime.ToString(String format)
This happened in a locked section, but the lock was not a value type.

Categories

Resources