88 lines
3.6 KiB
C#
88 lines
3.6 KiB
C#
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using w4c_workflows.Services;
|
|
using w4c_workflows.Services.Runs;
|
|
using Xunit;
|
|
|
|
namespace w4c_workflows.Tests;
|
|
|
|
/// <summary>
|
|
/// Regression: the run's working directory must be resolved from the tenant's OWN
|
|
/// source directory (the same one the workflow-file writer uses), never the
|
|
/// global/git root. Before the fix, <see cref="TaskDispatcher"/> fell back to the
|
|
/// git root when not in Forgejo-backed mode, so a freshly created workflow's entry
|
|
/// file (e.g. <c>Main.cs</c>) was not found at run time ("entry file not found:
|
|
/// Main.cs").
|
|
/// </summary>
|
|
public class TaskDispatcherWorkingDirTests
|
|
{
|
|
private static WorkflowSourceFactory NewFactory(string copiesRoot) =>
|
|
new(
|
|
new ConfigurationBuilder()
|
|
.AddInMemoryCollection(new Dictionary<string, string?>
|
|
{
|
|
["WorkflowSource:CopiesRoot"] = copiesRoot,
|
|
})
|
|
.Build(),
|
|
env: null!, // unused by the factory, keep the test free of ASP.NET types
|
|
NullLoggerFactory.Instance);
|
|
|
|
private static TaskDispatcher NewDispatcher(string copiesRoot) =>
|
|
new(
|
|
db: null!, // not used by ResolveWorkingDir
|
|
jobs: null!, // not used by ResolveWorkingDir
|
|
config: new ConfigurationBuilder().Build(),
|
|
logger: NullLogger<TaskDispatcher>.Instance,
|
|
sourceFactory: NewFactory(copiesRoot));
|
|
|
|
[Fact]
|
|
public async Task ResolveWorkingDir_uses_tenant_copies_root_not_git_root()
|
|
{
|
|
using var tmp = new TempDir();
|
|
var dispatcher = NewDispatcher(tmp.Path);
|
|
|
|
// A workflow definition stored under the tenant's own dir, referenced as a
|
|
// repo-relative path with the shared "workflows" prefix.
|
|
var workingDir = dispatcher.ResolveWorkingDir("tenant-1", "workflows/test/workflow.yaml");
|
|
|
|
// The run must resolve inside the tenant's CopiesRoot directory, i.e. exactly
|
|
// where WorkflowFilesController.SaveFile writes the code files.
|
|
var expected = Path.Combine(tmp.Path, "tenant-1", "workflows", "test");
|
|
Assert.Equal(Path.GetFullPath(expected), Path.GetFullPath(workingDir));
|
|
|
|
// And the entry file must actually exist there — proving "entry file not
|
|
// found: Main.cs" can no longer happen for a correctly scaffolded workflow.
|
|
Directory.CreateDirectory(expected);
|
|
var entry = Path.Combine(expected, "Main.cs");
|
|
await File.WriteAllTextAsync(entry, "public static class Program { }");
|
|
Assert.True(File.Exists(entry));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ResolveWorkingDirAsync_uses_tenant_copies_root_not_git_root()
|
|
{
|
|
using var tmp = new TempDir();
|
|
var dispatcher = NewDispatcher(tmp.Path);
|
|
|
|
var workingDir = await dispatcher.ResolveWorkingDirAsync(
|
|
"tenant-2", "workflows/ship/workflow.yaml", default);
|
|
|
|
var expected = Path.Combine(tmp.Path, "tenant-2", "workflows", "ship");
|
|
Assert.Equal(Path.GetFullPath(expected), Path.GetFullPath(workingDir));
|
|
}
|
|
|
|
[Fact]
|
|
public void ResolveWorkingDir_without_factory_falls_back_to_global_root()
|
|
{
|
|
var dispatcher = new TaskDispatcher(
|
|
db: null!,
|
|
jobs: null!,
|
|
config: new ConfigurationBuilder().Build(),
|
|
logger: NullLogger<TaskDispatcher>.Instance);
|
|
|
|
// No source factory configured: must not throw, returns a deterministic path.
|
|
var workingDir = dispatcher.ResolveWorkingDir("t-1", "workflows/a/workflow.yaml");
|
|
Assert.False(string.IsNullOrWhiteSpace(workingDir));
|
|
}
|
|
}
|