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 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 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 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 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 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 OwnershipCache_ShouldInvalidateOnCall() { await using var context = JosekiTestsDb.CreateUniqueContext(); const string rootLevelId = "/subscriptions/0000-000-000-0000"; var ownerEntry = new OwnershipEntity { ComponentId = rootLevelId, Owner = "*****@*****.**", }; context.Ownership.Add(ownerEntry); await context.SaveChangesAsync(); var ownershipCache = new OwnershipCache(context, new MemoryCache(new MemoryCacheOptions())); var owner1 = await ownershipCache.GetOwner(rootLevelId); owner1.Should().Be("*****@*****.**"); // remove entry from db context.Ownership.Remove(ownerEntry); await context.SaveChangesAsync(); // see that cache is in progress. var ownerAgain = await ownershipCache.GetOwner(rootLevelId); ownerAgain.Should().Be("*****@*****.**"); // invalidate cache ownershipCache.Invalidate(); var ownerNull = await ownershipCache.GetOwner(rootLevelId); ownerNull.Should().Be(string.Empty); }