mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 19:04:51 +08:00
Fix unit test memory leak
Shutdown ASP.NET AppDomains after running each SpecFlow scenario. --HG-- branch : dev
This commit is contained in:
@@ -14,10 +14,10 @@ using HtmlAgilityPack;
|
||||
using log4net.Appender;
|
||||
using log4net.Core;
|
||||
using log4net.Repository;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Specs.Hosting;
|
||||
using Orchard.Specs.Util;
|
||||
using TechTalk.SpecFlow;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Orchard.Specs.Bindings {
|
||||
[Binding]
|
||||
@@ -27,6 +27,9 @@ namespace Orchard.Specs.Bindings {
|
||||
private HtmlDocument _doc;
|
||||
private MessageSink _messages;
|
||||
|
||||
public WebAppHosting() {
|
||||
}
|
||||
|
||||
public WebHost Host {
|
||||
get { return _webHost; }
|
||||
}
|
||||
@@ -36,6 +39,14 @@ namespace Orchard.Specs.Bindings {
|
||||
set { _details = value; }
|
||||
}
|
||||
|
||||
[AfterScenario]
|
||||
public void AfterScenario() {
|
||||
if (_webHost != null) {
|
||||
_webHost.Dispose();
|
||||
_webHost = null;
|
||||
}
|
||||
}
|
||||
|
||||
[Given(@"I have a clean site")]
|
||||
public void GivenIHaveACleanSite() {
|
||||
GivenIHaveACleanSiteBasedOn("Orchard.Web");
|
||||
|
@@ -44,6 +44,13 @@ namespace Orchard.Specs.Hosting {
|
||||
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
if (_webHostAgent != null) {
|
||||
_webHostAgent.Shutdown();
|
||||
_webHostAgent = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyExtension(string extensionFolder, string extensionName) {
|
||||
var sourceModule = _orchardWebPath.Combine(extensionFolder).Combine(extensionName);
|
||||
var targetModule = _tempSite.Combine(extensionFolder).Combine(extensionName);
|
||||
@@ -73,6 +80,5 @@ namespace Orchard.Specs.Hosting {
|
||||
fieldInfo.SetValue(to, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Web.Hosting;
|
||||
|
||||
namespace Orchard.Specs.Hosting {
|
||||
public class WebHostAgent : MarshalByRefObject
|
||||
@@ -8,5 +9,9 @@ namespace Orchard.Specs.Hosting {
|
||||
shuttle.Delegate();
|
||||
return shuttle;
|
||||
}
|
||||
|
||||
public void Shutdown() {
|
||||
HostingEnvironment.InitiateShutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -284,9 +284,6 @@
|
||||
<Name>Orchard</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WCFMetadata Include="Service References\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Hosting\Simple.Web\Content\Static.txt">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
|
11
src/Tools/Orchard/ApplicationObject.cs
Normal file
11
src/Tools/Orchard/ApplicationObject.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Orchard {
|
||||
public class ApplicationObject {
|
||||
public string ApplicationId { get; set; }
|
||||
public object ObjectInstance { get; set; }
|
||||
}
|
||||
}
|
@@ -18,7 +18,7 @@ namespace Orchard.Host {
|
||||
}
|
||||
|
||||
public void Stop(bool immediate) {
|
||||
//TODO
|
||||
HostingEnvironment.UnregisterObject(this);
|
||||
}
|
||||
|
||||
public int RunCommand(TextReader input, TextWriter output, Logger logger, OrchardParameters args) {
|
||||
|
@@ -71,6 +71,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ApplicationObject.cs" />
|
||||
<Compile Include="Logger.cs" />
|
||||
<Compile Include="OrchardHost.cs" />
|
||||
<Compile Include="Parameters\ICommandParametersParser.cs" />
|
||||
@@ -104,7 +105,9 @@
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="app.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
@@ -7,6 +7,7 @@ using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using Orchard.Host;
|
||||
using Orchard.Parameters;
|
||||
using System.Threading;
|
||||
|
||||
namespace Orchard {
|
||||
class OrchardHost {
|
||||
@@ -77,13 +78,23 @@ namespace Orchard {
|
||||
var orchardDirectory = GetOrchardDirectory(_arguments.WorkingDirectory);
|
||||
LogInfo("Orchard root directory: \"{0}\"", orchardDirectory.FullName);
|
||||
|
||||
return CreateHostAndExecute(orchardDirectory);
|
||||
}
|
||||
|
||||
private int CreateHostAndExecute(DirectoryInfo orchardDirectory) {
|
||||
var appManager = ApplicationManager.GetApplicationManager();
|
||||
|
||||
LogInfo("Creating ASP.NET AppDomain for command agent...");
|
||||
var host = (CommandHost)CreateWorkerAppDomainWithHost(_arguments.VirtualPath, orchardDirectory.FullName, typeof(CommandHost));
|
||||
var appObject = CreateWorkerAppDomainWithHost(appManager, _arguments.VirtualPath, orchardDirectory.FullName, typeof(CommandHost));
|
||||
var host = (CommandHost)appObject.ObjectInstance;
|
||||
|
||||
LogInfo("Executing command in ASP.NET AppDomain...");
|
||||
var result = Execute(host);
|
||||
LogInfo("Return code for command: {0}", result);
|
||||
|
||||
LogInfo("Shutting down ASP.NET AppDomain...");
|
||||
appManager.ShutdownApplication(appObject.ApplicationId);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -182,14 +193,13 @@ namespace Orchard {
|
||||
string.Format("Directory \"{0}\" doesn't seem to contain an Orchard installation", new DirectoryInfo(directory).FullName));
|
||||
}
|
||||
|
||||
private static object CreateWorkerAppDomainWithHost(string virtualPath, string physicalPath, Type hostType) {
|
||||
private static ApplicationObject CreateWorkerAppDomainWithHost(ApplicationManager appManager, string virtualPath, string physicalPath, Type hostType) {
|
||||
// this creates worker app domain in a way that host doesn't need to be in GAC or bin
|
||||
// using BuildManagerHost via private reflection
|
||||
string uniqueAppString = string.Concat(virtualPath, physicalPath).ToLowerInvariant();
|
||||
string appId = (uniqueAppString.GetHashCode()).ToString("x", CultureInfo.InvariantCulture);
|
||||
|
||||
// create BuildManagerHost in the worker app domain
|
||||
var appManager = ApplicationManager.GetApplicationManager();
|
||||
var buildManagerHostType = typeof(HttpRuntime).Assembly.GetType("System.Web.Compilation.BuildManagerHost");
|
||||
var buildManagerHost = appManager.CreateObject(appId, buildManagerHostType, virtualPath, physicalPath, false);
|
||||
|
||||
@@ -202,7 +212,9 @@ namespace Orchard {
|
||||
new object[] { hostType.Assembly.FullName, hostType.Assembly.Location });
|
||||
|
||||
// create Host in the worker app domain
|
||||
return appManager.CreateObject(appId, hostType, virtualPath, physicalPath, false);
|
||||
return new ApplicationObject {
|
||||
ApplicationId = appId,
|
||||
ObjectInstance = appManager.CreateObject(appId, hostType, virtualPath, physicalPath, false) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user