2020package org.ossreviewtoolkit.plugins.scanners.scanoss
2121
2222import com.github.tomakehurst.wiremock.WireMockServer
23+ import com.github.tomakehurst.wiremock.client.WireMock
2324import com.github.tomakehurst.wiremock.core.WireMockConfiguration
2425
26+ import io.kotest.assertions.fail
2527import io.kotest.core.spec.style.StringSpec
2628import io.kotest.matchers.collections.containExactly
2729import io.kotest.matchers.collections.containExactlyInAnyOrder
2830import io.kotest.matchers.should
31+ import io.kotest.matchers.shouldBe
2932
3033import io.mockk.spyk
3134
@@ -39,11 +42,16 @@ import org.ossreviewtoolkit.model.SnippetFinding
3942import org.ossreviewtoolkit.model.TextLocation
4043import org.ossreviewtoolkit.model.VcsInfo
4144import org.ossreviewtoolkit.model.VcsType
45+ import org.ossreviewtoolkit.model.config.Excludes
46+ import org.ossreviewtoolkit.model.config.PathExclude
47+ import org.ossreviewtoolkit.model.config.PathExcludeReason
4248import org.ossreviewtoolkit.plugins.api.Secret
4349import org.ossreviewtoolkit.scanner.ScanContext
4450import org.ossreviewtoolkit.utils.spdx.SpdxExpression
4551
52+ // Define separate directories for different test scenarios.
4653private val TEST_DIRECTORY_TO_SCAN = File (" src/test/assets/filesToScan" )
54+ private val EXCLUSION_TEST_DIRECTORY = File (" src/test/assets/exclusionTest" )
4755
4856/* *
4957 * A test for scanning a directory with the [ScanOss] scanner.
@@ -110,4 +118,61 @@ class ScanOssScannerDirectoryTest : StringSpec({
110118 )
111119 }
112120 }
121+
122+ " Scanner should exclude only files matching the specified path pattern (**/*.kt)" {
123+ val pathExcludes = listOf(
124+ PathExclude (
125+ pattern = "**/*.kt", // Glob pattern to match all .kt files in any directory.
126+ reason = PathExcludeReason .BUILD_TOOL_OF ,
127+ comment = "Excluding .kt source files from scanning"
128+ )
129+ )
130+
131+ // Verify our test file exists. This file should be included in the scan since it does not match the exclusion
132+ // pattern (it is a .go file, not a .kt file).
133+ val includedFile = File (EXCLUSION_TEST_DIRECTORY , "server.go")
134+ if (!includedFile.isFile) {
135+ fail("The file ${includedFile.absolutePath} does not exist - test environment may not be properly set up")
136+ }
137+
138+ // Run the scanner with our exclusion pattern. This will traverse the directory and should skip .kt files.
139+ scanner.scanPath(
140+ EXCLUSION_TEST_DIRECTORY ,
141+ ScanContext (
142+ labels = emptyMap(),
143+ packageType = PackageType .PACKAGE ,
144+ excludes = Excludes (paths = pathExcludes)
145+ )
146+ )
147+
148+ // Retrieve all HTTP POST requests captured by WireMock during the scan.
149+ val requests = server.findAll(WireMock .postRequestedFor(WireMock .anyUrl()))
150+ val requestBodies = requests.map { it.bodyAsString }
151+
152+ // The scanner sends files to the API in a multipart/form-data POST request with this format:
153+ // --boundary
154+ // Content-Disposition: form-data; name="file"; filename="[UUID].wfp"
155+ // Content-Type: text/plain; charset=utf-8
156+ // Content-Length: [length]
157+ //
158+ // file=[hash],[size],[filename]
159+ // [fingerprint data for the file]
160+ // --boundary--
161+
162+ // Extract included filenames using a regex pattern from the ScanOSS HTTP POST.
163+ // The pattern matches lines starting with "file=" followed by hash and size, then captures the filename.
164+ val filenamePattern = " file=.*?,.*?,(.+)" .toRegex(RegexOption .MULTILINE )
165+ val includedFiles = requestBodies.flatMap { body ->
166+ filenamePattern.findAll(body).map { it.groupValues[1 ] }.toList()
167+ }
168+
169+ // Verify that .kt files were excluded from the scan.
170+ // These assertions check that Kotlin files are not present in the API requests.
171+ includedFiles.any { it.contains("ArchiveUtils .kt") } shouldBe false
172+ includedFiles.any { it.contains("ScannerFactory .kt") } shouldBe false
173+
174+ // Verify that non-.kt files were included in the scan.
175+ // This assertion checks that our Go file was sent to the API.
176+ includedFiles.any { it.contains("server.go") } shouldBe true
177+ }
113178})
0 commit comments