Skip to content

Commit 306135b

Browse files
committed
fix(fossid-webapp): Ignore duplicate rule creation
A change in FossID 24.2.1 is that the API server returns an error when the client tries to create an ignore rule when an identical rule already exists. The situation can arise because of global ignore rules: defined by an operator, they are automatically assigned to a newly created scan. Therefore, when listing the rules of a previous delta scan, these global rules are also present. The previous commit didn't resolve the issue fully therefore this commit fixes the issue by simply ignoring duplicate rule creation. Signed-off-by: Nicolas Nobelis <[email protected]>
1 parent ffe47b6 commit 306135b

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

plugins/scanners/fossid/src/main/kotlin/events/CloneRepositoryHandler.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,22 @@ class CloneRepositoryHandler(val config: FossIdConfig, val service: FossIdServic
151151

152152
val allRules = excludesRules + legacyRules
153153
allRules.forEach {
154-
service.createIgnoreRule(
154+
val response = service.createIgnoreRule(
155155
config.user.value,
156156
config.apiKey.value,
157157
scanCode,
158158
it.type,
159159
it.value,
160160
RuleScope.SCAN
161-
).checkResponse("create ignore rules", false)
161+
)
162+
// It could be that global rules are automatically added to a scan. Therefore, a failure in creation
163+
// because of duplication should be ignored.
164+
if (response.error != "Rule already exists") {
165+
response.checkResponse("create ignore rules", false)
162166

163-
logger.info {
164-
"Ignore rule of type '${it.type}' and value '${it.value}' has been created for the new scan."
167+
logger.info {
168+
"Ignore rule of type '${it.type}' and value '${it.value}' has been created for the new scan."
169+
}
165170
}
166171
}
167172

plugins/scanners/fossid/src/test/kotlin/FossIdTest.kt

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ import org.ossreviewtoolkit.clients.fossid.downloadFromGit
5555
import org.ossreviewtoolkit.clients.fossid.extractArchives
5656
import org.ossreviewtoolkit.clients.fossid.listIgnoreRules
5757
import org.ossreviewtoolkit.clients.fossid.listScansForProject
58+
import org.ossreviewtoolkit.clients.fossid.model.rules.IgnoreRule
59+
import org.ossreviewtoolkit.clients.fossid.model.rules.RuleType
5860
import org.ossreviewtoolkit.clients.fossid.model.status.DownloadStatus
5961
import org.ossreviewtoolkit.clients.fossid.model.status.ScanStatus
6062
import org.ossreviewtoolkit.clients.fossid.removeUploadedContent
@@ -700,6 +702,60 @@ class FossIdTest : WordSpec({
700702
}
701703
}
702704

705+
"should not fail when trying to create a legacy rule if it already exist" {
706+
val projectCode = PROJECT
707+
val originCode = "originalScanCode"
708+
val scanCode = scanCode(PROJECT, FossId.DeltaTag.DELTA)
709+
val config = createConfig()
710+
val vcsInfo = createVcsInfo()
711+
val scan = createScan(vcsInfo.url, vcsInfo.revision, originCode)
712+
713+
val existingRule = IgnoreRule(
714+
SCAN_ID,
715+
RuleType.DIRECTORY,
716+
"*.git",
717+
SCAN_ID,
718+
"Global rule for .git directories"
719+
)
720+
721+
val service = FossIdRestService.create(config.serverUrl)
722+
.expectProjectRequest(projectCode)
723+
.expectListScans(projectCode, listOf(scan))
724+
.expectCheckScanStatus(originCode, ScanStatus.FINISHED)
725+
.expectCheckScanStatus(scanCode, ScanStatus.NOT_STARTED, ScanStatus.FINISHED)
726+
.expectCreateScan(projectCode, scanCode, vcsInfo)
727+
.expectDownload(scanCode)
728+
.expectListIgnoreRules(originCode, listOf(existingRule))
729+
.expectCreateIgnoreRule(scanCode, existingRule.type, existingRule.value, error = true)
730+
.mockFiles(scanCode)
731+
coEvery { service.runScan(any()) } returns EntityResponseBody(status = 1)
732+
733+
val fossId = createFossId(config)
734+
735+
fossId.scan(
736+
createPackage(createIdentifier(index = 1), vcsInfo),
737+
mapOf(FossId.PROJECT_REVISION_LABEL to "master")
738+
)
739+
740+
val comment = createOrtScanComment(vcsInfo.url, vcsInfo.revision, "master").asJsonString()
741+
coVerify {
742+
service.createScan(USER, API_KEY, projectCode, scanCode, vcsInfo.url, vcsInfo.revision, comment)
743+
service.downloadFromGit(USER, API_KEY, scanCode)
744+
service.checkDownloadStatus(USER, API_KEY, scanCode)
745+
service.runScan(
746+
USER,
747+
API_KEY,
748+
scanCode,
749+
mapOf(
750+
*FossId.deltaScanRunParameters(originCode),
751+
"auto_identification_detect_declaration" to "0",
752+
"auto_identification_detect_copyright" to "0",
753+
"sensitivity" to "10"
754+
)
755+
)
756+
}
757+
}
758+
703759
"create a delta scan for an existing scan with a legacy comment" {
704760
val projectCode = PROJECT
705761
val originCode = "originalScanCode"

plugins/scanners/fossid/src/test/kotlin/TestUtils.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,26 @@ internal fun FossIdServiceWithVersion.expectListIgnoreRules(
544544
return this
545545
}
546546

547+
/**
548+
* Prepare this service mock to return the list of [rules] for the given [scanCode].
549+
*/
550+
internal fun FossIdServiceWithVersion.expectCreateIgnoreRule(
551+
scanCode: String,
552+
type: RuleType,
553+
value: String,
554+
scope: RuleScope = RuleScope.SCAN,
555+
error: Boolean = false
556+
): FossIdServiceWithVersion {
557+
if (error) {
558+
coEvery { createIgnoreRule(USER, API_KEY, scanCode, type, value, scope) } returns
559+
EntityResponseBody("create ignore rules", error = "Rule already exists")
560+
} else {
561+
coEvery { createIgnoreRule(USER, API_KEY, scanCode, type, value, scope) } returns EntityResponseBody()
562+
}
563+
564+
return this
565+
}
566+
547567
/**
548568
* Prepare this service mock to expect a request to create an 'ignore rule' for the given [scanCode], [ruleType],
549569
* [value] and [scope].

0 commit comments

Comments
 (0)