From 8535d0fbe3e60f1a709523873b34299725196e42 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 31 Mar 2020 17:27:51 +1100 Subject: [PATCH 1/3] Cleans up IIOHelper and removes methods/props that shouldn't exist, changes test helper to use WorkingDirectory fixes some usages of MapPath --- .../Legacy/GlobalSettings.cs | 2 +- src/Umbraco.Core/AssemblyExtensions.cs | 29 +++++++ .../Configuration/XmlConfigManipulator.cs | 6 +- src/Umbraco.Core/IO/IIOHelper.cs | 24 +---- src/Umbraco.Core/IO/IOHelper.cs | 87 ++----------------- src/Umbraco.Core/IO/PhysicalFileSystem.cs | 2 +- .../CompositionExtensions/Services.cs | 6 +- .../Migrations/Install/DatabaseBuilder.cs | 13 +-- .../Packaging/PackageInstallation.cs | 14 ++- .../Runtime/CoreRuntime.cs | 12 ++- src/Umbraco.Tests.Common/TestHelperBase.cs | 28 +++--- .../ApplicationBuilderExtensions.cs | 8 +- .../Implementations/TestHelper.cs | 25 +++--- .../Implementations/TestHostingEnvironment.cs | 3 +- .../Testing/UmbracoIntegrationTest.cs | 2 +- .../UmbracoSettings/UmbracoSettingsTests.cs | 2 +- .../Packaging/PackageExtractionTests.cs | 4 +- .../Packaging/PackageInstallationTest.cs | 24 ++--- .../Persistence/DatabaseContextTests.cs | 2 +- src/Umbraco.Tests/TestHelpers/TestHelper.cs | 13 +-- src/Umbraco.Tests/TestHelpers/TestObjects.cs | 15 ++-- .../TestHelpers/TestWithDatabaseBase.cs | 11 +-- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 2 +- .../UmbracoExamine/ExamineBaseTest.cs | 3 +- .../AuthenticationControllerTests.cs | 2 +- .../AspNetCoreHostingEnvironment.cs | 4 +- .../AspNet/AspNetHostingEnvironment.cs | 4 +- 27 files changed, 154 insertions(+), 193 deletions(-) diff --git a/src/Umbraco.Configuration/Legacy/GlobalSettings.cs b/src/Umbraco.Configuration/Legacy/GlobalSettings.cs index 78036f9e42..cb3fd9cf47 100644 --- a/src/Umbraco.Configuration/Legacy/GlobalSettings.cs +++ b/src/Umbraco.Configuration/Legacy/GlobalSettings.cs @@ -177,7 +177,7 @@ namespace Umbraco.Core.Configuration.Legacy /// Value of the setting to be saved. internal static void SaveSetting(string key, string value, IIOHelper ioHelper) { - var fileName = ioHelper.MapPath(string.Format("{0}/web.config", ioHelper.Root)); + var fileName = ioHelper.MapPath("~/web.config"); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single(); diff --git a/src/Umbraco.Core/AssemblyExtensions.cs b/src/Umbraco.Core/AssemblyExtensions.cs index 0d0115ce20..19162e5934 100644 --- a/src/Umbraco.Core/AssemblyExtensions.cs +++ b/src/Umbraco.Core/AssemblyExtensions.cs @@ -6,6 +6,35 @@ namespace Umbraco.Core { public static class AssemblyExtensions { + private static string _rootDir = ""; + + /// + /// Utility method that returns the path to the root of the application, by getting the path to where the assembly where this + /// method is included is present, then traversing until it's past the /bin directory. Ie. this makes it work + /// even if the assembly is in a /bin/debug or /bin/release folder + /// + /// + public static string GetRootDirectorySafe(this Assembly executingAssembly) + { + if (string.IsNullOrEmpty(_rootDir) == false) + { + return _rootDir; + } + + var codeBase = executingAssembly.CodeBase; + var uri = new Uri(codeBase); + var path = uri.LocalPath; + var baseDirectory = Path.GetDirectoryName(path); + if (string.IsNullOrEmpty(baseDirectory)) + throw new Exception("No root directory could be resolved. Please ensure that your Umbraco solution is correctly configured."); + + _rootDir = baseDirectory.Contains("bin") + ? baseDirectory.Substring(0, baseDirectory.LastIndexOf("bin", StringComparison.OrdinalIgnoreCase) - 1) + : baseDirectory; + + return _rootDir; + } + /// /// Returns the file used to load the assembly /// diff --git a/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs b/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs index 333f9dc6f9..af2c58f83d 100644 --- a/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs +++ b/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs @@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration public void RemoveConnectionString() { var key = Constants.System.UmbracoConnectionName; - var fileName = _ioHelper.MapPath(string.Format("{0}/web.config", _ioHelper.Root)); + var fileName = _ioHelper.MapPath("~/web.config"); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single(); @@ -58,7 +58,7 @@ namespace Umbraco.Core.Configuration var fileSource = "web.config"; - var fileName = _ioHelper.MapPath(_ioHelper.Root + "/" + fileSource); + var fileName = _ioHelper.MapPath("~/" + fileSource); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root)."); @@ -71,7 +71,7 @@ namespace Umbraco.Core.Configuration if (configSourceAttribute != null) { fileSource = configSourceAttribute.Value; - fileName = _ioHelper.MapPath(_ioHelper.Root + "/" + fileSource); + fileName = _ioHelper.MapPath("~/" + fileSource); if (!File.Exists(fileName)) throw new Exception($"Invalid configSource \"{fileSource}\" (no such file)."); diff --git a/src/Umbraco.Core/IO/IIOHelper.cs b/src/Umbraco.Core/IO/IIOHelper.cs index f478b49de6..17ad20826b 100644 --- a/src/Umbraco.Core/IO/IIOHelper.cs +++ b/src/Umbraco.Core/IO/IIOHelper.cs @@ -7,8 +7,6 @@ namespace Umbraco.Core.IO string BackOfficePath { get; } - bool ForceNotHosted { get; set; } - char DirSepChar { get; } string FindFile(string virtualPath); string ResolveVirtualUrl(string path); @@ -43,24 +41,6 @@ namespace Umbraco.Core.IO bool PathStartsWith(string path, string root, char separator); - /// - /// Returns the path to the root of the application, by getting the path to where the assembly where this - /// method is included is present, then traversing until it's past the /bin directory. Ie. this makes it work - /// even if the assembly is in a /bin/debug or /bin/release folder - /// - /// - string GetRootDirectorySafe(); - - string GetRootDirectoryBinFolder(); - - /// - /// Allows you to overwrite RootDirectory, which would otherwise be resolved - /// automatically upon application start. - /// - /// The supplied path should be the absolute path to the root of the umbraco site. - /// - void SetRootDirectory(string rootPath); - void EnsurePathExists(string path); /// @@ -73,6 +53,10 @@ namespace Umbraco.Core.IO /// /// Gets the root path of the application /// + /// + /// In most cases this will be an empty string which indicates the app is not running in a virtual directory. + /// This is NOT a physical path. + /// string Root { get; diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs index 9eddea6477..b68c58e91d 100644 --- a/src/Umbraco.Core/IO/IOHelper.cs +++ b/src/Umbraco.Core/IO/IOHelper.cs @@ -31,13 +31,6 @@ namespace Umbraco.Core.IO } } - /// - /// Gets or sets a value forcing Umbraco to consider it is non-hosted. - /// - /// This should always be false, unless unit testing. - public bool ForceNotHosted { get; set; } - - private static string _rootDir = ""; // static compiled regex for faster performance //private static readonly Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); @@ -113,13 +106,9 @@ namespace Umbraco.Core.IO : _hostingEnvironment.MapPath("~/" + path.TrimStart('/')); if (result != null) return result; - - } - - - var root = GetRootDirectorySafe(); + var root = Assembly.GetExecutingAssembly().GetRootDirectorySafe(); var newPath = path.TrimStart('~', '/').Replace('/', DirSepChar); var retval = root + DirSepChar.ToString(CultureInfo.InvariantCulture) + newPath; @@ -199,71 +188,6 @@ namespace Umbraco.Core.IO return path[root.Length] == separator; } - /// - /// Returns the path to the root of the application, by getting the path to where the assembly where this - /// method is included is present, then traversing until it's past the /bin directory. Ie. this makes it work - /// even if the assembly is in a /bin/debug or /bin/release folder - /// - /// - public string GetRootDirectorySafe() - { - if (String.IsNullOrEmpty(_rootDir) == false) - { - return _rootDir; - } - - var codeBase = Assembly.GetExecutingAssembly().CodeBase; - var uri = new Uri(codeBase); - var path = uri.LocalPath; - var baseDirectory = Path.GetDirectoryName(path); - if (String.IsNullOrEmpty(baseDirectory)) - throw new Exception("No root directory could be resolved. Please ensure that your Umbraco solution is correctly configured."); - - _rootDir = baseDirectory.Contains("bin") - ? baseDirectory.Substring(0, baseDirectory.LastIndexOf("bin", StringComparison.OrdinalIgnoreCase) - 1) - : baseDirectory; - - return _rootDir; - } - - public string GetRootDirectoryBinFolder() - { - string binFolder = String.Empty; - if (String.IsNullOrEmpty(_rootDir)) - { - binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory.FullName; - return binFolder; - } - - binFolder = Path.Combine(GetRootDirectorySafe(), "bin"); - - // do this all the time (no #if DEBUG) because Umbraco release - // can be used in tests by an app (eg Deploy) being debugged - var debugFolder = Path.Combine(binFolder, "debug"); - if (Directory.Exists(debugFolder)) - return debugFolder; - - var releaseFolder = Path.Combine(binFolder, "release"); - if (Directory.Exists(releaseFolder)) - return releaseFolder; - - if (Directory.Exists(binFolder)) - return binFolder; - - return _rootDir; - } - - /// - /// Allows you to overwrite RootDirectory, which would otherwise be resolved - /// automatically upon application start. - /// - /// The supplied path should be the absolute path to the root of the umbraco site. - /// - public void SetRootDirectory(string rootPath) - { - _rootDir = rootPath; - } - public void EnsurePathExists(string path) { var absolutePath = MapPath(path); @@ -280,7 +204,7 @@ namespace Umbraco.Core.IO { if (path.IsFullPath()) { - var rootDirectory = GetRootDirectorySafe(); + var rootDirectory = MapPath("~"); var relativePath = path.ToLowerInvariant().Replace(rootDirectory.ToLowerInvariant(), string.Empty); path = relativePath; } @@ -293,6 +217,10 @@ namespace Umbraco.Core.IO /// /// Gets the root path of the application /// + /// + /// In most cases this will be an empty string which indicates the app is not running in a virtual directory. + /// This is NOT a physical path. + /// public string Root { get @@ -301,7 +229,8 @@ namespace Umbraco.Core.IO var appPath = _hostingEnvironment.ApplicationVirtualPath; // ReSharper disable once ConditionIsAlwaysTrueOrFalse - if (appPath == null || appPath == "/") appPath = string.Empty; + if (appPath == null || appPath == "/") + appPath = string.Empty; _root = appPath; diff --git a/src/Umbraco.Core/IO/PhysicalFileSystem.cs b/src/Umbraco.Core/IO/PhysicalFileSystem.cs index 24284fec98..52c210ad28 100644 --- a/src/Umbraco.Core/IO/PhysicalFileSystem.cs +++ b/src/Umbraco.Core/IO/PhysicalFileSystem.cs @@ -59,7 +59,7 @@ namespace Umbraco.Core.IO if (Path.IsPathRooted(rootPath) == false) { // but the test suite App.config cannot really "root" anything so we have to do it here - var localRoot = _ioHelper.GetRootDirectorySafe(); + var localRoot = _ioHelper.MapPath("~"); rootPath = Path.Combine(localRoot, rootPath); } diff --git a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Services.cs b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Services.cs index a41015c4e8..2ab56308ef 100644 --- a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Services.cs +++ b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Services.cs @@ -69,11 +69,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions composition.RegisterUnique(factory => CreatePackageRepository(factory, "installedPackages.config")); composition.RegisterUnique(); composition.RegisterUnique(); - composition.RegisterUnique(factory => //factory required because we need to pass in a string path - new PackageInstallation( - factory.GetInstance(), factory.GetInstance(), - factory.GetInstance(), factory.GetInstance(), - new DirectoryInfo( factory.GetInstance().GetRootDirectorySafe()))); + composition.RegisterUnique(); return composition; } diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs index 8d5922028c..291a4a329d 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Xml.Linq; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Migrations.Upgrade; @@ -24,8 +25,8 @@ namespace Umbraco.Core.Migrations.Install private readonly IRuntimeState _runtime; private readonly IMigrationBuilder _migrationBuilder; private readonly IKeyValueService _keyValueService; + private readonly IHostingEnvironment _hostingEnvironment; private readonly ILogger _logger; - private readonly IIOHelper _ioHelper; private readonly IUmbracoVersion _umbracoVersion; private readonly IDbProviderFactoryCreator _dbProviderFactoryCreator; private readonly IConfigManipulator _configManipulator; @@ -43,7 +44,7 @@ namespace Umbraco.Core.Migrations.Install ILogger logger, IMigrationBuilder migrationBuilder, IKeyValueService keyValueService, - IIOHelper ioHelper, + IHostingEnvironment hostingEnvironment, IUmbracoVersion umbracoVersion, IDbProviderFactoryCreator dbProviderFactoryCreator, IConfigManipulator configManipulator) @@ -55,7 +56,7 @@ namespace Umbraco.Core.Migrations.Install _logger = logger; _migrationBuilder = migrationBuilder; _keyValueService = keyValueService; - _ioHelper = ioHelper; + _hostingEnvironment = hostingEnvironment; _umbracoVersion = umbracoVersion; _dbProviderFactoryCreator = dbProviderFactoryCreator; _configManipulator = configManipulator; @@ -141,14 +142,14 @@ namespace Umbraco.Core.Migrations.Install /// public void ConfigureEmbeddedDatabaseConnection() { - ConfigureEmbeddedDatabaseConnection(_databaseFactory, _ioHelper); + ConfigureEmbeddedDatabaseConnection(_databaseFactory); } - private void ConfigureEmbeddedDatabaseConnection(IUmbracoDatabaseFactory factory, IIOHelper ioHelper) + private void ConfigureEmbeddedDatabaseConnection(IUmbracoDatabaseFactory factory) { _configManipulator.SaveConnectionString(EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe); - var path = Path.Combine(ioHelper.GetRootDirectorySafe(), "App_Data", "Umbraco.sdf"); + var path = Path.Combine(_hostingEnvironment.ApplicationPhysicalPath, "App_Data", "Umbraco.sdf"); if (File.Exists(path) == false) { // this should probably be in a "using (new SqlCeEngine)" clause but not sure diff --git a/src/Umbraco.Infrastructure/Packaging/PackageInstallation.cs b/src/Umbraco.Infrastructure/Packaging/PackageInstallation.cs index e307802606..cf31b3ea52 100644 --- a/src/Umbraco.Infrastructure/Packaging/PackageInstallation.cs +++ b/src/Umbraco.Infrastructure/Packaging/PackageInstallation.cs @@ -1,13 +1,10 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; using System.Xml.Linq; -using Umbraco.Core.IO; -using Umbraco.Core.Models; +using Umbraco.Core.Hosting; using Umbraco.Core.Models.Packaging; -using Umbraco.Core.Services; namespace Umbraco.Core.Packaging { @@ -27,18 +24,17 @@ namespace Umbraco.Core.Packaging /// /// /// - /// - /// The root folder of the application - /// + /// public PackageInstallation(PackageDataInstallation packageDataInstallation, PackageFileInstallation packageFileInstallation, CompiledPackageXmlParser parser, IPackageActionRunner packageActionRunner, - DirectoryInfo applicationRootFolder) + IHostingEnvironment hostingEnvironment) { + _packageExtraction = new PackageExtraction(); _packageFileInstallation = packageFileInstallation ?? throw new ArgumentNullException(nameof(packageFileInstallation)); _packageDataInstallation = packageDataInstallation ?? throw new ArgumentNullException(nameof(packageDataInstallation)); _parser = parser ?? throw new ArgumentNullException(nameof(parser)); _packageActionRunner = packageActionRunner ?? throw new ArgumentNullException(nameof(packageActionRunner)); - _applicationRootFolder = applicationRootFolder ?? throw new ArgumentNullException(nameof(applicationRootFolder)); + _applicationRootFolder = new DirectoryInfo(hostingEnvironment.ApplicationPhysicalPath); } public CompiledPackage ReadPackage(FileInfo packageFile) diff --git a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs index 139e9e9b67..5d2a4b4c64 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs @@ -269,7 +269,7 @@ namespace Umbraco.Core.Runtime { var path = GetApplicationRootPath(); if (string.IsNullOrWhiteSpace(path) == false) - IOHelper.SetRootDirectory(path); + IOHelper.Root = path; } private bool AcquireMainDom(IMainDom mainDom, IApplicationShutdownRegistry applicationShutdownRegistry) @@ -363,8 +363,14 @@ namespace Umbraco.Core.Runtime new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache()))); } - // by default, returns null, meaning that Umbraco should auto-detect the application root path. - // override and return the absolute path to the Umbraco site/solution, if needed + /// + /// Returns the application path of the site/solution + /// + /// + /// + /// By default is null which means it's not running in any virtual folder. If the site is running in a virtual folder, this + /// can be overridden and the virtual path returned (i.e. /mysite/) + /// protected virtual string GetApplicationRootPath() => null; diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index 67108833c3..3df80ded5d 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -61,17 +61,16 @@ namespace Umbraco.Tests.Common public IConfigsFactory GetConfigsFactory() => new ConfigsFactory(); /// - /// Gets the current assembly directory. + /// Gets the working directory of the test project. /// - /// The assembly directory. - public string CurrentAssemblyDirectory + public string WorkingDirectory { get { - var codeBase = typeof(TestHelperBase).Assembly.CodeBase; - var uri = new Uri(codeBase); - var path = uri.LocalPath; - return Path.GetDirectoryName(path); + var dir = Path.Combine(IOHelper.MapPath("~"), "TEMP"); + if (!Directory.Exists(dir)) + Directory.CreateDirectory(dir); + return dir; } } @@ -108,16 +107,21 @@ namespace Umbraco.Tests.Common public IWebRoutingSettings WebRoutingSettings => SettingsForTests.GenerateMockWebRoutingSettings(); /// - /// Maps the given making it rooted on . must start with ~/ + /// Some test files are copied to the /bin (/bin/debug) on build, this is a utility to return their physical path based on a virtual path name /// - /// The relative path. + /// /// - public string MapPathForTest(string relativePath) + public string MapPathForTestFiles(string relativePath) { if (!relativePath.StartsWith("~/")) - throw new ArgumentException("relativePath must start with '~/'", "relativePath"); + throw new ArgumentException("relativePath must start with '~/'", nameof(relativePath)); - return relativePath.Replace("~/", CurrentAssemblyDirectory + "/"); + var codeBase = typeof(TestHelperBase).Assembly.CodeBase; + var uri = new Uri(codeBase); + var path = uri.LocalPath; + var bin = Path.GetDirectoryName(path); + + return relativePath.Replace("~/", bin + "/"); } public IUmbracoVersion GetUmbracoVersion() => new UmbracoVersion(GetConfigs().Global()); diff --git a/src/Umbraco.Tests.Integration/Extensions/ApplicationBuilderExtensions.cs b/src/Umbraco.Tests.Integration/Extensions/ApplicationBuilderExtensions.cs index 553aa4fe85..dec194ccae 100644 --- a/src/Umbraco.Tests.Integration/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Umbraco.Tests.Integration/Extensions/ApplicationBuilderExtensions.cs @@ -5,6 +5,7 @@ using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using NUnit.Framework; using Umbraco.Configuration.Models; using Umbraco.Core; @@ -22,13 +23,16 @@ namespace Umbraco.Tests.Integration.Extensions /// Creates a LocalDb instance to use for the test /// /// - /// + /// /// /// public static IApplicationBuilder UseTestLocalDb(this IApplicationBuilder app, - string dbFilePath, + IHostEnvironment hostEnvironment, UmbracoIntegrationTest integrationTest) { + + var dbFilePath = Path.Combine(hostEnvironment.ContentRootPath, "LocalDb"); + // get the currently set db options var testOptions = TestOptionAttributeBase.GetTestOptions(); diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs index 4a986fa35a..50f0614291 100644 --- a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs +++ b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs @@ -23,7 +23,7 @@ namespace Umbraco.Tests.Integration.Implementations public class TestHelper : TestHelperBase { private IBackOfficeInfo _backOfficeInfo; - private readonly IHostingEnvironment _hostingEnvironment; + private IHostingEnvironment _hostingEnvironment; private readonly IApplicationShutdownRegistry _hostingLifetime; private readonly IIpResolver _ipResolver; private readonly IWebHostEnvironment _hostEnvironment; @@ -36,15 +36,15 @@ namespace Umbraco.Tests.Integration.Implementations _httpContextAccessor = Mock.Of(x => x.HttpContext == httpContext); _ipResolver = new AspNetIpResolver(_httpContextAccessor); - _hostEnvironment = Mock.Of(x => - x.ApplicationName == "UmbracoIntegrationTests" - && x.ContentRootPath == CurrentAssemblyDirectory - && x.WebRootPath == CurrentAssemblyDirectory); // same folder for now? + // For Azure Devops we can only store a database in certain locations so we will need to detect if we are running + // on a build server and if so we'll use the %temp% path. + //var siteTemp = System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", hash); - _hostingEnvironment = new TestHostingEnvironment( - SettingsForTests.GetDefaultHostingSettings(), - _hostEnvironment, - _httpContextAccessor); + var hostEnvironment = new Mock(); + hostEnvironment.Setup(x => x.ApplicationName).Returns("UmbracoIntegrationTests"); + hostEnvironment.Setup(x => x.ContentRootPath).Returns(() => WorkingDirectory); + hostEnvironment.Setup(x => x.WebRootPath).Returns(() => WorkingDirectory); + _hostEnvironment = hostEnvironment.Object; _hostingLifetime = new AspNetCoreApplicationShutdownRegistry(Mock.Of()); @@ -76,7 +76,12 @@ namespace Umbraco.Tests.Integration.Implementations return _backOfficeInfo; } - public override IHostingEnvironment GetHostingEnvironment() => _hostingEnvironment; + public override IHostingEnvironment GetHostingEnvironment() + => _hostingEnvironment ??= new TestHostingEnvironment( + SettingsForTests.GetDefaultHostingSettings(), + _hostEnvironment, + _httpContextAccessor); + public override IApplicationShutdownRegistry GetHostingEnvironmentLifetime() => _hostingLifetime; public override IIpResolver GetIpResolver() => _ipResolver; diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs b/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs index 491b7e5480..01d44c1a74 100644 --- a/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs +++ b/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs @@ -8,7 +8,8 @@ namespace Umbraco.Tests.Integration.Implementations public class TestHostingEnvironment : AspNetCoreHostingEnvironment, Umbraco.Core.Hosting.IHostingEnvironment { - public TestHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor) : base(hostingSettings, webHostEnvironment, httpContextAccessor) + public TestHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor) + : base(hostingSettings, webHostEnvironment, httpContextAccessor) { } diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index 3d94e52860..f40978d59c 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -127,7 +127,7 @@ namespace Umbraco.Tests.Integration.Testing Services = app.ApplicationServices; // This will create a db, install the schema and ensure the app is configured to run - app.UseTestLocalDb(Path.Combine(testHelper.CurrentAssemblyDirectory, "LocalDb"), this); + app.UseTestLocalDb(Services.GetRequiredService(), this); app.UseUmbracoCore(); } diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/UmbracoSettingsTests.cs b/src/Umbraco.Tests/Configurations/UmbracoSettings/UmbracoSettingsTests.cs index 7a82f3c070..0829de6668 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/UmbracoSettingsTests.cs +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/UmbracoSettingsTests.cs @@ -15,7 +15,7 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings [SetUp] public void Init() { - var config = new FileInfo(TestHelper.MapPathForTest("~/Configurations/UmbracoSettings/web.config")); + var config = new FileInfo(TestHelper.MapPathForTestFiles("~/Configurations/UmbracoSettings/web.config")); var fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = config.FullName }; var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); diff --git a/src/Umbraco.Tests/Packaging/PackageExtractionTests.cs b/src/Umbraco.Tests/Packaging/PackageExtractionTests.cs index 9bbda6dbbc..83620d35f5 100644 --- a/src/Umbraco.Tests/Packaging/PackageExtractionTests.cs +++ b/src/Umbraco.Tests/Packaging/PackageExtractionTests.cs @@ -10,14 +10,14 @@ using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Packaging { [TestFixture] - class PackageExtractionTests + public class PackageExtractionTests { private const string PackageFileName = "Document_Type_Picker_1.1.umb"; private static FileInfo GetTestPackagePath(string packageName) { const string testPackagesDirName = "Packaging\\Packages"; - string path = Path.Combine(TestHelper.IOHelper.GetRootDirectorySafe(), testPackagesDirName, packageName); + string path = Path.Combine(TestHelper.IOHelper.MapPath("~"), testPackagesDirName, packageName); return new FileInfo(path); } diff --git a/src/Umbraco.Tests/Packaging/PackageInstallationTest.cs b/src/Umbraco.Tests/Packaging/PackageInstallationTest.cs index 1630a1e969..90db389002 100644 --- a/src/Umbraco.Tests/Packaging/PackageInstallationTest.cs +++ b/src/Umbraco.Tests/Packaging/PackageInstallationTest.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.Packaging; @@ -25,12 +26,15 @@ namespace Umbraco.Tests.Packaging [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)] public class PackageInstallationTest : TestWithDatabaseBase { - private Guid _testBaseFolder; + private DirectoryInfo _testBaseFolder; public override void SetUp() { base.SetUp(); - _testBaseFolder = Guid.NewGuid(); + var path = Path.Combine(TestHelper.WorkingDirectory, Guid.NewGuid().ToString()); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + _testBaseFolder = new DirectoryInfo(path); } public override void TearDown() @@ -38,9 +42,8 @@ namespace Umbraco.Tests.Packaging base.TearDown(); //clear out files/folders - var path = IOHelper.MapPath("~/" + _testBaseFolder); - if (Directory.Exists(path)) - Directory.Delete(path, true); + if (_testBaseFolder.Exists) + _testBaseFolder.Delete(true); } private CompiledPackageXmlParser Parser => new CompiledPackageXmlParser(new ConflictingPackageData(ServiceContext.MacroService, ServiceContext.FileService),Factory.GetInstance()); @@ -60,7 +63,8 @@ namespace Umbraco.Tests.Packaging PackageDataInstallation, new PackageFileInstallation(Parser, IOHelper, ProfilingLogger), Parser, Mock.Of(), - applicationRootFolder: new DirectoryInfo(IOHelper.MapPath("~/" + _testBaseFolder))); //we don't want to extract package files to the real root, so extract to a test folder + //we don't want to extract package files to the real root, so extract to a test folder + Mock.Of(x => x.ApplicationPhysicalPath == _testBaseFolder.FullName)); private const string DocumentTypePickerPackage = "Document_Type_Picker_1.1.umb"; private const string HelloPackage = "Hello_1.0.0.zip"; @@ -118,10 +122,8 @@ namespace Umbraco.Tests.Packaging public void Can_Read_Compiled_Package_Warnings() { //copy a file to the same path that the package will install so we can detect file conflicts - var path = IOHelper.MapPath("~/" + _testBaseFolder); - Console.WriteLine(path); - - var filePath = Path.Combine(path, "bin", "Auros.DocumentTypePicker.dll"); + + var filePath = Path.Combine(_testBaseFolder.FullName, "bin", "Auros.DocumentTypePicker.dll"); Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, "test"); @@ -155,7 +157,7 @@ namespace Umbraco.Tests.Packaging Assert.AreEqual(1, result.Count); Assert.AreEqual("bin\\Auros.DocumentTypePicker.dll", result[0]); - Assert.IsTrue(File.Exists(Path.Combine(IOHelper.MapPath("~/" + _testBaseFolder), result[0]))); + Assert.IsTrue(File.Exists(Path.Combine(_testBaseFolder.FullName, result[0]))); //make sure the def is updated too Assert.AreEqual(result.Count, def.Files.Count); diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index d964ab972b..885877d312 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -51,7 +51,7 @@ namespace Umbraco.Tests.Persistence [Test] public void CreateDatabase() // FIXME: move to DatabaseBuilderTest! { - var path = TestHelper.CurrentAssemblyDirectory; + var path = TestHelper.WorkingDirectory; AppDomain.CurrentDomain.SetData("DataDirectory", path); // delete database file diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 11393e3e6b..aab0903f1d 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -82,10 +82,10 @@ namespace Umbraco.Tests.TestHelpers public static IConfigsFactory GetConfigsFactory() => _testHelperInternal.GetConfigsFactory(); /// - /// Gets the current assembly directory. + /// Gets the working directory of the test project. /// /// The assembly directory. - public static string CurrentAssemblyDirectory => _testHelperInternal.CurrentAssemblyDirectory; + public static string WorkingDirectory => _testHelperInternal.WorkingDirectory; public static IShortStringHelper ShortStringHelper => _testHelperInternal.ShortStringHelper; public static IJsonSerializer JsonSerializer => _testHelperInternal.JsonSerializer; @@ -102,12 +102,13 @@ namespace Umbraco.Tests.TestHelpers public static IWebRoutingSettings WebRoutingSettings => _testHelperInternal.WebRoutingSettings; + /// - /// Maps the given making it rooted on . must start with ~/ + /// Some test files are copied to the /bin (/bin/debug) on build, this is a utility to return their physical path based on a virtual path name /// - /// The relative path. + /// /// - public static string MapPathForTest(string relativePath) => _testHelperInternal.MapPathForTest(relativePath); + public static string MapPathForTestFiles(string relativePath) => _testHelperInternal.MapPathForTestFiles(relativePath); public static void InitializeContentDirectories() { @@ -147,7 +148,7 @@ namespace Umbraco.Tests.TestHelpers public static void CleanUmbracoSettingsConfig() { - var currDir = new DirectoryInfo(CurrentAssemblyDirectory); + var currDir = new DirectoryInfo(WorkingDirectory); var umbracoSettingsFile = Path.Combine(currDir.Parent.Parent.FullName, "config", "umbracoSettings.config"); if (File.Exists(umbracoSettingsFile)) diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index 4609d8a59c..70c1c4bedf 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Events; +using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Packaging; @@ -74,23 +75,21 @@ namespace Umbraco.Tests.TestHelpers /// /// Gets a ServiceContext. /// + /// /// /// A cache. /// A logger. - /// An Umbraco Version. /// An io helper. /// - /// + /// /// An event messages factory. /// Some url segment providers. - /// + /// An Umbraco Version. /// A container. - /// /// A ServiceContext. /// Should be used sparingly for integration tests only - for unit tests /// just mock the services to be passed to the ctor of the ServiceContext. - public ServiceContext GetServiceContext( - IScopeProvider scopeProvider, IScopeAccessor scopeAccessor, + public ServiceContext GetServiceContext(IScopeProvider scopeProvider, IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IIOHelper ioHelper, @@ -98,7 +97,6 @@ namespace Umbraco.Tests.TestHelpers IContentSettings contentSettings, IEventMessagesFactory eventMessagesFactory, UrlSegmentProviderCollection urlSegmentProviders, - TypeLoader typeLoader, IUmbracoVersion umbracoVersion, IFactory factory = null) { @@ -187,7 +185,8 @@ namespace Umbraco.Tests.TestHelpers new PackageDataInstallation(logger, fileService.Value, macroService.Value, localizationService.Value, dataTypeService.Value, entityService.Value, contentTypeService.Value, contentService.Value, propertyEditorCollection, scopeProvider, shortStringHelper, GetGlobalSettings(), localizedTextService.Value), new PackageFileInstallation(compiledPackageXmlParser, ioHelper, new ProfilingLogger(logger, new TestProfiler())), compiledPackageXmlParser, Mock.Of(), - new DirectoryInfo(ioHelper.GetRootDirectorySafe())), ioHelper); + Mock.Of(x => x.ApplicationPhysicalPath == ioHelper.MapPath("~"))), + ioHelper); }); var relationService = GetLazyService(factory, c => new RelationService(scopeProvider, logger, eventMessagesFactory, entityService.Value, GetRepo(c), GetRepo(c))); var tagService = GetLazyService(factory, c => new TagService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index b4db4f551c..159baa5c79 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -62,10 +62,11 @@ namespace Umbraco.Tests.TestHelpers public override void SetUp() { - base.SetUp(); - - var path = TestHelper.CurrentAssemblyDirectory; + // Ensure the data directory is set before continuing + var path = TestHelper.WorkingDirectory; AppDomain.CurrentDomain.SetData("DataDirectory", path); + + base.SetUp(); } protected override void Compose() @@ -167,7 +168,7 @@ namespace Umbraco.Tests.TestHelpers if (Options.Database == UmbracoTestOptions.Database.None) return; - var path = TestHelper.CurrentAssemblyDirectory; + var path = TestHelper.WorkingDirectory; //Get the connectionstring settings from config var settings = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName]; @@ -337,7 +338,7 @@ namespace Umbraco.Tests.TestHelpers private void RemoveDatabaseFile(Action onFail = null) { - var path = TestHelper.CurrentAssemblyDirectory; + var path = TestHelper.WorkingDirectory; try { var filePath = string.Concat(path, "\\UmbracoNPocoTests.sdf"); diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index c3505a23fa..fa01bdd97b 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -267,7 +267,7 @@ namespace Umbraco.Tests.Testing profiler = Mock.Of(); break; case UmbracoTestOptions.Logger.Serilog: - logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTest("~/unit-test.config"))); + logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTestFiles("~/unit-test.config"))); profiler = new LogProfiler(logger); break; case UmbracoTestOptions.Logger.Console: diff --git a/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs b/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs index 91cb843eb1..a6c544062e 100644 --- a/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs +++ b/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs @@ -17,7 +17,8 @@ namespace Umbraco.Tests.UmbracoExamine [OneTimeSetUp] public void InitializeFixture() { - var logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTest("~/unit-test.config"))); + + var logger = new SerilogLogger(TestHelper.CoreDebugSettings, IOHelper, TestHelper.Marchal, new FileInfo(TestHelper.MapPathForTestFiles("~/unit-test.config"))); _profilingLogger = new ProfilingLogger(logger, new LogProfiler(logger)); } diff --git a/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs b/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs index 0e757bbc6d..1499c5274e 100644 --- a/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs +++ b/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs @@ -77,7 +77,7 @@ namespace Umbraco.Tests.Web.Controllers var baseDir = IOHelper.MapPath("").TrimEnd(IOHelper.DirSepChar); HttpContext.Current = new HttpContext(new SimpleWorkerRequest("/", baseDir, "", "", new StringWriter())); } - IOHelper.ForceNotHosted = true; + var usersController = new AuthenticationController( new TestUserPasswordConfig(), Factory.GetInstance(), diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs index 6f1298918d..05d3ebf7c5 100644 --- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs +++ b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs @@ -21,8 +21,8 @@ namespace Umbraco.Web.BackOffice.AspNetCore public AspNetCoreHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor) { _hostingSettings = hostingSettings ?? throw new ArgumentNullException(nameof(hostingSettings)); - _webHostEnvironment = webHostEnvironment; - _httpContextAccessor = httpContextAccessor; + _webHostEnvironment = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment)); + _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor)); SiteName = webHostEnvironment.ApplicationName; ApplicationId = AppDomain.CurrentDomain.Id.ToString(); diff --git a/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs b/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs index a61ad356d5..0ae177517a 100644 --- a/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs +++ b/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Web; using System.Web.Hosting; using Umbraco.Core; @@ -18,7 +19,8 @@ namespace Umbraco.Web.Hosting _hostingSettings = hostingSettings ?? throw new ArgumentNullException(nameof(hostingSettings)); SiteName = HostingEnvironment.SiteName; ApplicationId = HostingEnvironment.ApplicationID; - ApplicationPhysicalPath = HostingEnvironment.ApplicationPhysicalPath; + // when we are not hosted (i.e. unit test or otherwise) we'll need to get the root path from the executing assembly + ApplicationPhysicalPath = HostingEnvironment.ApplicationPhysicalPath ?? Assembly.GetExecutingAssembly().GetRootDirectorySafe(); ApplicationVirtualPath = HostingEnvironment.ApplicationVirtualPath; IISVersion = HttpRuntime.IISVersion; } From 4ee3cf02d9d7c9d8dfc2fb7ed5dc754f6021baba Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 31 Mar 2020 18:01:27 +1100 Subject: [PATCH 2/3] Changes integration tests working folder, hopefully this works on azure devops --- .gitignore | 1 + src/Umbraco.Tests.Common/TestHelperBase.cs | 11 ++++-- .../Extensions/ServiceCollectionExtensions.cs | 3 ++ .../Implementations/TestHelper.cs | 34 ++++++++++++++++--- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 5390da67dd..2ed26621df 100644 --- a/.gitignore +++ b/.gitignore @@ -167,3 +167,4 @@ build/temp/ /src/Umbraco.Web.UI.NetCore/wwwroot/Media/* /src/Umbraco.Web.UI.NetCore/wwwroot/is-cache/* /src/Umbraco.Tests.Integration/App_Data/* +/src/Umbraco.Tests.Integration/TEMP/* diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index 3df80ded5d..b14bd5fd5d 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -30,6 +30,7 @@ namespace Umbraco.Tests.Common private readonly ITypeFinder _typeFinder; private UriUtility _uriUtility; private IIOHelper _ioHelper; + private string _workingDir; protected TestHelperBase(Assembly entryAssembly) { @@ -63,14 +64,18 @@ namespace Umbraco.Tests.Common /// /// Gets the working directory of the test project. /// - public string WorkingDirectory + public virtual string WorkingDirectory { get { - var dir = Path.Combine(IOHelper.MapPath("~"), "TEMP"); + if (_workingDir != null) return _workingDir; + + var dir = Path.Combine(Assembly.GetExecutingAssembly().GetRootDirectorySafe(), "TEMP"); + if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); - return dir; + _workingDir = dir; + return _workingDir; } } diff --git a/src/Umbraco.Tests.Integration/Extensions/ServiceCollectionExtensions.cs b/src/Umbraco.Tests.Integration/Extensions/ServiceCollectionExtensions.cs index 9dde20036b..dc58d3e9e6 100644 --- a/src/Umbraco.Tests.Integration/Extensions/ServiceCollectionExtensions.cs +++ b/src/Umbraco.Tests.Integration/Extensions/ServiceCollectionExtensions.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Umbraco.Tests.Integration.Implementations; namespace Umbraco.Tests.Integration.Extensions @@ -18,6 +19,8 @@ namespace Umbraco.Tests.Integration.Extensions services.AddSingleton(x => testHelper.GetHttpContextAccessor()); // the generic host does add IHostEnvironment but not this one because we are not actually in a web context services.AddSingleton(x => webHostEnvironment); + // replace the IHostEnvironment that generic host created too + services.AddSingleton(x => webHostEnvironment); } } } diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs index 50f0614291..e473950d7c 100644 --- a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs +++ b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs @@ -1,9 +1,11 @@  +using System; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Hosting; using Moq; using System.Data.Common; +using System.IO; using System.Net; using Umbraco.Core; using Umbraco.Core.Cache; @@ -28,6 +30,7 @@ namespace Umbraco.Tests.Integration.Implementations private readonly IIpResolver _ipResolver; private readonly IWebHostEnvironment _hostEnvironment; private readonly IHttpContextAccessor _httpContextAccessor; + private string _tempWorkingDir; public TestHelper() : base(typeof(TestHelper).Assembly) { @@ -36,10 +39,6 @@ namespace Umbraco.Tests.Integration.Implementations _httpContextAccessor = Mock.Of(x => x.HttpContext == httpContext); _ipResolver = new AspNetIpResolver(_httpContextAccessor); - // For Azure Devops we can only store a database in certain locations so we will need to detect if we are running - // on a build server and if so we'll use the %temp% path. - //var siteTemp = System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", hash); - var hostEnvironment = new Mock(); hostEnvironment.Setup(x => x.ApplicationName).Returns("UmbracoIntegrationTests"); hostEnvironment.Setup(x => x.ContentRootPath).Returns(() => WorkingDirectory); @@ -51,6 +50,33 @@ namespace Umbraco.Tests.Integration.Implementations Logger = new ProfilingLogger(new ConsoleLogger(new MessageTemplates()), Profiler); } + + public override string WorkingDirectory + { + get + { + // For Azure Devops we can only store a database in certain locations so we will need to detect if we are running + // on a build server and if so we'll use the %temp% path. + + if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("System.DefaultWorkingDirectory"))) + { + // we are using Azure Devops! + + if (_tempWorkingDir != null) return _tempWorkingDir; + + var temp = Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoTemp"); + Directory.CreateDirectory(temp); + _tempWorkingDir = temp; + return _tempWorkingDir; + + } + else + { + return base.WorkingDirectory; + } + } + } + public IUmbracoBootPermissionChecker UmbracoBootPermissionChecker { get; } = new TestUmbracoBootPermissionChecker(); public AppCaches AppCaches { get; } = new AppCaches(NoAppCache.Instance, NoAppCache.Instance, new IsolatedCaches(type => NoAppCache.Instance)); From ebdd5e3f6965a9892f5a7c2cc209182d4bcef9f1 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 31 Mar 2020 18:13:19 +1100 Subject: [PATCH 3/3] env var change --- src/Umbraco.Tests.Integration/Implementations/TestHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs index e473950d7c..3124e77eef 100644 --- a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs +++ b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs @@ -58,7 +58,7 @@ namespace Umbraco.Tests.Integration.Implementations // For Azure Devops we can only store a database in certain locations so we will need to detect if we are running // on a build server and if so we'll use the %temp% path. - if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("System.DefaultWorkingDirectory"))) + if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("System_DefaultWorkingDirectory"))) { // we are using Azure Devops!