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

View File

@@ -7,7 +7,6 @@ on:
branches:
- 1.10.x
- dev
- task/nuget-updates
schedule:
- cron: '0 0 * * 1' # Every Monday midnight.

View File

@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<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.Media.StorageConnectionString" value="UseDevelopmentStorage=true" />
</appSettings>

View File

@@ -1,77 +1,49 @@
using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using NUnit.Framework;
using Orchard.Azure.Services.Environment.Configuration;
namespace Orchard.Azure.Tests {
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();
[OneTimeSetUp]
public void FixtureSetup() {
if (!Process.GetProcessesByName("AzureStorageEmulator").Any()) {
var azureSDKPath = ConfigurationManager.AppSettings["AzureSDK"];
var storageEmulatorRelativePath = "Storage Emulator\\AzureStorageEmulator.exe";
var connectionString = PlatformConfigurationAccessor.GetSetting(StorageConnectionStringName, "default", "");
if (String.IsNullOrEmpty(azureSDKPath)) {
throw new ConfigurationErrorsException("Could not find the AppSetting \"AzureSDK\" that indicates the path to the Azure SDK on the local file system.");
}
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();
}
CloudStorageAccount.TryParse(connectionString, out CloudStorageAccount devAccount);
DevAccount = devAccount;
OnInit();
}
[OneTimeTearDown]
public void FixtureTearDown() {
if (_storageEmulator != null)
_storageEmulator.Close();
}
protected void DeleteAllBlobs(string containerName, CloudStorageAccount account) {
var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference(containerName);
foreach (var blob in container.ListBlobs()) {
if (blob is CloudBlob) {
((CloudBlob)blob).DeleteIfExists();
if (blob is CloudBlob blobLeaf) {
blobLeaf.DeleteIfExists();
}
if (blob is CloudBlobDirectory) {
DeleteAllBlobs((CloudBlobDirectory)blob);
if (blob is CloudBlobDirectory directory) {
DeleteAllBlobs(directory);
}
}
}
private static void DeleteAllBlobs(CloudBlobDirectory cloudBlobDirectory) {
foreach (var blob in cloudBlobDirectory.ListBlobs()) {
if (blob is CloudBlob) {
((CloudBlob)blob).DeleteIfExists();
if (blob is CloudBlob blobLeaf) {
blobLeaf.DeleteIfExists();
}
if (blob is CloudBlobDirectory) {
DeleteAllBlobs((CloudBlobDirectory)blob);
if (blob is CloudBlobDirectory directory) {
DeleteAllBlobs(directory);
}
}
}

View File

@@ -1,5 +1,4 @@
using System.Linq;
using Microsoft.WindowsAzure.Storage;
using NUnit.Framework;
using Orchard.Azure.Services.Environment.Configuration;
using Orchard.Environment.Configuration;
@@ -8,14 +7,14 @@ using Orchard.FileSystems.Media;
namespace Orchard.Azure.Tests.Environment.Configuration {
[TestFixture]
public class AzureShellSettingsManagerTests : AzureVirtualEnvironmentTest {
private IShellSettingsManager _shellSettingsManager;
protected CloudStorageAccount DevAccount;
protected IShellSettingsManager ShellSettingsManager;
protected override string StorageConnectionStringName { get; } = Constants.ShellSettingsStorageConnectionStringSettingName;
protected override void OnInit() {
CloudStorageAccount.TryParse("UseDevelopmentStorage=true", out DevAccount);
ShellSettingsManager = new AzureBlobShellSettingsManager(new Moq.Mock<IMimeTypeProvider>().Object, new Moq.Mock<IShellSettingsManagerEventHandler>().Object);
_shellSettingsManager = new AzureBlobShellSettingsManager(
new Moq.Mock<IMimeTypeProvider>().Object,
new Moq.Mock<IShellSettingsManagerEventHandler>().Object);
}
[SetUp]
@@ -33,9 +32,9 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test]
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.Name, Is.EqualTo("Default"));
Assert.That(settings.DataProvider, Is.EqualTo("SQLCe"));
@@ -44,10 +43,10 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test]
public void SettingsShouldBeOverwritable() {
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 = "SQLCe", DataConnectionString = "something else" });
_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.Name, Is.EqualTo("Default"));
Assert.That(settings.DataProvider, Is.EqualTo("SQLCe2"));
@@ -57,10 +56,10 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test]
public void MultipleFilesCanBeDetected() {
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 = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" });
_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));
var def = settings.Single(x => x.Name == "Default");
@@ -76,15 +75,15 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test]
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" };
Assert.That(ShellSettingsManager.LoadSettings().Count(), Is.EqualTo(1));
ShellSettingsManager.SaveSettings(foo);
Assert.That(ShellSettingsManager.LoadSettings().Count(), Is.EqualTo(2));
Assert.That(_shellSettingsManager.LoadSettings().Count(), Is.EqualTo(1));
_shellSettingsManager.SaveSettings(foo);
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.DataProvider, Does.Contain("Bar"));
Assert.That(foo.DataConnectionString, Does.Contain("Quux"));
@@ -92,9 +91,9 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test]
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;"));
}
}

View File

