Publish curated Knowledge Hub source from 2ed833f290b439a7bc91e5fd19b042c269e3bee9
This commit is contained in:
1 parent
10f2edcd29
commit
59f15b2d08
218 files changed
+23995
-1849
No files matched your search
@@ -0,0 +1,94 @@
|
||||
using System.Globalization;
|
||||
using ItWorx.KnowledgeHub.Domain.Jobs;
|
||||
|
||||
namespace ItWorx.KnowledgeHub.Domain.Tests;
|
||||
|
||||
public sealed class BackgroundJobTests
|
||||
{
|
||||
private static BackgroundJob NewJob(int total = 2) => BackgroundJob.Create(
|
||||
Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), BackgroundJobType.CourseTagging,
|
||||
"{}", new string('a', 64), new string('b', 64), "correlation", DateTimeOffset.UtcNow, total);
|
||||
|
||||
[Fact]
|
||||
public void A_retried_job_can_resume_and_finish_without_losing_its_original_start_time()
|
||||
{
|
||||
var job = NewJob();
|
||||
var now = DateTimeOffset.Parse("2026-10-02T12:00:00Z", CultureInfo.InvariantCulture);
|
||||
job.Start(Guid.NewGuid(), now, now.AddMinutes(1));
|
||||
job.ScheduleRetry(now.AddSeconds(1), now.AddSeconds(3), "worker_retry", "Tijdelijke fout.");
|
||||
|
||||
Assert.Equal(BackgroundJobStatus.Queued, job.Status);
|
||||
Assert.Equal(0, job.Failed);
|
||||
job.Start(Guid.NewGuid(), now.AddSeconds(3), now.AddMinutes(2));
|
||||
job.RecordOutcome(BackgroundJobItemState.Succeeded);
|
||||
job.RecordOutcome(BackgroundJobItemState.Succeeded);
|
||||
job.Complete(now.AddSeconds(4), "{\"complete\":true}");
|
||||
|
||||
Assert.Equal(BackgroundJobStatus.Succeeded, job.Status);
|
||||
Assert.Equal(now, job.StartedAt);
|
||||
Assert.Equal(2, job.Processed);
|
||||
Assert.Equal(2, job.Succeeded);
|
||||
Assert.Equal(100, job.Progress);
|
||||
Assert.Equal("{\"complete\":true}", job.ResultJson);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_worker_stops_after_three_retries_and_records_a_bounded_safe_failure()
|
||||
{
|
||||
var job = NewJob();
|
||||
var now = DateTimeOffset.Parse("2026-10-02T12:00:00Z", CultureInfo.InvariantCulture);
|
||||
|
||||
for (var attempt = 1; attempt <= 4; attempt++)
|
||||
{
|
||||
var attemptAt = now.AddSeconds(attempt * 10);
|
||||
job.Start(Guid.NewGuid(), attemptAt, attemptAt.AddMinutes(1));
|
||||
job.ScheduleRetry(attemptAt, attemptAt.AddSeconds(1), "processing_retry", "Veilige foutmelding.");
|
||||
if (attempt < 4)
|
||||
Assert.Equal(BackgroundJobStatus.Queued, job.Status);
|
||||
}
|
||||
|
||||
Assert.Equal(BackgroundJobStatus.Failed, job.Status);
|
||||
Assert.Equal(1, job.Failed);
|
||||
Assert.Equal(1, job.Processed);
|
||||
Assert.Equal(4, job.AttemptCount);
|
||||
Assert.True(job.ErrorsJson.Length < 4096);
|
||||
Assert.Contains("Veilige foutmelding", job.ErrorsJson, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Cancellation_is_immediate_for_queued_jobs_and_cooperative_for_running_jobs()
|
||||
{
|
||||
var queued = NewJob();
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
queued.RequestCancellation(now);
|
||||
Assert.Equal(BackgroundJobStatus.Cancelled, queued.Status);
|
||||
Assert.True(queued.IsTerminal);
|
||||
|
||||
var running = NewJob();
|
||||
running.Start(Guid.NewGuid(), now, now.AddMinutes(1));
|
||||
running.RequestCancellation(now.AddSeconds(1));
|
||||
Assert.Equal(BackgroundJobStatus.Running, running.Status);
|
||||
Assert.True(running.CancelRequestedAt.HasValue);
|
||||
running.Cancel(now.AddSeconds(2));
|
||||
Assert.Equal(BackgroundJobStatus.Cancelled, running.Status);
|
||||
Assert.Equal(0, running.Processed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Errors_are_capped_and_result_json_is_bounded()
|
||||
{
|
||||
var job = NewJob(30);
|
||||
for (var index = 0; index < 30; index++)
|
||||
job.RecordOutcome(BackgroundJobItemState.Failed, "page_failed", new string('x', 500), Guid.NewGuid());
|
||||
job.Complete(DateTimeOffset.UtcNow, new string('z', 5000));
|
||||
|
||||
Assert.Equal(BackgroundJobStatus.Failed, job.Status);
|
||||
Assert.Null(job.ResultJson);
|
||||
Assert.Equal(BackgroundJob.MaxStoredErrors, System.Text.Json.JsonSerializer.Deserialize<BackgroundJobError[]>(job.ErrorsJson)!.Length);
|
||||
Assert.All(System.Text.Json.JsonSerializer.Deserialize<BackgroundJobError[]>(job.ErrorsJson)!, error =>
|
||||
{
|
||||
Assert.Equal(BackgroundJob.MaxErrorMessageLength, error.Message.Length);
|
||||
Assert.Equal("page_failed", error.Code);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -28,9 +28,14 @@ public sealed class InfrastructureKnowledgeTests
|
||||
var service = InfrastructureService.Create(
|
||||
Guid.NewGuid(), "docker:knowledge-hub", "knowledge-hub", now, Guid.NewGuid());
|
||||
service.Confirm();
|
||||
service.Refresh(null, "knowledge-hub", "container", "running", HealthState.Healthy,
|
||||
"example/image", "", "", false, true, false, FactConfidence.High, Guid.NewGuid(), now);
|
||||
|
||||
service.MarkMissing(now.AddMinutes(1));
|
||||
Assert.Equal(InventoryPresence.Missing, service.Presence);
|
||||
Assert.Equal(HealthState.Unknown, service.Health);
|
||||
Assert.Equal("unknown", service.RuntimeStatus);
|
||||
Assert.Equal(now, service.LastSeenAt);
|
||||
|
||||
service.Refresh(
|
||||
null, "knowledge-hub", "container", "running", HealthState.Healthy,
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
using ItWorx.KnowledgeHub.Domain.Sources;
|
||||
|
||||
namespace ItWorx.KnowledgeHub.Domain.Tests.Sources;
|
||||
|
||||
public sealed class DataSourceTests
|
||||
{
|
||||
private static readonly DateTimeOffset Now = new(2026, 10, 2, 0, 0, 0, TimeSpan.Zero);
|
||||
|
||||
[Fact]
|
||||
public void A_registered_source_is_unknown_until_it_has_observed_evidence()
|
||||
{
|
||||
var source = DataSource.Create(Guid.NewGuid(), "inventory:test", "Inventory", DataSourceKind.Inventory, 24, Now);
|
||||
Assert.Equal("Unknown", source.GetState(Now));
|
||||
Assert.Null(source.LastSuccessAt);
|
||||
Assert.Null(source.RecordCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Newer_failure_outweighs_earlier_success_and_stale_success_is_not_current()
|
||||
{
|
||||
var source = DataSource.Create(Guid.NewGuid(), "inventory:test", "Inventory", DataSourceKind.Inventory, 24, Now);
|
||||
source.Observe(true, 12, null, "run1", Now);
|
||||
Assert.Equal("Current", source.GetState(Now));
|
||||
Assert.Equal("Stale", source.GetState(Now.AddHours(25)));
|
||||
source.Observe(false, null, "connectivity", "run2", Now.AddHours(1));
|
||||
Assert.Equal("Failed", source.GetState(Now.AddHours(1)));
|
||||
Assert.Equal(12, source.RecordCount);
|
||||
Assert.Throws<ArgumentException>(() => source.Observe(true, 99, null, "older", Now.AddMinutes(-1)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Importing_old_data_does_not_refresh_its_freshness()
|
||||
{
|
||||
var source = DataSource.Create(Guid.NewGuid(), "inventory:test", "Inventory", DataSourceKind.Inventory, 24, Now);
|
||||
source.Observe(true, 12, null, "import", Now, Now.AddDays(-2));
|
||||
Assert.Equal("Stale", source.GetState(Now));
|
||||
Assert.Equal(Now, source.LastSuccessAt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Disabling_preserves_prior_evidence_and_observations_require_safe_error_codes()
|
||||
{
|
||||
var source = DataSource.Create(Guid.NewGuid(), "inventory:test", "Inventory", DataSourceKind.Inventory, 24, Now);
|
||||
source.Observe(true, 12, null, "run1", Now);
|
||||
source.Configure("Inventory", false, 24);
|
||||
Assert.Equal("Disabled", source.GetState(Now));
|
||||
Assert.Equal(Now, source.LastSuccessAt);
|
||||
Assert.Throws<ArgumentException>(() => source.Observe(false, null, "secret connection string", "run2", Now));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user