Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions Telerik.JustMock/Core/Context/MSTestBaseMockingContextResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
JustMock Lite
Copyright © 2010-2015 Progress Software Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

using System;
using System.Threading;

namespace Telerik.JustMock.Core.Context
{
internal abstract class MSTestBaseMockingContextResolver : HierarchicalTestFrameworkContextResolver
{
protected MSTestBaseMockingContextResolver(string assertionFailedName, string assemblyName)
: base(assertionFailedName)
{
this.SetupStandardHierarchicalTestStructure(
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute, " + assemblyName },
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute, " + assemblyName, "Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute, " + assemblyName },
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.ClassInitializeAttribute, " + assemblyName, "Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute, " + assemblyName },
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyInitializeAttribute, " + assemblyName, "Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyCleanupAttribute, " + assemblyName },
FixtureConstuctorSemantics.InstanceConstructorCalledOncePerFixture);
}

#if !SILVERLIGHT
private const int DefaultGcFrequency = 50;
private int createdRepoCount;
private int lastGcCount;
private int gcFrequency = GetGcFrequency();
private bool synchronousGc = GetSynchronousGc();

private static int GetGcFrequency()
{
var valueStr = SecuredRegistryMethods.GetValue(false, @"Software\Telerik\JustMock", "MSTestGcFrequency");
int value;
if (!String.IsNullOrEmpty(valueStr) && int.TryParse(valueStr, out value) && value >= 1)
return value;

return DefaultGcFrequency;
}

private static bool GetSynchronousGc()
{
var valueStr = SecuredRegistryMethods.GetValue(false, @"Software\Telerik\JustMock", "SynchronousGc");
int value;
return !String.IsNullOrEmpty(valueStr) && int.TryParse(valueStr, out value) && value == 1;
}

protected override void OnMocksRepositoryCreated(MocksRepository repo)
{
// MSTest runs every test in a different thread. We'd like to collect Thread objects often so that their handle is released.
// At every N created repos (we assume that each test creates a single repo, so the number of repos created is close to
// the number of threads created) do a garbage collection, but only if it hasn't been already done in this interval.

createdRepoCount++;

if (createdRepoCount % gcFrequency == 0)
{
var gen2Collections = GC.CollectionCount(GC.MaxGeneration);
if (gen2Collections == lastGcCount)
{
if (synchronousGc)
{
GC.Collect();
}
else
{
ThreadPool.QueueUserWorkItem(_ => GC.Collect());
}

gen2Collections++;
}
lastGcCount = gen2Collections;
}
}
#endif
}
}
63 changes: 2 additions & 61 deletions Telerik.JustMock/Core/Context/MSTestMockingContextResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ limitations under the License.

namespace Telerik.JustMock.Core.Context
{
internal class MSTestMockingContextResolver : HierarchicalTestFrameworkContextResolver
internal class MSTestMockingContextResolver : MSTestBaseMockingContextResolver
{
#if SILVERLIGHT
private const string MstestAssemblyName = "Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight";
Expand All @@ -32,72 +32,13 @@ internal class MSTestMockingContextResolver : HierarchicalTestFrameworkContextRe
private const string MstestAssertionFailedName = "Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException, " + MstestAssemblyName;

public MSTestMockingContextResolver()
: base(MstestAssertionFailedName)
: base(MstestAssertionFailedName, MstestAssemblyName)
{
this.SetupStandardHierarchicalTestStructure(
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute, " + MstestAssemblyName },
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute, " + MstestAssemblyName, "Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute, " + MstestAssemblyName },
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.ClassInitializeAttribute, " + MstestAssemblyName, "Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute, " + MstestAssemblyName },
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyInitializeAttribute, " + MstestAssemblyName, "Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyCleanupAttribute, " + MstestAssemblyName },
FixtureConstuctorSemantics.InstanceConstructorCalledOncePerFixture);
}

public static bool IsAvailable
{
get { return FindType(MstestAssertionFailedName, false) != null; }
}

#if !SILVERLIGHT
private const int DefaultGcFrequency = 50;
private int createdRepoCount;
private int lastGcCount;
private int gcFrequency = GetGcFrequency();
private bool synchronousGc = GetSynchronousGc();

private static int GetGcFrequency()
{
var valueStr = SecuredRegistryMethods.GetValue(false, @"Software\Telerik\JustMock", "MSTestGcFrequency");
int value;
if (!String.IsNullOrEmpty(valueStr) && int.TryParse(valueStr, out value) && value >= 1)
return value;

return DefaultGcFrequency;
}

private static bool GetSynchronousGc()
{
var valueStr = SecuredRegistryMethods.GetValue(false, @"Software\Telerik\JustMock", "SynchronousGc");
int value;
return !String.IsNullOrEmpty(valueStr) && int.TryParse(valueStr, out value) && value == 1;
}

protected override void OnMocksRepositoryCreated(MocksRepository repo)
{
// MSTest runs every test in a different thread. We'd like to collect Thread objects often so that their handle is released.
// At every N created repos (we assume that each test creates a single repo, so the number of repos created is close to
// the number of threads created) do a garbage collection, but only if it hasn't been already done in this interval.

createdRepoCount++;

if (createdRepoCount % gcFrequency == 0)
{
var gen2Collections = GC.CollectionCount(GC.MaxGeneration);
if (gen2Collections == lastGcCount)
{
if (synchronousGc)
{
GC.Collect();
}
else
{
ThreadPool.QueueUserWorkItem(_ => GC.Collect());
}

gen2Collections++;
}
lastGcCount = gen2Collections;
}
}
#endif
}
}
63 changes: 2 additions & 61 deletions Telerik.JustMock/Core/Context/MSTestV2MockingContextResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,78 +20,19 @@ limitations under the License.