@@ -1,52 +1,46 @@
using System;
using System.IO;
using System.Linq;
using System.Web;
using NUnit.Framework;
using System.Linq;
using Orchard.Environment.Configuration;
using Orchard.Azure.Services.FileSystems.Media;
using Orchard.Environment.Configuration;
using Orchard.FileSystems.Media;
using Microsoft.WindowsAzure.Storage;
using Orchard.Azure.Services.Environment.Configuration;
namespace Orchard.Azure.Tests.FileSystems.Media {
[TestFixture]
public class AzureBlobStorageProviderTests : AzureVirtualEnvironmentTest {
private CloudStorageAccount _devAccount;
private IPlatformConfigurationAccessor _platformConfigurationAccessor;
private AzureBlobStorageProvider _azureBlobStorageProvider;
protected override void OnInit() {
protected override string StorageConnectionStringName { get; } = Constants.MediaStorageStorageConnectionStringSettingName;
CloudStorageAccount.TryParse("UseDevelopmentStorage=true", out _devAccount);
_platformConfigurationAccessor = new DefaultPlatformConfigurationAccessor();
_azureBlobStorageProvider = new AzureBlobStorageProvider(new ShellSettings { Name = "default" }, new ConfigurationMimeTypeProvider(), _platformConfigurationAccessor);
protected override void OnInit() {
_azureBlobStorageProvider = new AzureBlobStorageProvider(
new ShellSettings { Name = "default" },
new ConfigurationMimeTypeProvider(),
PlatformConfigurationAccessor);
}
[SetUp]
public void Setup() {
// ensure default container is empty before running any test
DeleteAllBlobs(_azureBlobStorageProvider.Container.Name, _devAccount);
DeleteAllBlobs(_azureBlobStorageProvider.Container.Name, DevAccount);
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void GetFileShouldOnlyAcceptRelativePath() {
_azureBlobStorageProvider.CreateFile("foo.txt");
_azureBlobStorageProvider.GetFile("/foo.txt");
Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.GetFile("/foo.txt"));
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void GetFileThatDoesNotExistShouldThrow() {
_azureBlobStorageProvider.GetFile("notexisting");
Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.GetFile("notexisting"));
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void DeleteFileThatDoesNotExistShouldThrow() {
_azureBlobStorageProvider.DeleteFile("notexisting");
Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.DeleteFile("notexisting"));
}
[Test]
@@ -72,12 +66,11 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void CreateFileShouldThrowAnExceptionIfAlreadyExisting() {
var storageFile = _azureBlobStorageProvider.CreateFile("foo.txt");
Assert.AreEqual(storageFile.GetSize(), 0);
_azureBlobStorageProvider.CreateFile("foo.txt");
Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.CreateFile("foo.txt"));
}
[Test]
@@ -108,10 +101,9 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void CreateFolderThatExistsShouldThrow() {
_azureBlobStorageProvider.CreateFile("folder/foo.txt");
_azureBlobStorageProvider.CreateFolder("folder");
Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.CreateFolder("folder"));
}
[Test]
@@ -196,10 +188,9 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void CannotCreateAlreadyExistingFolders() {
_azureBlobStorageProvider.CreateFile("folder1/foo.txt");
_azureBlobStorageProvider.CreateFolder("folder1");
Assert.Throws<ArgumentException>(() => _azureBlobStorageProvider.CreateFolder("folder1"));
}
[Test]
@@ -210,21 +201,21 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
[Test]
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");
using ( var stream = foo.OpenWrite() )
using ( var writer = new StreamWriter(stream) )
writer.Write(teststring);
using (var stream = foo.OpenWrite())
using (var writer = new StreamWriter(stream))
writer.Write(testString);
string content;
using ( var stream = foo.OpenRead() )
using ( var reader = new StreamReader(stream) ) {
using (var stream = foo.OpenRead())
using (var reader = new StreamReader(stream)) {
content = reader.ReadToEnd();
}
Assert.AreEqual(teststring, content);
Assert.AreEqual(testString, content);
}
[Test]
@@ -243,19 +234,17 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
using (var sr = new StreamReader(sf.OpenRead())) {
content = sr.ReadToEnd();
}
Assert.That(content, Is.EqualTo("fo"));
}
[Test]
public void HttpContextWeaverShouldBeDisposed()
{
public void HttpContextWeaverShouldBeDisposed() {
_azureBlobStorageProvider.CreateFile("foo1.txt");
_azureBlobStorageProvider.CreateFile("foo2.txt");
_azureBlobStorageProvider.CreateFile("foo3.txt");
foreach(var f in _azureBlobStorageProvider.ListFiles(""))
{
foreach (var _ in _azureBlobStorageProvider.ListFiles("")) {
Assert.That(HttpContext.Current, Is.Null);
}
}
@@ -278,8 +267,7 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
[Test]
public void GetStoragePathShouldReturnAValidLocalPath()
{
public void GetStoragePathShouldReturnAValidLocalPath() {
_azureBlobStorageProvider.CreateFile("folder1/foo.txt");
var publicPath = _azureBlobStorageProvider.GetPublicUrl("folder1/foo.txt");
var storagePath = _azureBlobStorageProvider.GetStoragePath(publicPath);
@@ -289,12 +277,10 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
}
[Test]
public void GetStoragePathShouldReturnNullIfPathIsNotLocal()
{
public void GetStoragePathShouldReturnNullIfPathIsNotLocal() {
var storagePath = _azureBlobStorageProvider.GetStoragePath("http://orchardproject.net/foo");
Assert.IsNull(storagePath);
}
}
}

View File

@@ -1,6 +1,7 @@
namespace Orchard.Azure {
public class Constants {
public const string DevelopmentStorageConnectionString = "UseDevelopmentStorage=true";
public const string ShellSettingsStorageConnectionStringSettingName = "Orchard.Azure.Settings.StorageConnectionString";
public const string ShellSettingsContainerNameSettingName = "Orchard.Azure.Settings.ContainerName";
public const string ShellSettingsDefaultContainerName = "sites"; // Container names must be lower case.