public async Task ExtractOwnershipFromK8sAudit() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var cache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions())); var processor = new ExtractOwnershipProcessor(context, cache); context.Ownership.Count().Should().Be(0, "ownership list should be empty"); var auditMetaPath = Path.Combine("audits", "samples", "k8s_audit.json"); var audit = new Audit { MetadataKube = new MetadataKube { Id = 1, AuditId = string.Empty, Date = DateTime.Now, JSON = File.ReadAllText(auditMetaPath), }, }; await processor.Process(audit, CancellationToken.None); var list = context.Ownership.ToList(); context.Ownership.Count().Should().Be(2, "ownership list should have 2 items"); }
public async Task ExtractOwnershipFromAzskAudit() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); context.Ownership.Count().Should().Be(0, "ownership list should be empty"); var cache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions())); var processor = new ExtractOwnershipProcessor(context, cache); var auditMetaPath = Path.Combine("audits", "samples", "azsk_audit.json"); var audit = new Audit { MetadataAzure = new MetadataAzure { Id = 1, AuditId = string.Empty, Date = DateTime.Now, JSON = File.ReadAllText(auditMetaPath), }, }; await processor.Process(audit, CancellationToken.None); var list = context.Ownership.ToList(); context.Ownership.Count().Should().Be(17, "ownership list should have 17 items"); foreach (var expectedComponentId in azskAuditComponentIds) { var item = context.Ownership.FirstOrDefault(x => x.ComponentId == expectedComponentId); item.Should().NotBe(null, expectedComponentId); } }
public async Task SaveInProgressImageScanSavesCorrectEntity() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var db = new MssqlJosekiDatabase(context, parser); var scan = new ImageScanResultWithCVEs { Date = DateTime.UtcNow, Id = Guid.NewGuid().ToString(), Description = Guid.NewGuid().ToString(), ImageTag = Guid.NewGuid().ToString(), Status = ImageScanStatus.Queued, }; // Act & Assert context.ImageScanResult.Should().HaveCount(0); await db.SaveInProgressImageScan(scan); context.ImageScanResult.Should().HaveCount(1); var actual = await context.ImageScanResult.FirstAsync(); actual.Date.Should().Be(scan.Date); actual.ExternalId.Should().Be(scan.Id); actual.Description.Should().Be(scan.Description); actual.ImageTag.Should().Be(scan.ImageTag); actual.Status.Should().Be(joseki.db.entities.ImageScanStatus.Queued); }
public async Task GetLastMonthAuditsReturnsOnlyRequestedComponentAudits() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); var auditDate = DateTime.UtcNow.Date.AddDays(-1); var expectedComponent = this.GenerateComponent(); var anotherComponent = this.GenerateComponent(); await context.Audit.AddRangeAsync(new[] { new AuditEntity { Date = auditDate, ComponentId = expectedComponent.ComponentId, InfrastructureComponent = expectedComponent }, new AuditEntity { Date = DateTime.UtcNow.AddDays(-2), ComponentId = anotherComponent.ComponentId, InfrastructureComponent = anotherComponent }, }); await context.SaveChangesAsync(); // Act & Assert var audits = await wrapper.GetLastMonthAudits(expectedComponent.ComponentId); audits.Should().ContainSingle(a => a.ComponentId == expectedComponent.ComponentId && a.Date == auditDate); }
public async Task SaveAuditResultSavesKubeMetadata() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var db = new MssqlJosekiDatabase(context, parser); var audit = new Audit { MetadataKube = new MetadataKube { Date = DateTime.UtcNow, JSON = Guid.NewGuid().ToString(), }, }; // Act & Assert context.MetadataKube.Should().HaveCount(0); await db.SaveAuditResult(audit); context.MetadataKube.Should().HaveCount(1); var actual = await context.MetadataKube.FirstAsync(); actual.JSON.Should().Be(audit.MetadataKube.JSON); actual.Date.Should().Be(audit.MetadataKube.Date); }
public async Task GetAuditsReturnsOnlyLatestAuditAtRequestedDate() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); // create three audits a day before at 00:00, 08:00, 16:00 var component = this.GenerateComponent(); var auditDate = DateTime.UtcNow.Date.AddDays(-1); var entities = Enumerable .Range(0, 3) .Select(i => new AuditEntity { Date = auditDate.AddHours(i * 8), ComponentId = component.ComponentId, InfrastructureComponent = component }); await context.Audit.AddRangeAsync(entities); await context.SaveChangesAsync(); // Act var audits = await wrapper.GetAudits(auditDate); // Assert // returned audit should be the latest one at requested day audits.Should().ContainSingle(i => i.Date.Hour == 16); }
public async Task GetLastMonthAuditsReturnsOnlyLatestAuditAtAnyGivenDay() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); // create three audits at each day at 00:00, 08:00, 16:00 var expectedComponent = this.GenerateComponent(); var today = DateTime.UtcNow.Date; foreach (var auditDate in Enumerable.Range(0, 31).Select(i => today.AddDays(-i))) { var entities = Enumerable .Range(0, 3) .Select(i => new AuditEntity { Date = auditDate.AddHours(i * 8), ComponentId = expectedComponent.ComponentId, InfrastructureComponent = expectedComponent }); await context.Audit.AddRangeAsync(entities); } await context.SaveChangesAsync(); // Act var audits = await wrapper.GetLastMonthAudits(expectedComponent.ComponentId); // Assert // returned audit should be the latest one at each day audits.Should().HaveCount(31); audits.All(i => i.Date.Hour == 16).Should().BeTrue(); }
public async Task GetAuditReturnsOnlyAuditAtRequestedDay() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); var auditDate = DateTime.UtcNow.Date.AddDays(-1); var component = this.GenerateComponent(); await context.Audit.AddRangeAsync(new[] { new AuditEntity { Date = auditDate, ComponentId = component.ComponentId, InfrastructureComponent = component }, new AuditEntity { Date = auditDate.AddDays(-1), ComponentId = component.ComponentId, InfrastructureComponent = component }, }); await context.SaveChangesAsync(); // Act var audit = await wrapper.GetAudit(component.ComponentId, auditDate); // Assert audit.ComponentId.Should().Be(component.ComponentId); audit.Date.Should().Be(auditDate); }
public async Task GetCounterSummariesForAuditReturnsZeroSummaryForNotExistingId() { // Arrange var randomizer = new Random(); await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); var auditId = randomizer.Next(); await context.CheckResult.AddRangeAsync(new[] { new CheckResultEntity { AuditId = auditId - 1, Value = CheckValue.Succeeded, Check = new CheckEntity { Severity = CheckSeverity.Critical } }, new CheckResultEntity { AuditId = auditId + 1, Value = CheckValue.Succeeded, Check = new CheckEntity { Severity = CheckSeverity.Critical } }, }); await context.SaveChangesAsync(); // Act var summary = await wrapper.GetCounterSummariesForAudit(auditId); // Assert summary.Failed.Should().Be(0); summary.Warning.Should().Be(0); summary.NoData.Should().Be(0); summary.Passed.Should().Be(0); }
public async Task GetLastMonthAuditsReturnsOnlyLast31DaysAudits() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); var expectedComponent = this.GenerateComponent(); var today = DateTime.UtcNow.Date; var entities = Enumerable .Range(0, 35) .Select(i => new AuditEntity { Date = today.AddDays(-i), ComponentId = expectedComponent.ComponentId, InfrastructureComponent = expectedComponent }); await context.Audit.AddRangeAsync(entities); await context.SaveChangesAsync(); // Act var audits = await wrapper.GetLastMonthAudits(expectedComponent.ComponentId); // Assert var oneMonthAgo = today.AddDays(-30); audits.Should().HaveCount(31); audits.All(i => i.Date >= oneMonthAgo).Should().BeTrue(); }
public async Task GetCounterSummariesForAuditCountsNoDataAndInProgressAsNoData() { // Arrange var randomizer = new Random(); await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); var auditId = randomizer.Next(); await context.CheckResult.AddRangeAsync(new[] { new CheckResultEntity { AuditId = auditId, Value = CheckValue.NoData, Check = new CheckEntity { Severity = CheckSeverity.Critical } }, new CheckResultEntity { AuditId = auditId, Value = CheckValue.InProgress, Check = new CheckEntity { Severity = CheckSeverity.High } }, }); await context.SaveChangesAsync(); // Act var summary = await wrapper.GetCounterSummariesForAudit(auditId); // Assert summary.Failed.Should().Be(0); summary.Warning.Should().Be(0); summary.NoData.Should().Be(2); summary.Passed.Should().Be(0); }
public async Task TestCascadedOwnership_BlankObjectAndGroupOwnerShouldReturnRootLevel() { await using var context = JosekiTestsDb.CreateUniqueContext(); const string rootLevelId = "/subscriptions/0000-000-000-0000"; const string groupLevelId = "/subscriptions/0000-000-000-0000/resource_group/das-rg"; const string objectLevelId = "/subscriptions/0000-000-000-0000/resource_group/das-rg/VirtualNetwork/das-vn"; context.Ownership.AddRange(new OwnershipEntity[] { new OwnershipEntity { ComponentId = rootLevelId, Owner = "*****@*****.**", }, new OwnershipEntity { ComponentId = groupLevelId, Owner = string.Empty, }, new OwnershipEntity { ComponentId = objectLevelId, Owner = string.Empty, }, }); await context.SaveChangesAsync(); var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions())); var owner = await ownershipCache.GetOwner(objectLevelId); owner.Should().Be("*****@*****.**"); }
public async Task SaveAuditResultSavesCorrectAudit() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var db = new MssqlJosekiDatabase(context, parser); var audit = new Audit { ComponentId = Guid.NewGuid().ToString(), ComponentName = Guid.NewGuid().ToString(), Date = DateTime.UtcNow, ScannerId = Guid.NewGuid().ToString(), Id = Guid.NewGuid().ToString(), }; // Act & Assert context.Audit.Should().HaveCount(0); await db.SaveAuditResult(audit); context.Audit.Should().HaveCount(1); var actual = await context.Audit.FirstAsync(); actual.AuditId.Should().Be(audit.Id); actual.Date.Should().Be(audit.Date); actual.ComponentId.Should().Be(audit.ComponentId); }
public async Task GetAuditsReturnsOnlyUniqueComponentAudits() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); var auditDate = DateTime.UtcNow.Date.AddDays(-1); var component1 = this.GenerateComponent(); var component2 = this.GenerateComponent(); var component3 = this.GenerateComponent(); await context.Audit.AddRangeAsync(new[] { new AuditEntity { Id = 1, Date = auditDate, ComponentId = component1.ComponentId, InfrastructureComponent = component1 }, // this one should be ignored new AuditEntity { Id = 2, Date = auditDate.AddHours(6), ComponentId = component1.ComponentId, InfrastructureComponent = component1 }, new AuditEntity { Id = 3, Date = auditDate.AddHours(12), ComponentId = component2.ComponentId, InfrastructureComponent = component2 }, new AuditEntity { Id = 4, Date = auditDate.AddHours(23), ComponentId = component3.ComponentId, InfrastructureComponent = component3 }, }); await context.SaveChangesAsync(); // Act var audits = await wrapper.GetAudits(auditDate); // Assert audits.Should().HaveCount(3); audits.All(i => i.Id > 1).Should().BeTrue(); }
public async Task GetAuditedComponentsWithHistoryReturnsOnlyOneMonthData() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var db = new MssqlJosekiDatabase(context, parser); var componentId = Guid.NewGuid().ToString(); var today = DateTime.UtcNow; // create more than 31 entries, which the oldest ones would be filtered-out var entities = Enumerable.Range(0, 35) .Select(i => today.AddDays(-i)).Select(i => new AuditEntity { Date = i, ComponentId = componentId, InfrastructureComponent = new InfrastructureComponentEntity(), }); context.AddRange(entities); await context.SaveChangesAsync(); // Act & Assert var audits = await db.GetAuditedComponentsWithHistory(today); audits.Should().HaveCount(31); audits.All(i => i.Date >= today.AddDays(-30)).Should().BeTrue("All audits should be not earlier than 30 days ago"); }
public async Task GetAllComponentsIdsReturnsOnlyUniqueIds() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); var today = DateTime.UtcNow.Date; var componentId = Guid.NewGuid().ToString(); var audits = new[] { new AuditEntity { Date = today, ComponentId = componentId }, new AuditEntity { Date = today.AddDays(-1), ComponentId = componentId }, }; await context.Audit.AddRangeAsync(audits); await context.SaveChangesAsync(); // Act & Assert var allComponentsIds = await wrapper.GetAllComponentsIds(); // returned array should have the only one componentId allComponentsIds.Should().ContainSingle(componentId); }
public async Task GetNotExpiredImageScansReturnsTheLatestScan() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var db = new MssqlJosekiDatabase(context, parser); var tag = Guid.NewGuid().ToString(); var scans = new[] { new ImageScanResultEntity { ImageTag = tag, Date = DateTime.UtcNow.AddHours(-5), Status = joseki.db.entities.ImageScanStatus.Failed }, new ImageScanResultEntity { ImageTag = tag, Date = DateTime.UtcNow, Status = joseki.db.entities.ImageScanStatus.Queued }, new ImageScanResultEntity { ImageTag = tag, Date = DateTime.UtcNow.AddHours(-3), Status = joseki.db.entities.ImageScanStatus.Succeeded }, }; context.ImageScanResult.AddRange(scans); await context.SaveChangesAsync(); // Act & Assert var notExpiredScans = await db.GetNotExpiredImageScans(new[] { tag }); notExpiredScans.Should().HaveCount(1); notExpiredScans.First().Status.Should().Be(ImageScanStatus.Queued); }
public async Task GetAuditsReturnsOnlyAuditsAtRequestedDay() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var wrapper = new InfraScoreDbWrapper(context); var auditDate = DateTime.UtcNow.Date.AddDays(-1); var component1 = this.GenerateComponent(); var component2 = this.GenerateComponent(); var component3 = this.GenerateComponent(); await context.Audit.AddRangeAsync(new[] { new AuditEntity { Date = auditDate, ComponentId = component1.ComponentId, InfrastructureComponent = component1 }, new AuditEntity { Date = auditDate.AddDays(-1), ComponentId = component2.ComponentId, InfrastructureComponent = component2 }, new AuditEntity { Date = auditDate.AddDays(1), ComponentId = component3.ComponentId, InfrastructureComponent = component3 }, }); await context.SaveChangesAsync(); // Act var audits = await wrapper.GetAudits(auditDate); // Assert audits.Should().ContainSingle(i => i.Date == auditDate); }
public async Task ProcessAuditHappyPath() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var checksCache = new ChecksCache(parser, context, new MemoryCache(new MemoryCacheOptions())); var blobsMock = new Mock <IBlobStorageProcessor>(MockBehavior.Strict); var dbMock = new Mock <IJosekiDatabase>(); var queueMock = new Mock <IQueue>(); var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions())); var postProcessor = new Mock <ExtractOwnershipProcessor>(context, ownershipCache); var processor = new PolarisAuditProcessor(blobsMock.Object, dbMock.Object, checksCache, queueMock.Object, postProcessor.Object); var container = new ScannerContainer(Path.Combine("audits", "samples", "polaris")) { Metadata = new ScannerMetadata { Type = ScannerType.Polaris, Id = Guid.NewGuid().ToString(), }, }; var audit = new AuditBlob { Name = "meta.json", ParentContainer = container }; blobsMock .Setup(i => i.GetUnprocessedAudits(container)) .ReturnsAsync(new[] { audit }) .Verifiable(); blobsMock .Setup(i => i.DownloadFile($"{container.Name}/{audit.Name}")) .ReturnsAsync(File.OpenRead($"{container.Name}/{audit.Name}")) .Verifiable(); blobsMock .Setup(i => i.DownloadFile($"{container.Name}/audit.json")) .ReturnsAsync(File.OpenRead($"{container.Name}/audit.json")) .Verifiable(); blobsMock .Setup(i => i.DownloadFile($"{container.Name}/k8s-meta.json")) .ReturnsAsync(File.OpenRead($"{container.Name}/k8s-meta.json")) .Verifiable(); blobsMock .Setup(i => i.MarkAsProcessed(audit)) .Returns(Task.CompletedTask) .Verifiable(); // Act & Assert await processor.Process(container, CancellationToken.None); blobsMock.Verify(); dbMock.Verify(i => i.GetNotExpiredImageScans(It.Is <string[]>(tags => tags.Length == UniqueImageTagCount))); dbMock.Verify(i => i.SaveInProgressImageScan(It.IsAny <ImageScanResultWithCVEs>()), Times.Exactly(UniqueImageTagCount)); queueMock.Verify(i => i.EnqueueImageScanRequest(It.IsAny <ImageScanResultWithCVEs>()), Times.Exactly(UniqueImageTagCount)); dbMock.Verify(i => i.SaveAuditResult(It.Is <Audit>(a => VerifyHappyPathAudit(a, container)))); }
public async Task ProcessAuditHappyPath() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var checksCache = new ChecksCache(parser, context, new MemoryCache(new MemoryCacheOptions())); var blobsMock = new Mock <IBlobStorageProcessor>(MockBehavior.Strict); var dbMock = new Mock <IJosekiDatabase>(); var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions())); var postProcessor = new Mock <ExtractOwnershipProcessor>(context, ownershipCache); var processor = new AzskAuditProcessor(blobsMock.Object, dbMock.Object, checksCache, postProcessor.Object); var container = new ScannerContainer(Path.Combine("audits", "samples", "azsk")) { Metadata = new ScannerMetadata { Type = ScannerType.Azsk, Id = Guid.NewGuid().ToString(), }, }; var audit = new AuditBlob { Name = "meta.json", ParentContainer = container }; blobsMock .Setup(i => i.GetUnprocessedAudits(container)) .ReturnsAsync(new[] { audit }) .Verifiable(); blobsMock .Setup(i => i.DownloadFile($"{container.Name}/{audit.Name}")) .ReturnsAsync(File.OpenRead($"{container.Name}/{audit.Name}")) .Verifiable(); blobsMock .Setup(i => i.DownloadFile($"{container.Name}/resources.json")) .ReturnsAsync(File.OpenRead($"{container.Name}/resources.json")) .Verifiable(); blobsMock .Setup(i => i.DownloadFile($"{container.Name}/subscription.json")) .ReturnsAsync(File.OpenRead($"{container.Name}/subscription.json")) .Verifiable(); blobsMock .Setup(i => i.MarkAsProcessed(audit)) .Returns(Task.CompletedTask) .Verifiable(); // Act & Assert await processor.Process(container, CancellationToken.None); blobsMock.Verify(); dbMock.Verify(i => i.SaveAuditResult(It.Is <Audit>(a => VerifyHappyPathAudit(a, container)))); }
public async Task InvalidComponentId_ShouldThrowException() { await using var context = JosekiTestsDb.CreateUniqueContext(); var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions())); const string invalidId_missingSlashPrefix = "subscription/0000-000-000-0000/"; var owner1 = await ownershipCache.GetOwner(invalidId_missingSlashPrefix); owner1.Should().Be(string.Empty); }
public async Task EmptyComponentId_ShouldThrowException() { await using var context = JosekiTestsDb.CreateUniqueContext(); var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions())); string emptyComponentId = string.Empty; var owner1 = await ownershipCache.GetOwner(emptyComponentId); owner1.Should().Be(string.Empty); }
public async Task SaveImageScanResultCouldSaveNewEntity() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var db = new MssqlJosekiDatabase(context, parser); var cves = new List <ImageScanToCve> { new ImageScanToCve { InternalCveId = 1, Target = Guid.NewGuid().ToString(), UsedPackage = Guid.NewGuid().ToString(), UsedPackageVersion = Guid.NewGuid().ToString() }, new ImageScanToCve { InternalCveId = 2, Target = Guid.NewGuid().ToString(), UsedPackage = Guid.NewGuid().ToString(), UsedPackageVersion = Guid.NewGuid().ToString() }, new ImageScanToCve { InternalCveId = 3, Target = Guid.NewGuid().ToString(), UsedPackage = Guid.NewGuid().ToString(), UsedPackageVersion = Guid.NewGuid().ToString() }, }; var scan = new ImageScanResultWithCVEs { Date = DateTime.UtcNow, Id = Guid.NewGuid().ToString(), Description = Guid.NewGuid().ToString(), ImageTag = Guid.NewGuid().ToString(), Status = ImageScanStatus.Succeeded, FoundCVEs = cves, }; // Act & Assert context.ImageScanResult.Should().HaveCount(0); context.ImageScanResultToCve.Should().HaveCount(0); await db.SaveImageScanResult(scan); context.ImageScanResult.Should().HaveCount(1); context.ImageScanResultToCve.Should().HaveCount(cves.Count); var actual = await context.ImageScanResult.FirstAsync(); actual.Date.Should().Be(scan.Date); actual.ExternalId.Should().Be(scan.Id); actual.Description.Should().Be(scan.Description); actual.ImageTag.Should().Be(scan.ImageTag); actual.Status.Should().Be(joseki.db.entities.ImageScanStatus.Succeeded); foreach (var actualCve in await context.ImageScanResultToCve.ToArrayAsync()) { var expectedCve = cves.First(i => i.InternalCveId == actualCve.CveId); actualCve.Target.Should().Be(expectedCve.Target); actualCve.UsedPackage.Should().Be(expectedCve.UsedPackage); actualCve.UsedPackageVersion.Should().Be(expectedCve.UsedPackageVersion); } }
public async Task ExpiredThresholdCausesRecordUpdate() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var cveCache = new CveCache(parser, context, new MemoryCache(new MemoryCacheOptions())); var id = this.GetCveId(); var now = DateTime.UtcNow; var expirationDate = now.AddDays(-(parser.Get().Cache.CveTtl + 1)); var oldCve = new CveEntity { CveId = id, Severity = joseki.db.entities.CveSeverity.Medium, PackageName = Guid.NewGuid().ToString(), Title = Guid.NewGuid().ToString(), Description = Guid.NewGuid().ToString(), Remediation = Guid.NewGuid().ToString(), References = Guid.NewGuid().ToString(), DateUpdated = expirationDate, DateCreated = expirationDate, }; // this is the hack -_- // Use sync version, because it does not update DateUpdated & DateCreated context.Cve.Add(oldCve); context.SaveChanges(); var newCve = new CVE { Id = id, Description = Guid.NewGuid().ToString(), Remediation = Guid.NewGuid().ToString(), Severity = CveSeverity.High, PackageName = Guid.NewGuid().ToString(), Title = Guid.NewGuid().ToString(), References = Guid.NewGuid().ToString(), }; // Act & Assert context.Cve.Count().Should().Be(1, "context should have the only one record before GetOrAddItem"); await cveCache.GetOrAddItem(id, () => newCve); var actualEntity = await context.Cve.FirstAsync(i => i.CveId == id); actualEntity.Description.Should().Be(newCve.Description); actualEntity.Remediation.Should().Be(newCve.Remediation); actualEntity.PackageName.Should().Be(newCve.PackageName); actualEntity.Title.Should().Be(newCve.Title); actualEntity.References.Should().Be(newCve.References); actualEntity.Severity.Should().Be(joseki.db.entities.CveSeverity.High); actualEntity.DateUpdated.Should().BeOnOrAfter(now); }
public async Task GetAuditedComponentsWithHistoryReturnsEmptyArrayIfNoAudits() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var db = new MssqlJosekiDatabase(context, parser); // Act & Assert var audits = await db.GetAuditedComponentsWithHistory(DateTime.UtcNow); audits.Should().BeEmpty(); }
private async Task <(GetKnowledgebaseItemsHandler, string)> getUniqueHandlerAsync() { await using var context = JosekiTestsDb.CreateUniqueContext(); var path = Path.Combine(BaseTestPath, Guid.NewGuid().ToString()); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var handler = new GetKnowledgebaseItemsHandler(context, path); return(handler, path); }
public async Task QueryComponentHistoryThrowsExceptionIfNoAudits() { // Arrange var componentId = Guid.NewGuid().ToString(); await using var context = JosekiTestsDb.CreateUniqueContext(); var cacheMock = new Mock <IInfrastructureScoreCache>(); var handler = new GetInfrastructureHistoryHandler(context, cacheMock.Object); // Act & Assert await handler .Invoking(h => h.GetHistory(componentId)) .Should() .ThrowAsync <ComponentNotFoundException>(); }
public async Task ProcessScanResultWithoutCVEs() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var cveCache = new CveCache(parser, context, new MemoryCache(new MemoryCacheOptions())); var blobsMock = new Mock <IBlobStorageProcessor>(MockBehavior.Strict); var dbMock = new Mock <IJosekiDatabase>(); var processor = new TrivyAuditProcessor(blobsMock.Object, dbMock.Object, cveCache); var container = new ScannerContainer(Path.Combine("audits", "samples", "trivy")) { Metadata = new ScannerMetadata { Type = ScannerType.Trivy, Id = Guid.NewGuid().ToString(), }, }; var audit = new AuditBlob { Name = "meta_no_cve.json", ParentContainer = container }; blobsMock .Setup(i => i.GetUnprocessedAudits(container)) .ReturnsAsync(new[] { audit }) .Verifiable(); blobsMock .Setup(i => i.DownloadFile($"{container.Name}/{audit.Name}")) .ReturnsAsync(File.OpenRead($"{container.Name}/{audit.Name}")) .Verifiable(); blobsMock .Setup(i => i.DownloadFile($"{container.Name}/result_no_cves.json")) .ReturnsAsync(File.OpenRead($"{container.Name}/result_no_cves.json")) .Verifiable(); blobsMock .Setup(i => i.MarkAsProcessed(audit)) .Returns(Task.CompletedTask) .Verifiable(); // Act & Assert await processor.Process(container, CancellationToken.None); blobsMock.Verify(); dbMock.Verify(i => i.SaveImageScanResult(It.Is <ImageScanResultWithCVEs>(a => VerifyNoCveScan(a)))); }
public async Task ExpiredThresholdCausesAzskRecordUpdate() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var checksCache = new ChecksCache(parser, context, new MemoryCache(new MemoryCacheOptions())); var id = $"azsk.{Guid.NewGuid().ToString()}"; var now = DateTime.UtcNow; var expirationDate = now.AddDays(-(parser.Get().Cache.AzureCheckTtl + 1)); var oldCheck = new CheckEntity { CheckId = id, Category = Guid.NewGuid().ToString(), Description = Guid.NewGuid().ToString(), Severity = joseki.db.entities.CheckSeverity.Medium, DateUpdated = expirationDate, DateCreated = expirationDate, }; // this is the hack -_- // Use sync version, because it does not update DateUpdated & DateCreated context.Check.Add(oldCheck); context.SaveChanges(); var newCheck = new Check { Id = id, Category = Guid.NewGuid().ToString(), Description = Guid.NewGuid().ToString(), Remediation = Guid.NewGuid().ToString(), Severity = CheckSeverity.High, }; // Act & Assert context.Check.Count().Should().Be(1, "context should have the only one record before GetOrAddItem"); await checksCache.GetOrAddItem(id, () => newCheck); var actualEntity = await context.Check.FirstAsync(i => i.CheckId == id); actualEntity.Category.Should().Be(newCheck.Category); actualEntity.Description.Should().Be(newCheck.Description); actualEntity.Remediation.Should().Be(newCheck.Remediation); actualEntity.Severity.Should().Be(joseki.db.entities.CheckSeverity.High); actualEntity.DateUpdated.Should().BeOnOrAfter(now); }
public async Task GetNotExistingItemAddOneRecordToDb() { // Arrange await using var context = JosekiTestsDb.CreateUniqueContext(); var parser = new ConfigurationParser("config.sample.yaml"); var cveCache = new CveCache(parser, context, new MemoryCache(new MemoryCacheOptions())); var id = this.GetCveId(); var cve = new CVE { Id = id, Description = Guid.NewGuid().ToString(), }; // Act & Assert context.Cve.Count().Should().Be(0, "context should be empty before GetOrAddItem"); await cveCache.GetOrAddItem(id, () => cve); context.Cve.Count().Should().Be(1, "context should have a single value after GetOrAddItem"); }