namespace Telerik.JustMock.Core.Context
{
internal class MSTestV2MockingContextResolver : HierarchicalTestFrameworkContextResolver
internal class MSTestV2MockingContextResolver : MSTestBaseMockingContextResolver
{
private const string Mstestv2AssemblyName = "Microsoft.VisualStudio.TestPlatform.TestFramework";
private const string Mstestv2AssertionFailedName = "Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException, " + Mstestv2AssemblyName;

public MSTestV2MockingContextResolver()
: base(Mstestv2AssertionFailedName)
: base(Mstestv2AssertionFailedName, Mstestv2AssemblyName)
{
this.SetupStandardHierarchicalTestStructure(
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute, " + Mstestv2AssemblyName },
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute, " + Mstestv2AssemblyName, "Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute, " + Mstestv2AssemblyName },
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.ClassInitializeAttribute, " + Mstestv2AssemblyName, "Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute, " + Mstestv2AssemblyName },
new[] { "Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyInitializeAttribute, " + Mstestv2AssemblyName, "Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyCleanupAttribute, " + Mstestv2AssemblyName },
FixtureConstuctorSemantics.InstanceConstructorCalledOncePerFixture);
}

public static bool IsAvailable
{
get { return FindType(Mstestv2AssertionFailedName, false) != null; }
}

private const int DefaultGcFrequency = 50;
private int createdRepoCount;
private int lastGcCount;
private int gcFrequency = GetGcFrequency();
private bool synchronousGc = GetSynchronousGc();

private static int GetGcFrequency()
{
var valueStr = SecuredRegistryMethods.GetValue(false, @"Software\Telerik\JustMock", "MSTestGcFrequency");
int value;
if (!String.IsNullOrEmpty(valueStr) && int.TryParse(valueStr, out value) && value >= 1)
return value;

return DefaultGcFrequency;
}

private static bool GetSynchronousGc()
{
var valueStr = SecuredRegistryMethods.GetValue(false, @"Software\Telerik\JustMock", "SynchronousGc");
int value;
return !String.IsNullOrEmpty(valueStr) && int.TryParse(valueStr, out value) && value == 1;
}

#if !SILVERLIGHT
protected override void OnMocksRepositoryCreated(MocksRepository repo)
{
// MSTest runs every test in a different thread. We'd like to collect Thread objects often so that their handle is released.
// At every N created repos (we assume that each test creates a single repo, so the number of repos created is close to
// the number of threads created) do a garbage collection, but only if it hasn't been already done in this interval.

createdRepoCount++;

if (createdRepoCount % gcFrequency == 0)
{
var gen2Collections = GC.CollectionCount(GC.MaxGeneration);
if (gen2Collections == lastGcCount)
{
if (synchronousGc)
{
GC.Collect();
}
else
{
ThreadPool.QueueUserWorkItem(_ => GC.Collect());
}

gen2Collections++;
}
lastGcCount = gen2Collections;
}
}
#endif
}
}
21 changes: 21 additions & 0 deletions Telerik.JustMock/Core/Context/MSTestV4MockingContextResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Threading;

namespace Telerik.JustMock.Core.Context
{
internal class MSTestV4MockingContextResolver : MSTestBaseMockingContextResolver
{
private const string Mstestv4AssemblyName = "MSTest.TestFramework";
private const string Mstestv4AssertionFailedName = "Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException, " + Mstestv4AssemblyName;

public MSTestV4MockingContextResolver()
: base(Mstestv4AssertionFailedName, Mstestv4AssemblyName)
{
}

public static bool IsAvailable
{
get { return FindType(Mstestv4AssertionFailedName, false) != null; }
}
}
}
2 changes: 2 additions & 0 deletions Telerik.JustMock/Core/Context/MockingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ static MockingContext()
registeredContextResolvers.Add(new MSTestMockingContextResolver());
if (MSTestV2MockingContextResolver.IsAvailable)
registeredContextResolvers.Add(new MSTestV2MockingContextResolver());
if (MSTestV4MockingContextResolver.IsAvailable)
registeredContextResolvers.Add(new MSTestV4MockingContextResolver());
#endif

foreach (var resolver in registeredContextResolvers)
Expand Down