diff --git a/src/main/java/org/dependencytrack/event/kafka/processor/VulnerabilityScanResultProcessor.java b/src/main/java/org/dependencytrack/event/kafka/processor/VulnerabilityScanResultProcessor.java index 6354b529e..7e16f8385 100644 --- a/src/main/java/org/dependencytrack/event/kafka/processor/VulnerabilityScanResultProcessor.java +++ b/src/main/java/org/dependencytrack/event/kafka/processor/VulnerabilityScanResultProcessor.java @@ -201,12 +201,26 @@ private Set syncVulnerabilities(final QueryManager qm, final Scan } try { - syncedVulns.add(syncVulnerability(qm, vuln, scannerResult.getScanner())); + final Vulnerability syncedVuln = syncVulnerability(qm, vuln, scannerResult.getScanner()); + + // Detach vulnerabilities from JDO persistence context. + // We do not want to trigger any DB interactions by accessing their fields later. + // Note that even PersistenceManager#detachCopy will load / unload fields based + // on the current FetchPlan. But we just want to keep the data we already have, + // and #makeTransientAll does exactly that. + qm.getPersistenceManager().makeTransient(syncedVuln); + if (vuln.getAliases() != null && !vuln.getAliases().isEmpty()) { + final var syncedAliases = new ArrayList(); for (VulnerabilityAlias alias : vuln.getAliases()) { - qm.synchronizeVulnerabilityAlias(alias); + final VulnerabilityAlias syncedAlias = qm.synchronizeVulnerabilityAlias(alias); + qm.getPersistenceManager().makeTransient(syncedAlias); + syncedAliases.add(syncedAlias); } + syncedVuln.setAliases(syncedAliases); } + + syncedVulns.add(syncedVuln); } catch (RuntimeException e) { // Use a broad catch here, so we can still try to process other // vulnerabilities, even though processing one of them failed. @@ -216,13 +230,6 @@ private Set syncVulnerabilities(final QueryManager qm, final Scan } } - // Detach vulnerabilities from JDO persistence context. - // We do not want to trigger any DB interactions by accessing their fields. - // Note that even PersistenceManager#detachCopy will load / unload fields based - // on the current FetchPlan. But we just want to keep the data we already have, - // and #makeTransientAll does exactly that. - qm.getPersistenceManager().makeTransientAll(syncedVulns); - return syncedVulns; } diff --git a/src/main/java/org/dependencytrack/policy/cel/CelPolicyScriptHost.java b/src/main/java/org/dependencytrack/policy/cel/CelPolicyScriptHost.java index db315aee0..e3085fc16 100644 --- a/src/main/java/org/dependencytrack/policy/cel/CelPolicyScriptHost.java +++ b/src/main/java/org/dependencytrack/policy/cel/CelPolicyScriptHost.java @@ -13,7 +13,6 @@ import org.projectnessie.cel.CEL; import org.projectnessie.cel.Env; import org.projectnessie.cel.Env.AstIssuesTuple; -import org.projectnessie.cel.EnvOption; import org.projectnessie.cel.Program; import org.projectnessie.cel.common.CELError; import org.projectnessie.cel.common.Errors; @@ -52,17 +51,17 @@ public enum CacheMode { private final AbstractCacheManager cacheManager; private final Env environment; - CelPolicyScriptHost(final AbstractCacheManager cacheManager, final List envOptions) { + public CelPolicyScriptHost(final AbstractCacheManager cacheManager, final CelPolicyType policyType) { this.locks = Striped.lock(128); this.cacheManager = cacheManager; this.environment = Env.newCustomEnv( ProtoTypeRegistry.newRegistry(), - envOptions + policyType.envOptions() ); } public static synchronized CelPolicyScriptHost getInstance(final CelPolicyType policyType) { - return INSTANCES.computeIfAbsent(policyType, ignored -> new CelPolicyScriptHost(CacheManager.getInstance(), policyType.envOptions())); + return INSTANCES.computeIfAbsent(policyType, ignored -> new CelPolicyScriptHost(CacheManager.getInstance(), policyType)); } /** diff --git a/src/main/java/org/dependencytrack/policy/cel/CelVulnerabilityPolicyEvaluator.java b/src/main/java/org/dependencytrack/policy/cel/CelVulnerabilityPolicyEvaluator.java index ea14e7bba..fb653ef2c 100644 --- a/src/main/java/org/dependencytrack/policy/cel/CelVulnerabilityPolicyEvaluator.java +++ b/src/main/java/org/dependencytrack/policy/cel/CelVulnerabilityPolicyEvaluator.java @@ -55,13 +55,14 @@ public class CelVulnerabilityPolicyEvaluator implements VulnerabilityPolicyEvalu private final CelPolicyScriptHost scriptHost; private final AbstractCacheManager cacheManager; + @SuppressWarnings("unused") // Called by ServiceLoader public CelVulnerabilityPolicyEvaluator() { this(ServiceLoader.load(VulnerabilityPolicyProvider.class).findFirst().orElseThrow(), CelPolicyScriptHost.getInstance(CelPolicyType.VULNERABILITY), CacheManager.getInstance()); } - CelVulnerabilityPolicyEvaluator(final VulnerabilityPolicyProvider policyProvider, - final CelPolicyScriptHost scriptHost, final AbstractCacheManager cacheManager) { + public CelVulnerabilityPolicyEvaluator(final VulnerabilityPolicyProvider policyProvider, + final CelPolicyScriptHost scriptHost, final AbstractCacheManager cacheManager) { this.policyProvider = policyProvider; this.scriptHost = scriptHost; this.cacheManager = cacheManager; diff --git a/src/main/java/org/dependencytrack/policy/cel/persistence/CelPolicyDao.java b/src/main/java/org/dependencytrack/policy/cel/persistence/CelPolicyDao.java index 11b53d6cd..3c8802f0e 100644 --- a/src/main/java/org/dependencytrack/policy/cel/persistence/CelPolicyDao.java +++ b/src/main/java/org/dependencytrack/policy/cel/persistence/CelPolicyDao.java @@ -256,7 +256,7 @@ private static Set determineFieldsToLoad(final Descriptor typeDescriptor if (fieldDescriptor.isRepeated() && typeInstance.getRepeatedFieldCount(fieldDescriptor) == 0) { // There's no way differentiate between repeated fields being not set or just empty. fieldsToLoad.add(fieldName); - } else if (!typeInstance.hasField(fieldDescriptor)) { + } else if (!fieldDescriptor.isRepeated() && !typeInstance.hasField(fieldDescriptor)) { fieldsToLoad.add(fieldName); } } diff --git a/src/test/java/org/dependencytrack/TestCacheManager.java b/src/test/java/org/dependencytrack/TestCacheManager.java new file mode 100644 index 000000000..05a51b67a --- /dev/null +++ b/src/test/java/org/dependencytrack/TestCacheManager.java @@ -0,0 +1,13 @@ +package org.dependencytrack; + +import alpine.server.cache.AbstractCacheManager; + +import java.util.concurrent.TimeUnit; + +public class TestCacheManager extends AbstractCacheManager { + + public TestCacheManager(final long expiresAfter, final TimeUnit timeUnit, final long maxSize) { + super(expiresAfter, timeUnit, maxSize); + } + +} diff --git a/src/test/java/org/dependencytrack/event/kafka/processor/VulnerabilityScanResultProcessorTest.java b/src/test/java/org/dependencytrack/event/kafka/processor/VulnerabilityScanResultProcessorTest.java index 8812cc204..4945ca0b4 100644 --- a/src/test/java/org/dependencytrack/event/kafka/processor/VulnerabilityScanResultProcessorTest.java +++ b/src/test/java/org/dependencytrack/event/kafka/processor/VulnerabilityScanResultProcessorTest.java @@ -17,7 +17,9 @@ import org.cyclonedx.proto.v1_4.Property; import org.cyclonedx.proto.v1_4.Source; import org.cyclonedx.proto.v1_4.VulnerabilityRating; +import org.cyclonedx.proto.v1_4.VulnerabilityReference; import org.dependencytrack.AbstractPostgresEnabledTest; +import org.dependencytrack.TestCacheManager; import org.dependencytrack.event.kafka.KafkaEventHeaders; import org.dependencytrack.event.kafka.KafkaTopics; import org.dependencytrack.event.kafka.serialization.KafkaProtobufDeserializer; @@ -36,12 +38,16 @@ import org.dependencytrack.model.Project; import org.dependencytrack.model.Severity; import org.dependencytrack.model.Vulnerability; +import org.dependencytrack.model.VulnerabilityAlias; import org.dependencytrack.model.VulnerabilityAnalysisLevel; +import org.dependencytrack.model.VulnerabilityPolicy; import org.dependencytrack.notification.NotificationConstants; import org.dependencytrack.persistence.CweImporter; -import org.dependencytrack.policy.vulnerability.VulnerabilityPolicy; +import org.dependencytrack.policy.cel.CelPolicyScriptHost; +import org.dependencytrack.policy.cel.CelPolicyType; +import org.dependencytrack.policy.cel.CelVulnerabilityPolicyEvaluator; +import org.dependencytrack.policy.vulnerability.DatabaseVulnerabilityPolicyProvider; import org.dependencytrack.policy.vulnerability.VulnerabilityPolicyAnalysis; -import org.dependencytrack.policy.vulnerability.VulnerabilityPolicyEvaluator; import org.dependencytrack.policy.vulnerability.VulnerabilityPolicyRating; import org.dependencytrack.proto.notification.v1.NewVulnerabilitySubject; import org.dependencytrack.proto.notification.v1.NewVulnerableDependencySubject; @@ -54,15 +60,13 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mockito; import java.math.BigDecimal; import java.sql.Date; import java.time.Instant; -import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.UUID; +import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; import static org.cyclonedx.proto.v1_4.ScoreMethod.SCORE_METHOD_CVSSV2; @@ -82,9 +86,6 @@ import static org.dependencytrack.proto.vulnanalysis.v1.Scanner.SCANNER_OSSINDEX; import static org.dependencytrack.proto.vulnanalysis.v1.Scanner.SCANNER_SNYK; import static org.dependencytrack.util.KafkaTestUtil.deserializeValue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; @RunWith(JUnitParamsRunner.class) public class VulnerabilityScanResultProcessorTest extends AbstractPostgresEnabledTest { @@ -92,20 +93,21 @@ public class VulnerabilityScanResultProcessorTest extends AbstractPostgresEnable private TopologyTestDriver testDriver; private TestInputTopic inputTopic; private TestOutputTopic outputTopic; - private VulnerabilityPolicyEvaluator policyEvaluatorMock; @Before public void setUp() throws Exception { super.setUp(); - policyEvaluatorMock = mock(VulnerabilityPolicyEvaluator.class); - doReturn(Collections.emptyMap()).when(policyEvaluatorMock).evaluate(any(), any(), any()); + final var cacheManager = new TestCacheManager(5, TimeUnit.MINUTES, 100); + final var scriptHost = new CelPolicyScriptHost(cacheManager, CelPolicyType.VULNERABILITY); + final var policyProvider = new DatabaseVulnerabilityPolicyProvider(); + final var policyEvaluator = new CelVulnerabilityPolicyEvaluator(policyProvider, scriptHost, cacheManager); final var streamsBuilder = new StreamsBuilder(); streamsBuilder .stream("input-topic", Consumed .with(new KafkaProtobufSerde<>(ScanKey.parser()), new KafkaProtobufSerde<>(ScanResult.parser()))) - .processValues(() -> new VulnerabilityScanResultProcessor(policyEvaluatorMock)) + .processValues(() -> new VulnerabilityScanResultProcessor(policyEvaluator)) .to("output-topic", Produced .with(new KafkaProtobufSerde<>(ScanKey.parser()), new KafkaProtobufSerde<>(ScanResult.parser()))); @@ -632,12 +634,10 @@ public void analysisThroughPolicyNewAnalysisTest() { final var policy = new VulnerabilityPolicy(); policy.setName("Foo"); policy.setAuthor("Jane Doe"); - policy.setConditions(List.of("conditionA", "conditionB")); + policy.setConditions(new String[]{"has(component.name)", "project.version != \"\""}); policy.setAnalysis(policyAnalysis); policy.setRatings(List.of(policyRating)); - Mockito.reset(policyEvaluatorMock); - doReturn(Map.of(newVuln.getUuid(), policy)) - .when(policyEvaluatorMock).evaluate(any(), any(), any()); + qm.createVulnerabilityPolicy(policy, null); final var componentUuid = component.getUuid(); final var scanToken = UUID.randomUUID().toString(); @@ -677,7 +677,7 @@ public void analysisThroughPolicyNewAnalysisTest() { // test might not be stable, hence the check for "in any order". assertThat(analysis.getAnalysisComments()).extracting(AnalysisComment::getCommenter).containsOnly("[Policy{Name=Foo, Author=Jane Doe}]"); assertThat(analysis.getAnalysisComments()).extracting(AnalysisComment::getComment).containsExactlyInAnyOrder( - "Matched on condition(s):\n- conditionA\n- conditionB", + "Matched on condition(s):\n- has(component.name)\n- project.version != \"\"", "State: NOT_SET → NOT_AFFECTED", "Justification: NOT_SET → CODE_NOT_REACHABLE", "Response: NOT_SET → WILL_NOT_FIX", @@ -734,11 +734,9 @@ public void analysisThroughPolicyNewAnalysisSuppressionTest() { final var policy = new VulnerabilityPolicy(); policy.setName("Foo"); policy.setAuthor("Jane Doe"); - policy.setConditions(List.of("conditionA", "conditionB")); + policy.setConditions(new String[]{"has(component.name)", "project.version != \"\""}); policy.setAnalysis(policyAnalysis); - Mockito.reset(policyEvaluatorMock); - doReturn(Map.of(newVuln.getUuid(), policy)) - .when(policyEvaluatorMock).evaluate(any(), any(), any()); + qm.createVulnerabilityPolicy(policy, null); final var componentUuid = component.getUuid(); final var scanToken = UUID.randomUUID().toString(); @@ -778,7 +776,7 @@ public void analysisThroughPolicyNewAnalysisSuppressionTest() { // test might not be stable, hence the check for "in any order". assertThat(analysis.getAnalysisComments()).extracting(AnalysisComment::getCommenter).containsOnly("[Policy{Name=Foo, Author=Jane Doe}]"); assertThat(analysis.getAnalysisComments()).extracting(AnalysisComment::getComment).containsExactlyInAnyOrder( - "Matched on condition(s):\n- conditionA\n- conditionB", + "Matched on condition(s):\n- has(component.name)\n- project.version != \"\"", "State: NOT_SET → FALSE_POSITIVE", "Unsuppressed → Suppressed" ); @@ -836,12 +834,10 @@ public void analysisThroughPolicyExistingDifferentAnalysisTest() { final var policy = new VulnerabilityPolicy(); policy.setName("Foo"); policy.setAuthor("Jane Doe"); - policy.setConditions(List.of("conditionA", "conditionB")); + policy.setConditions(new String[]{"has(component.name)", "project.version != \"\""}); policy.setAnalysis(policyAnalysis); policy.setRatings(List.of(policyRating)); - Mockito.reset(policyEvaluatorMock); - doReturn(Map.of(vuln.getUuid(), policy)) - .when(policyEvaluatorMock).evaluate(any(), any(), any()); + qm.createVulnerabilityPolicy(policy, null); final var componentUuid = component.getUuid(); final var scanToken = UUID.randomUUID().toString(); @@ -881,7 +877,7 @@ public void analysisThroughPolicyExistingDifferentAnalysisTest() { // test might not be stable, hence the check for "in any order". assertThat(analysis.getAnalysisComments()).extracting(AnalysisComment::getCommenter).containsOnly("[Policy{Name=Foo, Author=Jane Doe}]"); assertThat(analysis.getAnalysisComments()).extracting(AnalysisComment::getComment).containsExactlyInAnyOrder( - "Matched on condition(s):\n- conditionA\n- conditionB", + "Matched on condition(s):\n- has(component.name)\n- project.version != \"\"", "State: FALSE_POSITIVE → NOT_AFFECTED", "Justification: NOT_SET → CODE_NOT_REACHABLE", "Response: CAN_NOT_FIX → WILL_NOT_FIX", @@ -944,12 +940,10 @@ public void analysisThroughPolicyExistingEqualAnalysisTest() { policyRating.setScore(1.6); final var policy = new VulnerabilityPolicy(); policy.setName("Foo"); - policy.setConditions(List.of("conditionA", "conditionB")); + policy.setConditions(new String[]{"has(component.name)", "project.version != \"\""}); policy.setAnalysis(policyAnalysis); policy.setRatings(List.of(policyRating)); - Mockito.reset(policyEvaluatorMock); - doReturn(Map.of(vuln.getUuid(), policy)) - .when(policyEvaluatorMock).evaluate(any(), any(), any()); + qm.createVulnerabilityPolicy(policy, null); final var componentUuid = component.getUuid(); final var scanToken = UUID.randomUUID().toString(); @@ -993,6 +987,106 @@ public void analysisThroughPolicyExistingEqualAnalysisTest() { assertThat(kafkaMockProducer.history()).isEmpty(); } + @Test + public void analysisThroughPolicyWithAliasesTest() { + final var project = new Project(); + project.setName("acme-app"); + project.setVersion("1.0.0"); + qm.persist(project); + + final var component = new Component(); + component.setName("acme-lib"); + component.setVersion("1.1.0"); + component.setProject(project); + qm.persist(component); + + // Create a vulnerability for which no aliases are currently known. + // Aliases will be reported by the ScanResult. + final var vulnA = new Vulnerability(); + vulnA.setVulnId("CVE-100"); + vulnA.setSource(Vulnerability.Source.NVD); + qm.persist(vulnA); + + // Create a vulnerability for which an alias is already known. + // The same alias will be reported by the ScanResult. + final var vulnB = new Vulnerability(); + vulnB.setVulnId("CVE-200"); + vulnB.setSource(Vulnerability.Source.NVD); + qm.persist(vulnB); + final var vulnAliasB = new VulnerabilityAlias(); + vulnAliasB.setCveId("CVE-200"); + vulnAliasB.setGhsaId("GHSA-200"); + qm.synchronizeVulnerabilityAlias(vulnAliasB); + + // Create a policy that suppresses any finding with the alias GHSA-100 or GHSA-200. + final var policyAnalysis = new VulnerabilityPolicyAnalysis(); + policyAnalysis.setState(VulnerabilityPolicyAnalysis.State.FALSE_POSITIVE); + policyAnalysis.setSuppress(true); + final var policy = new VulnerabilityPolicy(); + policy.setName("Foo"); + policy.setConditions(new String[]{"vuln.aliases.exists(alias, alias.id == \"GHSA-100\" || alias.id == \"GHSA-200\")"}); + policy.setAnalysis(policyAnalysis); + qm.createVulnerabilityPolicy(policy, null); + + // Report three vulnerabilities for the component: + // - CVE-100 with alias GHSA-100 (vuln already in DB, alias is new) + // - CVE-200 with alias GHSA-200 (vuln and alias already in DB) + // - CVE-300 without alias (vuln already in DB) + final var componentUuid = component.getUuid(); + final var scanToken = UUID.randomUUID().toString(); + final var scanKey = ScanKey.newBuilder().setScanToken(scanToken).setComponentUuid(componentUuid.toString()).build(); + final var scanResult = ScanResult.newBuilder() + .setKey(scanKey) + .addScannerResults(ScannerResult.newBuilder() + .setScanner(SCANNER_INTERNAL) + .setStatus(SCAN_STATUS_SUCCESSFUL) + .setBom(Bom.newBuilder().addAllVulnerabilities(List.of( + org.cyclonedx.proto.v1_4.Vulnerability.newBuilder() + .setId("CVE-100") + .setSource(Source.newBuilder().setName("NVD")) + .addReferences(VulnerabilityReference.newBuilder() + .setId("GHSA-100") + .setSource(Source.newBuilder().setName("GITHUB"))) + .build(), + org.cyclonedx.proto.v1_4.Vulnerability.newBuilder() + .setId("CVE-200") + .setSource(Source.newBuilder().setName("NVD")) + .addReferences(VulnerabilityReference.newBuilder() + .setId("GHSA-200") + .setSource(Source.newBuilder().setName("GITHUB"))) + .build(), + org.cyclonedx.proto.v1_4.Vulnerability.newBuilder() + .setId("CVE-300") + .setSource(Source.newBuilder().setName("NVD")) + .build() + )))) + .build(); + inputTopic.pipeInput(new TestRecord<>(scanKey, scanResult)); + assertThat(outputTopic.readValuesToList()).containsOnly(scanResult); + + qm.getPersistenceManager().evictAll(); + assertThat(component.getVulnerabilities()).satisfiesExactlyInAnyOrder( + v -> { + assertThat(v.getVulnId()).isEqualTo("CVE-100"); + assertThat(qm.getAnalysis(component, v)).satisfies(analysis -> { + assertThat(analysis.getAnalysisState()).isEqualTo(AnalysisState.FALSE_POSITIVE); + assertThat(analysis.isSuppressed()).isTrue(); + }); + }, + v -> { + assertThat(v.getVulnId()).isEqualTo("CVE-200"); + assertThat(qm.getAnalysis(component, v)).satisfies(analysis -> { + assertThat(analysis.getAnalysisState()).isEqualTo(AnalysisState.FALSE_POSITIVE); + assertThat(analysis.isSuppressed()).isTrue(); + }); + }, + v -> { + assertThat(v.getVulnId()).isEqualTo("CVE-300"); + assertThat(qm.getAnalysis(component, v)).isNull(); + } + ); + } + private org.cyclonedx.proto.v1_4.Vulnerability createVuln(final String id, final String source) { return org.cyclonedx.proto.v1_4.Vulnerability.newBuilder() .setId(id) diff --git a/src/test/java/org/dependencytrack/policy/cel/CelPolicyScriptHostTest.java b/src/test/java/org/dependencytrack/policy/cel/CelPolicyScriptHostTest.java index a99c7b770..204777264 100644 --- a/src/test/java/org/dependencytrack/policy/cel/CelPolicyScriptHostTest.java +++ b/src/test/java/org/dependencytrack/policy/cel/CelPolicyScriptHostTest.java @@ -1,8 +1,8 @@ package org.dependencytrack.policy.cel; -import alpine.server.cache.AbstractCacheManager; import com.google.api.expr.v1alpha1.Type; import org.apache.commons.codec.digest.DigestUtils; +import org.dependencytrack.TestCacheManager; import org.dependencytrack.policy.cel.CelPolicyScriptHost.CacheMode; import org.junit.Test; import org.projectnessie.cel.tools.ScriptCreateException; @@ -22,22 +22,14 @@ public class CelPolicyScriptHostTest { - private static class TestCacheManager extends AbstractCacheManager { - - private TestCacheManager() { - super(30, TimeUnit.SECONDS, 5); - } - - } - @Test public void testCompileWithCache() throws Exception { final var scriptSrc = """ component.name == "foo" """; - final var cacheManager = new TestCacheManager(); - final CelPolicyScript script = new CelPolicyScriptHost(cacheManager, CelPolicyType.COMPONENT.envOptions()).compile(""" + final var cacheManager = new TestCacheManager(30, TimeUnit.SECONDS, 5); + final CelPolicyScript script = new CelPolicyScriptHost(cacheManager, CelPolicyType.COMPONENT).compile(""" component.name == "foo" """, CacheMode.CACHE); @@ -50,8 +42,8 @@ public void testCompileWithoutCache() throws Exception { component.name == "foo" """; - final var cacheManager = new TestCacheManager(); - new CelPolicyScriptHost(cacheManager, CelPolicyType.COMPONENT.envOptions()).compile(""" + final var cacheManager = new TestCacheManager(30, TimeUnit.SECONDS, 5); + new CelPolicyScriptHost(cacheManager, CelPolicyType.COMPONENT).compile(""" component.name == "foo" """, CacheMode.NO_CACHE); diff --git a/src/test/java/org/dependencytrack/policy/cel/CelVulnerabilityPolicyEvaluatorTest.java b/src/test/java/org/dependencytrack/policy/cel/CelVulnerabilityPolicyEvaluatorTest.java index d1c239f60..5eb4c61eb 100644 --- a/src/test/java/org/dependencytrack/policy/cel/CelVulnerabilityPolicyEvaluatorTest.java +++ b/src/test/java/org/dependencytrack/policy/cel/CelVulnerabilityPolicyEvaluatorTest.java @@ -1,7 +1,7 @@ package org.dependencytrack.policy.cel; -import alpine.server.cache.AbstractCacheManager; import org.dependencytrack.AbstractPostgresEnabledTest; +import org.dependencytrack.TestCacheManager; import org.dependencytrack.model.VulnerabilityAlias; import org.dependencytrack.policy.vulnerability.VulnerabilityPolicy; import org.dependencytrack.policy.vulnerability.VulnerabilityPolicyEvaluator; @@ -36,7 +36,7 @@ public class CelVulnerabilityPolicyEvaluatorTest extends AbstractPostgresEnabled public void setUp() throws Exception { super.setUp(); - final var cacheManager = new TestCacheManager(); + final var cacheManager = new TestCacheManager(30, TimeUnit.SECONDS, 5); final var policyScriptHost = CelPolicyScriptHost.getInstance(CelPolicyType.VULNERABILITY); policyProviderMock = mock(VulnerabilityPolicyProvider.class); policyEvaluator = new CelVulnerabilityPolicyEvaluator(policyProviderMock, policyScriptHost, cacheManager); @@ -221,12 +221,4 @@ public void testEvaluateWithAdditionalRequiredFields() throws Exception { assertThat(exceptionsThrown).isEmpty(); } - private static final class TestCacheManager extends AbstractCacheManager { - - private TestCacheManager() { - super(30, TimeUnit.SECONDS, 5); - } - - } - } \ No newline at end of file