Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OFFI-142: Handle dynamic setup operation #415

Merged
merged 4 commits into from
Oct 14, 2024
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
11 changes: 11 additions & 0 deletions Lombiq.Tests.UI.Samples/UITestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ protected override Task ExecuteTestAsync(
"OrchardCore.Media.Core.DefaultMediaFileStoreCacheFileProvider|ERROR|Error deleting cache folder",
]);

// Strictly speaking this is not necessary here, because we always use the same static method for setup.
// However, if you used a dynamic setup operation (e.g. `context => SetupHelpers.RunSetupAsync(context,
// someOtherVariable)` then the default setup identifier calculator would always return a new random
// value, because it uses `setupOperation.GetHashCode()` under the hood. A custom calculator would fix
// that. But in this example we just safely replace it with a human-readable name so the setup snapshot
// directory is easier to find.
configuration.SetupConfiguration.SetupOperationIdentifierCalculator = setupOperation =>
setupOperation == SetupHelpers.RunSetupAsync
? "Sample Setup"
: OrchardCoreSetupConfiguration.DefaultSetupOperationIdentifierCalculator(setupOperation);

if (changeConfigurationAsync != null) await changeConfigurationAsync(configuration);
});
}
Expand Down
19 changes: 19 additions & 0 deletions Lombiq.Tests.UI/Services/OrchardCoreSetupConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ namespace Lombiq.Tests.UI.Services;
/// </summary>
public class OrchardCoreSetupConfiguration
{
public static readonly Func<Func<UITestContext, Task<Uri>>, string> DefaultSetupOperationIdentifierCalculator =
setupOperation => setupOperation.GetHashCode().ToTechnicalString();

/// <summary>
/// Gets or sets the Orchard setup operation so the result can be snapshot and used in subsequent tests.
/// WARNING: It's highly recommended to put assertions at the end to detect setup issues and fail tests early (since
Expand All @@ -21,6 +24,15 @@ public class OrchardCoreSetupConfiguration
/// </summary>
public Func<UITestContext, Task<Uri>> SetupOperation { get; set; }

/// <summary>
/// Gets or sets a function that calculates a unique ID which represents the setup operation. This is used when
/// generating the setup snapshot path. If you set the <see cref="SetupOperation"/> to a dynamic value (e.g. using a
/// lambda expression or a method that returns a new <see cref="Func{T,TResult}"/> instance) then you must set this
/// property to a custom function. Otherwise, it's safe to leave it as-is.
/// </summary>
public Func<Func<UITestContext, Task<Uri>>, string> SetupOperationIdentifierCalculator { get; set; } =
DefaultSetupOperationIdentifierCalculator;

/// <summary>
/// Gets or sets a value indicating whether if a specific setup operations fails and exhausts <see
/// cref="OrchardCoreUITestExecutorConfiguration.MaxRetryCount"/> globally then all tests using the same operation
Expand All @@ -37,4 +49,11 @@ public class OrchardCoreSetupConfiguration

public BeforeSetupHandler BeforeSetup { get; set; }
public AfterSetupHandler AfterSetup { get; set; }

/// <summary>
/// If <see cref="SetupOperation"/> is not <see langword="null"/>, it invokes <see
/// cref="SetupOperationIdentifierCalculator"/> with the <see cref="SetupOperation"/> and returns the result.
/// </summary>
public string CalculateSetupOperationIdentifier() =>
SetupOperation is null ? null : SetupOperationIdentifierCalculator(SetupOperation);
}
10 changes: 6 additions & 4 deletions Lombiq.Tests.UI/Services/UITestExecutionSession.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Atata.HtmlValidation;
using Cysharp.Text;
using Lombiq.HelpfulLibraries.Common.Utilities;
using Lombiq.Tests.UI.Constants;
using Lombiq.Tests.UI.Exceptions;
Expand Down Expand Up @@ -452,7 +453,7 @@ private async Task SetupAsync()
snapshotSubdirectory = "SQLite-AzureBlob";
}

snapshotSubdirectory += "-" + setupConfiguration.SetupOperation!.GetHashCode().ToTechnicalString();
snapshotSubdirectory += "-" + setupConfiguration.CalculateSetupOperationIdentifier();

_snapshotDirectoryPath = Path.Combine(setupConfiguration.SetupSnapshotDirectoryPath, snapshotSubdirectory);

Expand Down Expand Up @@ -661,9 +662,10 @@ Task UITestingBeforeAppStartHandlerAsync(OrchardCoreAppStartContext context, Ins
}

private string GetSetupHashCode() =>
_configuration.SetupConfiguration.SetupOperation.GetHashCode().ToTechnicalString() +
_configuration.UseSqlServer +
_configuration.UseAzureBlobStorage;
ZString.Concat(
_configuration.SetupConfiguration.CalculateSetupOperationIdentifier(),
_configuration.UseSqlServer,
_configuration.UseAzureBlobStorage);

private Task OnAssertLogsAsync(UITestContext context) => context.AssertLogsAsync();

Expand Down