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 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 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"); }
public async Task GetExistingItemDoesNotAddNewRecords() { // 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(), }; context.Cve.Add(cve.ToEntity()); await context.SaveChangesAsync(); // Act & Assert context.Cve.Count().Should().Be(1, "context should have the only one record before GetOrAddItem"); await cveCache.GetOrAddItem(id, () => cve); context.Cve.Count().Should().Be(1, "context should still have the only one record after GetOrAddItem"); }
/// <summary> /// Initializes a new instance of the <see cref="TrivyAuditProcessor"/> class. /// </summary> /// <param name="blobStorage">Blob Storage implementation.</param> /// <param name="db">Joseki database implementation.</param> /// <param name="cache">CVE cache object.</param> public TrivyAuditProcessor(IBlobStorageProcessor blobStorage, IJosekiDatabase db, CveCache cache) { this.blobStorage = blobStorage; this.db = db; this.cache = cache; }