Adding Orchard.Azure.Tests to the solution, cleanup and DRYing, but it can't start the storage emulator on its own anymore

When running those tests, make sure the storage emulator is running: npm install azurite -g; azurite --blobHost 127.0.0.1
This commit is contained in:
Benedek Farkas
2025-10-14 23:29:17 +02:00
parent dffd946e4c
commit 11bf8f4a06
6 changed files with 65 additions and 110 deletions
-1
View File
@@ -7,7 +7,6 @@ on:
branches: branches:
- 1.10.x - 1.10.x
- dev - dev
- task/nuget-updates
schedule: schedule:
- cron: '0 0 * * 1' # Every Monday midnight. - cron: '0 0 * * 1' # Every Monday midnight.
-2
View File
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<appSettings> <appSettings>
<add key="AzureSDK" value="C:\Program Files (x86)\Microsoft SDKs\Azure\" />
<add key="Orchard.Azure.Settings.StorageConnectionString" value="UseDevelopmentStorage=true" /> <add key="Orchard.Azure.Settings.StorageConnectionString" value="UseDevelopmentStorage=true" />
<add key="Orchard.Azure.Media.StorageConnectionString" value="UseDevelopmentStorage=true" /> <add key="Orchard.Azure.Media.StorageConnectionString" value="UseDevelopmentStorage=true" />
</appSettings> </appSettings>
@@ -1,77 +1,49 @@
using System; using Microsoft.WindowsAzure.Storage;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob; using Microsoft.WindowsAzure.Storage.Blob;
using NUnit.Framework; using NUnit.Framework;
using Orchard.Azure.Services.Environment.Configuration;
namespace Orchard.Azure.Tests { namespace Orchard.Azure.Tests {
public abstract class AzureVirtualEnvironmentTest { public abstract class AzureVirtualEnvironmentTest {
private Process _storageEmulator; protected IPlatformConfigurationAccessor PlatformConfigurationAccessor = new DefaultPlatformConfigurationAccessor();
protected abstract string StorageConnectionStringName { get; }
protected CloudStorageAccount DevAccount { get; private set; }
protected abstract void OnInit(); protected abstract void OnInit();
[OneTimeSetUp] [OneTimeSetUp]
public void FixtureSetup() { public void FixtureSetup() {
if (!Process.GetProcessesByName("AzureStorageEmulator").Any()) { var connectionString = PlatformConfigurationAccessor.GetSetting(StorageConnectionStringName, "default", "");
var azureSDKPath = ConfigurationManager.AppSettings["AzureSDK"];
var storageEmulatorRelativePath = "Storage Emulator\\AzureStorageEmulator.exe";
if (String.IsNullOrEmpty(azureSDKPath)) { CloudStorageAccount.TryParse(connectionString, out CloudStorageAccount devAccount);
throw new ConfigurationErrorsException("Could not find the AppSetting \"AzureSDK\" that indicates the path to the Azure SDK on the local file system."); DevAccount = devAccount;
}
var storageEmulatorAbsolutePath = Path.Combine(azureSDKPath, storageEmulatorRelativePath);
if (!File.Exists(storageEmulatorAbsolutePath)) {
throw new ConfigurationErrorsException("Could not find the executable to start the Azure Storage Emulator.");
}
var storageEmulatorStartInfo = new ProcessStartInfo {
Arguments = "start",
FileName = storageEmulatorAbsolutePath
};
_storageEmulator = new Process { StartInfo = storageEmulatorStartInfo };
_storageEmulator.Start();
_storageEmulator.WaitForExit();
}
OnInit(); OnInit();
} }
[OneTimeTearDown]
public void FixtureTearDown() {
if (_storageEmulator != null)
_storageEmulator.Close();
}
protected void DeleteAllBlobs(string containerName, CloudStorageAccount account) { protected void DeleteAllBlobs(string containerName, CloudStorageAccount account) {
var blobClient = account.CreateCloudBlobClient(); var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference(containerName); var container = blobClient.GetContainerReference(containerName);
foreach (var blob in container.ListBlobs()) { foreach (var blob in container.ListBlobs()) {
if (blob is CloudBlob) { if (blob is CloudBlob blobLeaf) {
((CloudBlob)blob).DeleteIfExists(); blobLeaf.DeleteIfExists();
} }
if (blob is CloudBlobDirectory) { if (blob is CloudBlobDirectory directory) {
DeleteAllBlobs((CloudBlobDirectory)blob); DeleteAllBlobs(directory);
} }
} }
} }
private static void DeleteAllBlobs(CloudBlobDirectory cloudBlobDirectory) { private static void DeleteAllBlobs(CloudBlobDirectory cloudBlobDirectory) {
foreach (var blob in cloudBlobDirectory.ListBlobs()) { foreach (var blob in cloudBlobDirectory.ListBlobs()) {
if (blob is CloudBlob) { if (blob is CloudBlob blobLeaf) {
((CloudBlob)blob).DeleteIfExists(); blobLeaf.DeleteIfExists();
} }
if (blob is CloudBlobDirectory) { if (blob is CloudBlobDirectory directory) {
DeleteAllBlobs((CloudBlobDirectory)blob); DeleteAllBlobs(directory);
} }
} }
} }
@@ -1,5 +1,4 @@
using System.Linq; using System.Linq;
using Microsoft.WindowsAzure.Storage;
using NUnit.Framework; using NUnit.Framework;
using Orchard.Azure.Services.Environment.Configuration; using Orchard.Azure.Services.Environment.Configuration;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
@@ -8,14 +7,14 @@ using Orchard.FileSystems.Media;
namespace Orchard.Azure.Tests.Environment.Configuration { namespace Orchard.Azure.Tests.Environment.Configuration {
[TestFixture] [TestFixture]
public class AzureShellSettingsManagerTests : AzureVirtualEnvironmentTest { public class AzureShellSettingsManagerTests : AzureVirtualEnvironmentTest {
private IShellSettingsManager _shellSettingsManager;
protected CloudStorageAccount DevAccount; protected override string StorageConnectionStringName { get; } = Constants.ShellSettingsStorageConnectionStringSettingName;
protected IShellSettingsManager ShellSettingsManager;
protected override void OnInit() { protected override void OnInit() {
_shellSettingsManager = new AzureBlobShellSettingsManager(
CloudStorageAccount.TryParse("UseDevelopmentStorage=true", out DevAccount); new Moq.Mock<IMimeTypeProvider>().Object,
ShellSettingsManager = new AzureBlobShellSettingsManager(new Moq.Mock<IMimeTypeProvider>().Object, new Moq.Mock<IShellSettingsManagerEventHandler>().Object); new Moq.Mock<IShellSettingsManagerEventHandler>().Object);
} }
[SetUp] [SetUp]
@@ -33,9 +32,9 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test] [Test]
public void SingleSettingsFileShouldComeBackAsExpected() { public void SingleSettingsFileShouldComeBackAsExpected() {
ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" }); _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" });
var settings = ShellSettingsManager.LoadSettings().Single(); var settings = _shellSettingsManager.LoadSettings().Single();
Assert.That(settings, Is.Not.Null); Assert.That(settings, Is.Not.Null);
Assert.That(settings.Name, Is.EqualTo("Default")); Assert.That(settings.Name, Is.EqualTo("Default"));
Assert.That(settings.DataProvider, Is.EqualTo("SQLCe")); Assert.That(settings.DataProvider, Is.EqualTo("SQLCe"));
@@ -44,10 +43,10 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test] [Test]
public void SettingsShouldBeOverwritable() { public void SettingsShouldBeOverwritable() {
ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" }); _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" });
ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe2", DataConnectionString = "something else2" }); _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe2", DataConnectionString = "something else2" });
var settings = ShellSettingsManager.LoadSettings().Single(); var settings = _shellSettingsManager.LoadSettings().Single();
Assert.That(settings, Is.Not.Null); Assert.That(settings, Is.Not.Null);
Assert.That(settings.Name, Is.EqualTo("Default")); Assert.That(settings.Name, Is.EqualTo("Default"));
Assert.That(settings.DataProvider, Is.EqualTo("SQLCe2")); Assert.That(settings.DataProvider, Is.EqualTo("SQLCe2"));
@@ -57,10 +56,10 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test] [Test]
public void MultipleFilesCanBeDetected() { public void MultipleFilesCanBeDetected() {
ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" }); _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" });
ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Another", DataProvider = "SQLCe2", DataConnectionString = "something else2" }); _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Another", DataProvider = "SQLCe2", DataConnectionString = "something else2" });
var settings = ShellSettingsManager.LoadSettings(); var settings = _shellSettingsManager.LoadSettings();
Assert.That(settings.Count(), Is.EqualTo(2)); Assert.That(settings.Count(), Is.EqualTo(2));
var def = settings.Single(x => x.Name == "Default"); var def = settings.Single(x => x.Name == "Default");
@@ -76,15 +75,15 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test] [Test]
public void NewSettingsCanBeStored() { public void NewSettingsCanBeStored() {
ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "something else" }); _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "something else" });
var foo = new ShellSettings { Name = "Foo", DataProvider = "Bar", DataConnectionString = "Quux" }; var foo = new ShellSettings { Name = "Foo", DataProvider = "Bar", DataConnectionString = "Quux" };
Assert.That(ShellSettingsManager.LoadSettings().Count(), Is.EqualTo(1)); Assert.That(_shellSettingsManager.LoadSettings().Count(), Is.EqualTo(1));
ShellSettingsManager.SaveSettings(foo); _shellSettingsManager.SaveSettings(foo);
Assert.That(ShellSettingsManager.LoadSettings().Count(), Is.EqualTo(2)); Assert.That(_shellSettingsManager.LoadSettings().Count(), Is.EqualTo(2));
foo = ShellSettingsManager.LoadSettings().Where(s => s.Name == "Foo").Single(); foo = _shellSettingsManager.LoadSettings().Where(s => s.Name == "Foo").Single();
Assert.That(foo.Name, Does.Contain("Foo")); Assert.That(foo.Name, Does.Contain("Foo"));
Assert.That(foo.DataProvider, Does.Contain("Bar")); Assert.That(foo.DataProvider, Does.Contain("Bar"));
Assert.That(foo.DataConnectionString, Does.Contain("Quux")); Assert.That(foo.DataConnectionString, Does.Contain("Quux"));
@@ -92,9 +91,9 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test] [Test]
public void SettingsCanContainSeparatorChar() { public void SettingsCanContainSeparatorChar() {
ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "Server=tcp:tjyptm5sfc.database.windows.net;Database=orchard;User ID=foo@bar;Password=foo;Trusted_Connection=False;Encrypt=True;" }); _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "Server=tcp:tjyptm5sfc.database.windows.net;Database=orchard;User ID=foo@bar;Password=foo;Trusted_Connection=False;Encrypt=True;" });
var settings = ShellSettingsManager.LoadSettings().Where(s => s.Name == "Default").Single(); var settings = _shellSettingsManager.LoadSettings().Where(s => s.Name == "Default").Single();
Assert.That(settings.DataConnectionString, Is.EqualTo("Server=tcp:tjyptm5sfc.database.windows.net;Database=orchard;User ID=foo@bar;Password=foo;Trusted_Connection=False;Encrypt=True;")); Assert.That(settings.DataConnectionString, Is.EqualTo("Server=tcp:tjyptm5sfc.database.windows.net;Database=orchard;User ID=foo@bar;Password=foo;Trusted_Connection=False;Encrypt=True;"));
} }
} }
@@ -1,52 +1,46 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Web; using System.Web;
using NUnit.Framework; using NUnit.Framework;
using System.Linq;
using Orchard.Environment.Configuration;
using Orchard.Azure.Services.FileSystems.Media; using Orchard.Azure.Services.FileSystems.Media;
using Orchard.Environment.Configuration;
using Orchard.FileSystems.Media; using Orchard.FileSystems.Media;
using Microsoft.WindowsAzure.Storage;
using Orchard.Azure.Services.Environment.Configuration;
namespace Orchard.Azure.Tests.FileSystems.Media { namespace Orchard.Azure.Tests.FileSystems.Media {
[TestFixture] [TestFixture]
public class AzureBlobStorageProviderTests : AzureVirtualEnvironmentTest { public class AzureBlobStorageProviderTests : AzureVirtualEnvironmentTest {
private CloudStorageAccount _devAccount;
private IPlatformConfigurationAccessor _platformConfigurationAccessor;
private AzureBlobStorageProvider _azureBlobStorageProvider; private AzureBlobStorageProvider _azureBlobStorageProvider;
protected override void OnInit() { protected override string StorageConnectionStringName { get; } = Constants.MediaStorageStorageConnectionStringSettingName;
CloudStorageAccount.TryParse("UseDevelopmentStorage=true", out _devAccount); protected override void OnInit() {
_platformConfigurationAccessor = new DefaultPlatformConfigurationAccessor(); _azureBlobStorageProvider = new AzureBlobStorageProvider(
_azureBlobStorageProvider = new AzureBlobStorageProvider(new ShellSettings { Name = "default" }, new ConfigurationMimeTypeProvider(), _platformConfigurationAccessor); new ShellSettings { Name = "default" },
new ConfigurationMimeTypeProvider(),
PlatformConfigurationAccessor);
} }
[SetUp] [SetUp]
public void Setup() { public void Setup() {
// ensure default container is empty before running any test // ensure default container is empty before running any test
DeleteAllBlobs(_azureBlobStorageProvider.Container.Name, _devAccount); DeleteAllBlobs(_azureBlobStorageProvider.Container.Name, DevAccount);
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentException))]
public void GetFileShouldOnlyAcceptRelativePath() { public void GetFileShouldOnlyAcceptRelativePath() {
_azureBlobStorageProvider.CreateFile("foo.txt"); _azureBlobStorageProvider.CreateFile("foo.txt");
_azureBlobStorageProvider.GetFile("/foo.txt"); Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.GetFile("/foo.txt"));
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentException))]
public void GetFileThatDoesNotExistShouldThrow() { public void GetFileThatDoesNotExistShouldThrow() {
_azureBlobStorageProvider.GetFile("notexisting"); Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.GetFile("notexisting"));
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentException))]
public void DeleteFileThatDoesNotExistShouldThrow() { public void DeleteFileThatDoesNotExistShouldThrow() {
_azureBlobStorageProvider.DeleteFile("notexisting"); Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.DeleteFile("notexisting"));
} }
[Test] [Test]
@@ -72,12 +66,11 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentException))]
public void CreateFileShouldThrowAnExceptionIfAlreadyExisting() { public void CreateFileShouldThrowAnExceptionIfAlreadyExisting() {
var storageFile = _azureBlobStorageProvider.CreateFile("foo.txt"); var storageFile = _azureBlobStorageProvider.CreateFile("foo.txt");
Assert.AreEqual(storageFile.GetSize(), 0); Assert.AreEqual(storageFile.GetSize(), 0);
_azureBlobStorageProvider.CreateFile("foo.txt"); Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.CreateFile("foo.txt"));
} }
[Test] [Test]
@@ -108,10 +101,9 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentException))]
public void CreateFolderThatExistsShouldThrow() { public void CreateFolderThatExistsShouldThrow() {
_azureBlobStorageProvider.CreateFile("folder/foo.txt"); _azureBlobStorageProvider.CreateFile("folder/foo.txt");
_azureBlobStorageProvider.CreateFolder("folder"); Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.CreateFolder("folder"));
} }
[Test] [Test]
@@ -196,10 +188,9 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentException))]
public void CannotCreateAlreadyExistingFolders() { public void CannotCreateAlreadyExistingFolders() {
_azureBlobStorageProvider.CreateFile("folder1/foo.txt"); _azureBlobStorageProvider.CreateFile("folder1/foo.txt");
_azureBlobStorageProvider.CreateFolder("folder1"); Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.CreateFolder("folder1"));
} }
[Test] [Test]
@@ -210,21 +201,21 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
[Test] [Test]
public void ShouldReadWriteFiles() { public void ShouldReadWriteFiles() {
const string teststring = "This is a test string."; const string testString = "This is a test string.";
var foo = _azureBlobStorageProvider.CreateFile("folder1/foo.txt"); var foo = _azureBlobStorageProvider.CreateFile("folder1/foo.txt");
using ( var stream = foo.OpenWrite() ) using (var stream = foo.OpenWrite())
using ( var writer = new StreamWriter(stream) ) using (var writer = new StreamWriter(stream))
writer.Write(teststring); writer.Write(testString);
string content; string content;
using ( var stream = foo.OpenRead() ) using (var stream = foo.OpenRead())
using ( var reader = new StreamReader(stream) ) { using (var reader = new StreamReader(stream)) {
content = reader.ReadToEnd(); content = reader.ReadToEnd();
} }
Assert.AreEqual(teststring, content); Assert.AreEqual(testString, content);
} }
[Test] [Test]
@@ -243,19 +234,17 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
using (var sr = new StreamReader(sf.OpenRead())) { using (var sr = new StreamReader(sf.OpenRead())) {
content = sr.ReadToEnd(); content = sr.ReadToEnd();
} }
Assert.That(content, Is.EqualTo("fo")); Assert.That(content, Is.EqualTo("fo"));
} }
[Test] [Test]
public void HttpContextWeaverShouldBeDisposed() public void HttpContextWeaverShouldBeDisposed() {
{
_azureBlobStorageProvider.CreateFile("foo1.txt"); _azureBlobStorageProvider.CreateFile("foo1.txt");
_azureBlobStorageProvider.CreateFile("foo2.txt"); _azureBlobStorageProvider.CreateFile("foo2.txt");
_azureBlobStorageProvider.CreateFile("foo3.txt"); _azureBlobStorageProvider.CreateFile("foo3.txt");
foreach(var f in _azureBlobStorageProvider.ListFiles("")) foreach (var _ in _azureBlobStorageProvider.ListFiles("")) {
{
Assert.That(HttpContext.Current, Is.Null); Assert.That(HttpContext.Current, Is.Null);
} }
} }
@@ -278,8 +267,7 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
[Test] [Test]
public void GetStoragePathShouldReturnAValidLocalPath() public void GetStoragePathShouldReturnAValidLocalPath() {
{
_azureBlobStorageProvider.CreateFile("folder1/foo.txt"); _azureBlobStorageProvider.CreateFile("folder1/foo.txt");
var publicPath = _azureBlobStorageProvider.GetPublicUrl("folder1/foo.txt"); var publicPath = _azureBlobStorageProvider.GetPublicUrl("folder1/foo.txt");
var storagePath = _azureBlobStorageProvider.GetStoragePath(publicPath); var storagePath = _azureBlobStorageProvider.GetStoragePath(publicPath);
@@ -289,12 +277,10 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
} }
[Test] [Test]
public void GetStoragePathShouldReturnNullIfPathIsNotLocal() public void GetStoragePathShouldReturnNullIfPathIsNotLocal() {
{
var storagePath = _azureBlobStorageProvider.GetStoragePath("http://orchardproject.net/foo"); var storagePath = _azureBlobStorageProvider.GetStoragePath("http://orchardproject.net/foo");
Assert.IsNull(storagePath); Assert.IsNull(storagePath);
} }
} }
} }
@@ -1,6 +1,7 @@
namespace Orchard.Azure { namespace Orchard.Azure {
public class Constants { public class Constants {
public const string DevelopmentStorageConnectionString = "UseDevelopmentStorage=true";
public const string ShellSettingsStorageConnectionStringSettingName = "Orchard.Azure.Settings.StorageConnectionString"; public const string ShellSettingsStorageConnectionStringSettingName = "Orchard.Azure.Settings.StorageConnectionString";
public const string ShellSettingsContainerNameSettingName = "Orchard.Azure.Settings.ContainerName"; public const string ShellSettingsContainerNameSettingName = "Orchard.Azure.Settings.ContainerName";
public const string ShellSettingsDefaultContainerName = "sites"; // Container names must be lower case. public const string ShellSettingsDefaultContainerName = "sites"; // Container names must be lower case.