@@ -62,13 +62,16 @@ import org.ossreviewtoolkit.clients.fossid.listIgnoredFiles
62
62
import org.ossreviewtoolkit.clients.fossid.listMarkedAsIdentifiedFiles
63
63
import org.ossreviewtoolkit.clients.fossid.listPendingFiles
64
64
import org.ossreviewtoolkit.clients.fossid.listScansForProject
65
+ import org.ossreviewtoolkit.clients.fossid.listSnippets
65
66
import org.ossreviewtoolkit.clients.fossid.model.Scan
66
67
import org.ossreviewtoolkit.clients.fossid.model.identification.common.LicenseMatchType
67
68
import org.ossreviewtoolkit.clients.fossid.model.identification.identifiedFiles.IdentifiedFile
68
69
import org.ossreviewtoolkit.clients.fossid.model.identification.ignored.IgnoredFile
69
70
import org.ossreviewtoolkit.clients.fossid.model.identification.markedAsIdentified.License
70
71
import org.ossreviewtoolkit.clients.fossid.model.identification.markedAsIdentified.LicenseFile
71
72
import org.ossreviewtoolkit.clients.fossid.model.identification.markedAsIdentified.MarkedAsIdentifiedFile
73
+ import org.ossreviewtoolkit.clients.fossid.model.result.MatchType
74
+ import org.ossreviewtoolkit.clients.fossid.model.result.Snippet
72
75
import org.ossreviewtoolkit.clients.fossid.model.rules.IgnoreRule
73
76
import org.ossreviewtoolkit.clients.fossid.model.rules.RuleScope
74
77
import org.ossreviewtoolkit.clients.fossid.model.rules.RuleType
@@ -78,23 +81,29 @@ import org.ossreviewtoolkit.clients.fossid.model.status.UnversionedScanDescripti
78
81
import org.ossreviewtoolkit.clients.fossid.runScan
79
82
import org.ossreviewtoolkit.downloader.VersionControlSystem
80
83
import org.ossreviewtoolkit.downloader.vcs.Git
84
+ import org.ossreviewtoolkit.model.ArtifactProvenance
81
85
import org.ossreviewtoolkit.model.CopyrightFinding
86
+ import org.ossreviewtoolkit.model.Hash
82
87
import org.ossreviewtoolkit.model.Identifier
83
88
import org.ossreviewtoolkit.model.Issue
84
89
import org.ossreviewtoolkit.model.LicenseFinding
85
90
import org.ossreviewtoolkit.model.Package
86
91
import org.ossreviewtoolkit.model.PackageType
92
+ import org.ossreviewtoolkit.model.RemoteArtifact
87
93
import org.ossreviewtoolkit.model.ScanResult
88
94
import org.ossreviewtoolkit.model.Severity
89
95
import org.ossreviewtoolkit.model.TextLocation
90
96
import org.ossreviewtoolkit.model.VcsInfo
91
97
import org.ossreviewtoolkit.model.VcsType
92
98
import org.ossreviewtoolkit.model.config.ScannerConfiguration
99
+ import org.ossreviewtoolkit.model.utils.Snippet as OrtSnippet
100
+ import org.ossreviewtoolkit.model.utils.SnippetFinding
93
101
import org.ossreviewtoolkit.scanner.ScanContext
94
102
import org.ossreviewtoolkit.scanner.scanners.fossid.FossId.Companion.SCAN_CODE_KEY
95
103
import org.ossreviewtoolkit.scanner.scanners.fossid.FossId.Companion.SCAN_ID_KEY
96
104
import org.ossreviewtoolkit.scanner.scanners.fossid.FossId.Companion.SERVER_URL_KEY
97
105
import org.ossreviewtoolkit.scanner.scanners.fossid.FossId.Companion.convertGitUrlToProjectName
106
+ import org.ossreviewtoolkit.utils.spdx.SpdxExpression
98
107
99
108
@Suppress(" LargeClass" )
100
109
class FossIdTest : WordSpec ({
@@ -314,6 +323,7 @@ class FossIdTest : WordSpec({
314
323
summary.licenseFindings shouldContainExactlyInAnyOrder expectedLicenseFindings
315
324
}
316
325
326
+ // TODO: Deprecation: Remove the pending files in issues. This is a breaking change.
317
327
" report pending files as issues" {
318
328
val projectCode = projectCode(PROJECT )
319
329
val scanCode = scanCode(PROJECT , null)
@@ -328,19 +338,57 @@ class FossIdTest : WordSpec({
328
338
.expectCheckScanStatus(scanCode, ScanStatus .FINISHED )
329
339
.expectCreateScan(projectCode, scanCode, vcsInfo, "")
330
340
.expectDownload(scanCode)
331
- .mockFiles(scanCode, pendingRange = 4..5)
341
+ .mockFiles(scanCode, pendingRange = 4..5, snippetRange = 1..5 )
332
342
333
343
val fossId = createFossId(config)
334
344
335
345
val summary = fossId.scan(createPackage(pkgId, vcsInfo)).summary
336
346
337
- val expectedIssues = listOf(createPendingFile(4), createPendingFile(5)).map {
347
+ val pendingFilesIssues = listOf(createPendingFile(4), createPendingFile(5)).map {
338
348
Issue (Instant .EPOCH , "FossId ", "Pending identification for '$it'.", Severity .HINT )
339
349
}
350
+ val urlMappingIssues = (1..5).map {
351
+ Issue (
352
+ Instant .EPOCH ,
353
+ "FossId ",
354
+ "Cannot determine PURL type for url 'url$it' and provider 'null'.",
355
+ Severity .ERROR
356
+ )
357
+ }
358
+ // Add the mapping issues from the snippet fake URLs: 5 issues for each pending file.
359
+ val expectedIssues = pendingFilesIssues + urlMappingIssues + urlMappingIssues
340
360
341
361
summary.issues.map { it.copy(timestamp = Instant .EPOCH ) } shouldBe expectedIssues
342
362
}
343
363
364
+ " report pending files as snippets" {
365
+ val projectCode = projectCode(PROJECT )
366
+ val scanCode = scanCode(PROJECT , null)
367
+ val config = createConfig(deltaScans = false)
368
+ val vcsInfo = createVcsInfo()
369
+ val scan = createScan(vcsInfo.url, "${vcsInfo.revision}_other ", scanCode)
370
+ val pkgId = createIdentifier(index = 42)
371
+
372
+ FossIdRestService .create(config.serverUrl)
373
+ .expectProjectRequest(projectCode)
374
+ .expectListScans(projectCode, listOf(scan))
375
+ .expectCheckScanStatus(scanCode, ScanStatus .FINISHED )
376
+ .expectCreateScan(projectCode, scanCode, vcsInfo, "")
377
+ .expectDownload(scanCode)
378
+ .mockFiles(scanCode, pendingRange = 1..5, snippetRange = 1..5)
379
+
380
+ val fossId = createFossId(config)
381
+
382
+ val summary = fossId.scan(createPackage(pkgId, vcsInfo)).summary
383
+
384
+ val expectedPendingFile = (1..5).map(::createPendingFile).toSet()
385
+ val expectedSnippetFindings = (1..5).map(::createSnippetFindings).flatten()
386
+
387
+ summary.snippetFindings shouldHaveSize expectedPendingFile.size * 5
388
+ summary.snippetFindings.map { it.sourceLocation.path }.toSet() shouldBe expectedPendingFile
389
+ summary.snippetFindings shouldBe expectedSnippetFindings
390
+ }
391
+
344
392
" create a new project if none exists yet" {
345
393
val projectCode = projectCode(PROJECT )
346
394
val scanCode = scanCode(PROJECT , null)
@@ -1238,6 +1286,52 @@ private fun createIgnoredFile(index: Int): IgnoredFile =
1238
1286
*/
1239
1287
private fun createPendingFile (index : Int ): String = " /pending/file/$index "
1240
1288
1289
+ /* *
1290
+ * Generate a FossID snippet based on the given [index].
1291
+ */
1292
+ private fun createSnippet (index : Int ): Snippet = Snippet (
1293
+ index,
1294
+ " created$index " ,
1295
+ index,
1296
+ index,
1297
+ index,
1298
+ MatchType .PARTIAL ,
1299
+ " reason$index " ,
1300
+ " author$index " ,
1301
+ " artifact$index " ,
1302
+ " version$index " ,
1303
+ " MIT" ,
1304
+ " releaseDate$index " ,
1305
+ " mirror$index " ,
1306
+ " file$index " ,
1307
+ " fileLicense$index " ,
1308
+ " url$index " ,
1309
+ " hits$index " ,
1310
+ index,
1311
+ " updated$index " ,
1312
+ " cpe$index " ,
1313
+ " $index " ,
1314
+ " matchField$index " ,
1315
+ " classification$index " ,
1316
+ " highlighting$index "
1317
+ )
1318
+
1319
+ /* *
1320
+ * Generate a ORT snippet finding based on the given [index].
1321
+ */
1322
+ private fun createSnippetFindings (index : Int ): Set <SnippetFinding > = (1 .. 5 ).map { snippetIndex ->
1323
+ SnippetFinding (
1324
+ TextLocation (" /pending/file/$index " , TextLocation .UNKNOWN_LINE ),
1325
+ OrtSnippet (
1326
+ snippetIndex.toFloat(),
1327
+ TextLocation (" file$snippetIndex " , TextLocation .UNKNOWN_LINE ),
1328
+ ArtifactProvenance (RemoteArtifact (" url$snippetIndex " , Hash .NONE )),
1329
+ " pkg:generic/author$snippetIndex /artifact$snippetIndex @version$snippetIndex " ,
1330
+ SpdxExpression .Companion .parse(" MIT" )
1331
+ )
1332
+ )
1333
+ }.toSet()
1334
+
1241
1335
/* *
1242
1336
* Prepare this service mock to answer a request for a project with the given [projectCode]. Return a response with
1243
1337
* the given [status] and [error].
@@ -1348,12 +1442,14 @@ private fun FossIdServiceWithVersion.mockFiles(
1348
1442
identifiedRange : IntRange = IntRange .EMPTY ,
1349
1443
markedRange : IntRange = IntRange .EMPTY ,
1350
1444
ignoredRange : IntRange = IntRange .EMPTY ,
1351
- pendingRange : IntRange = IntRange .EMPTY
1445
+ pendingRange : IntRange = IntRange .EMPTY ,
1446
+ snippetRange : IntRange = IntRange .EMPTY
1352
1447
): FossIdServiceWithVersion {
1353
1448
val identifiedFiles = identifiedRange.map(::createIdentifiedFile)
1354
1449
val markedFiles = markedRange.map(::createMarkedIdentifiedFile)
1355
1450
val ignoredFiles = ignoredRange.map(::createIgnoredFile)
1356
1451
val pendingFiles = pendingRange.map(::createPendingFile)
1452
+ val snippets = snippetRange.map(::createSnippet)
1357
1453
1358
1454
coEvery { listIdentifiedFiles(USER , API_KEY , scanCode) } returns
1359
1455
PolymorphicResponseBody (
@@ -1367,6 +1463,8 @@ private fun FossIdServiceWithVersion.mockFiles(
1367
1463
PolymorphicResponseBody (status = 1 , data = PolymorphicList (ignoredFiles))
1368
1464
coEvery { listPendingFiles(USER , API_KEY , scanCode) } returns
1369
1465
PolymorphicResponseBody (status = 1 , data = PolymorphicList (pendingFiles))
1466
+ coEvery { listSnippets(USER , API_KEY , scanCode, any()) } returns
1467
+ PolymorphicResponseBody (status = 1 , data = PolymorphicList (snippets))
1370
1468
1371
1469
return this
1372
1470
}
0 commit comments