From 336187efb82493d7788a07d1fbd67d09cd37b711 Mon Sep 17 00:00:00 2001 From: nscuro Date: Tue, 11 Jun 2024 18:36:52 +0200 Subject: [PATCH] Update License Of Existing Components On BOM Upload Ports tests from https://github.com/DependencyTrack/dependency-track/pull/3556 of Dependency-Track v4.11.0. The logic change in that PR was only necessary for the legacy `BomUploadProcessingTask`, which does not exist in Hyades anymore. Co-authored-by: Aravind Parappil Signed-off-by: nscuro --- .../tasks/BomUploadProcessingTaskTest.java | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java b/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java index 717008915..901daf8da 100644 --- a/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java @@ -948,6 +948,176 @@ public void informIssue3433Test() throws Exception { }); } + @Test // https://github.com/DependencyTrack/dependency-track/issues/3498 + public void informUpdateExistingLicenseTest() throws Exception { + final var existingLicense = new License(); + existingLicense.setLicenseId("GPL-3.0-or-later"); + existingLicense.setName("GPL-3.0-or-later"); + qm.persist(existingLicense); + + final var updatedLicense = new License(); + updatedLicense.setLicenseId("Apache-2.0"); + updatedLicense.setName("Apache-2.0"); + qm.persist(updatedLicense); + + final var project = new Project(); + project.setName("acme-update-license-app"); + qm.persist(project); + + final byte[] existingBomBytes = """ + { + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "acme-lib-y", + "version": "2.0.0", + "licenses": [ + { + "license": { + "name": "GPL-3.0-or-later" + } + } + ] + } + ] + } + """.getBytes(StandardCharsets.UTF_8); + + var bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), createTempBomFile(existingBomBytes)); + qm.createWorkflowSteps(bomUploadEvent.getChainIdentifier()); + new BomUploadProcessingTask().inform(bomUploadEvent); + assertBomProcessedNotification(); + + assertThat(qm.getAllComponents(project)).satisfiesExactly(component -> { + assertThat(component.getResolvedLicense()).isNotNull(); + assertThat(component.getResolvedLicense().getLicenseId()).isEqualTo(existingLicense.getLicenseId()); + }); + + // Upload bom again but with new license + final byte[] updatedBomBytes = """ + { + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "acme-lib-y", + "version": "2.0.0", + "licenses": [ + { + "license": { + "name": "Apache-2.0" + } + } + ] + } + ] + } + """.getBytes(StandardCharsets.UTF_8); + + bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), createTempBomFile(updatedBomBytes)); + qm.createWorkflowSteps(bomUploadEvent.getChainIdentifier()); + new BomUploadProcessingTask().inform(bomUploadEvent); + assertBomProcessedNotification(); + qm.getPersistenceManager().evictAll(); + + assertThat(qm.getAllComponents(project)).satisfiesExactly(component -> { + assertThat(component.getResolvedLicense()).isNotNull(); + assertThat(component.getResolvedLicense().getLicenseId()).isEqualTo(updatedLicense.getLicenseId()); + }); + + } + + @Test // https://github.com/DependencyTrack/dependency-track/issues/3498 + public void informDeleteExistingLicenseTest() throws Exception { + final var existingLicense = new License(); + existingLicense.setLicenseId("GPL-3.0-or-later"); + existingLicense.setName("GPL-3.0-or-later"); + qm.persist(existingLicense); + + final var project = new Project(); + project.setName("acme-update-license-app"); + qm.persist(project); + + final byte[] existingBomBytes = """ + { + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "acme-lib-y", + "version": "2.0.0", + "licenses": [ + { + "license": { + "name": "GPL-3.0-or-later" + } + } + ] + } + ] + } + """.getBytes(StandardCharsets.UTF_8); + + var bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), createTempBomFile(existingBomBytes)); + qm.createWorkflowSteps(bomUploadEvent.getChainIdentifier()); + new BomUploadProcessingTask().inform(bomUploadEvent); + assertBomProcessedNotification(); + + assertThat(qm.getAllComponents(project)).satisfiesExactly(component -> { + assertThat(component.getResolvedLicense()).isNotNull(); + assertThat(component.getResolvedLicense().getLicenseId()).isEqualTo(existingLicense.getLicenseId()); + }); + + // Upload bom again but with license deleted + final byte[] updatedBomBytes = """ + { + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "acme-lib-y", + "version": "2.0.0", + "licenses": [] + } + ] + } + """.getBytes(StandardCharsets.UTF_8); + + bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), createTempBomFile(updatedBomBytes)); + qm.createWorkflowSteps(bomUploadEvent.getChainIdentifier()); + new BomUploadProcessingTask().inform(bomUploadEvent); + assertBomProcessedNotification(); + qm.getPersistenceManager().evictAll(); + + assertThat(qm.getAllComponents(project)).satisfiesExactly(component -> { + assertThat(component.getResolvedLicense()).isNull(); + assertThat(component.getLicense()).isNull(); + assertThat(component.getLicenseUrl()).isNull(); + assertThat(component.getLicenseExpression()).isNull(); + }); + } + @Test public void informWithBomContainingServiceTest() throws Exception { final Project project = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false);