Add impact index fixture and filesystem artifact uploader
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Introduced a sample BOM index JSON file for impact index testing. - Created unit tests for the impact index fixture to ensure proper loading of sample images. - Implemented the FilesystemPackRunArtifactUploader class to handle artifact uploads to the local filesystem. - Added comprehensive tests for the FilesystemPackRunArtifactUploader, covering file copying, missing files, and expression outputs.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"schema": "scheduler-impact-index@1",
|
||||
"generatedAt": "2025-10-01T00:00:00Z",
|
||||
"image": {
|
||||
"repository": "registry.stellaops.test/team/sample-service",
|
||||
"digest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
||||
"tag": "1.0.0"
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"purl": "pkg:docker/sample-service@1.0.0",
|
||||
"usage": [
|
||||
"runtime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"purl": "pkg:pypi/requests@2.31.0",
|
||||
"usage": [
|
||||
"usedByEntrypoint"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
<ProjectReference Include="../StellaOps.Scheduler.Models/StellaOps.Scheduler.Models.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Fixtures\**\*.json" />
|
||||
<EmbeddedResource Include="..\..\samples\scanner\images\**\bom-index.json"
|
||||
Link="Fixtures\%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using StellaOps.Scheduler.ImpactIndex;
|
||||
using StellaOps.Scheduler.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Scheduler.WebService.Tests;
|
||||
|
||||
public sealed class ImpactIndexFixtureTests
|
||||
{
|
||||
[Fact]
|
||||
public void FixtureDirectoryExists()
|
||||
{
|
||||
var fixtureDirectory = GetFixtureDirectory();
|
||||
Assert.True(Directory.Exists(fixtureDirectory), $"Fixture directory not found: {fixtureDirectory}");
|
||||
|
||||
var files = Directory.EnumerateFiles(fixtureDirectory, "bom-index.json", SearchOption.AllDirectories).ToArray();
|
||||
Assert.NotEmpty(files);
|
||||
|
||||
var sampleFile = Path.Combine(fixtureDirectory, "sample", "bom-index.json");
|
||||
Assert.Contains(sampleFile, files);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FixtureImpactIndexLoadsSampleImage()
|
||||
{
|
||||
var fixtureDirectory = GetFixtureDirectory();
|
||||
var options = new ImpactIndexStubOptions
|
||||
{
|
||||
FixtureDirectory = fixtureDirectory,
|
||||
SnapshotId = "tests/impact-index-stub"
|
||||
};
|
||||
|
||||
var index = new FixtureImpactIndex(options, TimeProvider.System, NullLogger<FixtureImpactIndex>.Instance);
|
||||
var selector = new Selector(SelectorScope.AllImages);
|
||||
|
||||
var impactSet = await index.ResolveAllAsync(selector, usageOnly: false);
|
||||
|
||||
Assert.True(impactSet.Total > 0, "Expected the fixture impact index to load at least one image.");
|
||||
}
|
||||
|
||||
private static string GetFixtureDirectory()
|
||||
{
|
||||
var assemblyLocation = typeof(SchedulerWebApplicationFactory).Assembly.Location;
|
||||
var assemblyDirectory = Path.GetDirectoryName(assemblyLocation)
|
||||
?? AppContext.BaseDirectory;
|
||||
|
||||
return Path.GetFullPath(Path.Combine(assemblyDirectory, "seed-data", "impact-index"));
|
||||
}
|
||||
}
|
||||
@@ -11,16 +11,16 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using StellaOps.Scheduler.Models;
|
||||
using StellaOps.Scheduler.Queue;
|
||||
using StellaOps.Scheduler.Storage.Mongo.Repositories;
|
||||
|
||||
namespace StellaOps.Scheduler.WebService.Tests;
|
||||
|
||||
public sealed class RunEndpointTests : IClassFixture<WebApplicationFactory<Program>>
|
||||
{
|
||||
private readonly WebApplicationFactory<Program> _factory;
|
||||
|
||||
public RunEndpointTests(WebApplicationFactory<Program> factory)
|
||||
{
|
||||
_factory = factory;
|
||||
|
||||
namespace StellaOps.Scheduler.WebService.Tests;
|
||||
|
||||
public sealed class RunEndpointTests : IClassFixture<WebApplicationFactory<Program>>
|
||||
{
|
||||
private readonly WebApplicationFactory<Program> _factory;
|
||||
|
||||
public RunEndpointTests(WebApplicationFactory<Program> factory)
|
||||
{
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -100,13 +100,13 @@ public sealed class RunEndpointTests : IClassFixture<WebApplicationFactory<Progr
|
||||
var scheduleId = scheduleJson.GetProperty("schedule").GetProperty("id").GetString();
|
||||
Assert.False(string.IsNullOrEmpty(scheduleId));
|
||||
|
||||
var previewResponse = await client.PostAsJsonAsync("/api/v1/scheduler/runs/preview", new
|
||||
{
|
||||
scheduleId,
|
||||
usageOnly = true,
|
||||
sampleSize = 3
|
||||
});
|
||||
|
||||
var previewResponse = await client.PostAsJsonAsync("/api/v1/scheduler/runs/preview", new
|
||||
{
|
||||
scheduleId,
|
||||
usageOnly = true,
|
||||
sampleSize = 3
|
||||
});
|
||||
|
||||
previewResponse.EnsureSuccessStatusCode();
|
||||
var preview = await previewResponse.Content.ReadFromJsonAsync<JsonElement>();
|
||||
Assert.True(preview.GetProperty("total").GetInt32() >= 0);
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using StellaOps.Scheduler.WebService.Options;
|
||||
using StellaOps.Scheduler.WebService.Runs;
|
||||
using StellaOps.Scheduler.ImpactIndex;
|
||||
|
||||
namespace StellaOps.Scheduler.WebService.Tests;
|
||||
|
||||
@@ -15,6 +18,8 @@ public sealed class SchedulerWebApplicationFactory : WebApplicationFactory<Progr
|
||||
{
|
||||
builder.ConfigureAppConfiguration((_, configuration) =>
|
||||
{
|
||||
var fixtureDirectory = GetFixtureDirectory();
|
||||
|
||||
configuration.AddInMemoryCollection(new[]
|
||||
{
|
||||
new KeyValuePair<string, string?>("Scheduler:Authority:Enabled", "false"),
|
||||
@@ -27,12 +32,22 @@ public sealed class SchedulerWebApplicationFactory : WebApplicationFactory<Progr
|
||||
new KeyValuePair<string, string?>("Scheduler:Events:Webhooks:Excitor:Enabled", "true"),
|
||||
new KeyValuePair<string, string?>("Scheduler:Events:Webhooks:Excitor:HmacSecret", "excitor-secret"),
|
||||
new KeyValuePair<string, string?>("Scheduler:Events:Webhooks:Excitor:RateLimitRequests", "20"),
|
||||
new KeyValuePair<string, string?>("Scheduler:Events:Webhooks:Excitor:RateLimitWindowSeconds", "60")
|
||||
new KeyValuePair<string, string?>("Scheduler:Events:Webhooks:Excitor:RateLimitWindowSeconds", "60"),
|
||||
new KeyValuePair<string, string?>("Scheduler:ImpactIndex:FixtureDirectory", fixtureDirectory)
|
||||
});
|
||||
});
|
||||
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
var fixtureDirectory = GetFixtureDirectory();
|
||||
|
||||
services.RemoveAll<ImpactIndexStubOptions>();
|
||||
services.AddSingleton(new ImpactIndexStubOptions
|
||||
{
|
||||
FixtureDirectory = fixtureDirectory,
|
||||
SnapshotId = "tests/impact-index-stub"
|
||||
});
|
||||
|
||||
services.Configure<SchedulerEventsOptions>(options =>
|
||||
{
|
||||
options.Webhooks ??= new SchedulerInboundWebhooksOptions();
|
||||
@@ -52,4 +67,14 @@ public sealed class SchedulerWebApplicationFactory : WebApplicationFactory<Progr
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static string GetFixtureDirectory()
|
||||
{
|
||||
var assemblyLocation = typeof(SchedulerWebApplicationFactory).Assembly.Location;
|
||||
var assemblyDirectory = Path.GetDirectoryName(assemblyLocation)
|
||||
?? AppContext.BaseDirectory;
|
||||
|
||||
var fixtureDirectory = Path.Combine(assemblyDirectory, "seed-data", "impact-index");
|
||||
return Path.GetFullPath(fixtureDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,9 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../StellaOps.Scheduler.WebService/StellaOps.Scheduler.WebService.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="seed-data/impact-index/**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"schema": "scheduler-impact-index@1",
|
||||
"generatedAt": "2025-10-01T00:00:00Z",
|
||||
"image": {
|
||||
"repository": "registry.stellaops.test/team/sample-service",
|
||||
"digest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
||||
"tag": "1.0.0"
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"purl": "pkg:docker/sample-service@1.0.0",
|
||||
"usage": [
|
||||
"runtime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"purl": "pkg:pypi/requests@2.31.0",
|
||||
"usage": [
|
||||
"usedByEntrypoint"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user