Skip to content

Commit

Permalink
fix: trigger scan on startup for non-code (#513)
Browse files Browse the repository at this point in the history
  • Loading branch information
teodora-sandu authored Apr 18, 2024
1 parent 0460fe4 commit eefaa7e
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## [2.7.15]
### Fixed
- Re-enable scan results when re-enabling different scan types
- (LS Preview) do not trigger scan on startup for Snyk Code multiple times

## [2.7.14]
### Added
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/io/snyk/plugin/SnykPostStartupActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ class SnykPostStartupActivity : ProjectActivity {
getKubernetesImageCache(project)?.cacheKubernetesFileFromProject()
}

if (settings.scanOnSave && isSnykCodeLSEnabled()) {
getSnykTaskQueueService(project)?.scan()
if (settings.scanOnSave && (isSnykCodeLSEnabled() || isSnykOSSLSEnabled() || isSnykIaCLSEnabled())) {
getSnykTaskQueueService(project)?.scan(true)
}

ExtensionPointsUtil.controllerManager.extensionList.forEach {
Expand Down
5 changes: 5 additions & 0 deletions src/main/kotlin/io/snyk/plugin/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ fun isFileListenerEnabled(): Boolean = pluginSettings().fileListenerEnabled

fun isSnykCodeLSEnabled(): Boolean = Registry.`is`("snyk.preview.snyk.code.ls.enabled", true)

fun isSnykOSSLSEnabled(): Boolean = false

fun isSnykIaCLSEnabled(): Boolean = false


fun getWaitForResultsTimeout(): Long =
Registry.intValue(
"snyk.timeout.results.waiting",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class SnykControllerImpl(val project: Project) : SnykController {
* scan enqueues a scan of the project for vulnerabilities.
*/
override fun scan() {
getSnykTaskQueueService(project)?.scan()
getSnykTaskQueueService(project)?.scan(false)
}

/**
Expand Down
18 changes: 14 additions & 4 deletions src/main/kotlin/io/snyk/plugin/services/SnykTaskQueueService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import io.snyk.plugin.isContainerEnabled
import io.snyk.plugin.isIacEnabled
import io.snyk.plugin.isSnykCodeLSEnabled
import io.snyk.plugin.isSnykCodeRunning
import io.snyk.plugin.isSnykIaCLSEnabled
import io.snyk.plugin.isSnykOSSLSEnabled
import io.snyk.plugin.net.ClientException
import io.snyk.plugin.pluginSettings
import io.snyk.plugin.refreshAnnotationsForOpenFiles
Expand Down Expand Up @@ -98,7 +100,7 @@ class SnykTaskQueueService(val project: Project) {
}
}

fun scan() {
fun scan(isStartup: Boolean) {
taskQueue.run(object : Task.Backgroundable(project, "Snyk: initializing...", true) {
override fun run(indicator: ProgressIndicator) {
if (!confirmScanningAndSetWorkspaceTrustedStateIfNeeded(project)) return
Expand All @@ -114,14 +116,22 @@ class SnykTaskQueueService(val project: Project) {
if (!isSnykCodeLSEnabled()) {
scheduleSnykCodeScan()
} else {
LanguageServerWrapper.getInstance().sendScanCommand(project)
// the LS deals with triggering scans at startup
// TODO: Refactor when more than Snyk Code is available in LS for IntelliJ
if (!isStartup) {
LanguageServerWrapper.getInstance().sendScanCommand(project)
}
}
}
if (settings.ossScanEnable) {
scheduleOssScan()
if (!isSnykOSSLSEnabled()) {
scheduleOssScan()
}
}
if (isIacEnabled() && settings.iacScanEnabled) {
scheduleIacScan()
if (!isSnykIaCLSEnabled()) {
scheduleIacScan()
}
}
if (isContainerEnabled() && settings.containerScanEnabled) {
scheduleContainerScan()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import snyk.analytics.AnalysisIsTriggered
class SnykRunScanAction : AnAction(AllIcons.Actions.Execute), DumbAware {

override fun actionPerformed(actionEvent: AnActionEvent) {
getSnykTaskQueueService(actionEvent.project!!)?.scan()
getSnykTaskQueueService(actionEvent.project!!)?.scan(false)

getSnykAnalyticsService().logAnalysisIsTriggered(
AnalysisIsTriggered.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class IssueViewOptionsPanel(
.actionListener{ event, it ->
if (canBeChanged(it, it.isSelected)) {
currentOpenIssuesEnabled = it.isSelected
getSnykTaskQueueService(project)?.scan()
getSnykTaskQueueService(project)?.scan(false)
}
}
// bindSelected is needed to trigger apply() on the settings dialog that this panel is rendered in
Expand All @@ -44,7 +44,7 @@ class IssueViewOptionsPanel(
.actionListener{ event, it ->
if (canBeChanged(it, it.isSelected)) {
currentIgnoredIssuesEnabled = it.isSelected
getSnykTaskQueueService(project)?.scan()
getSnykTaskQueueService(project)?.scan(false)
}
}
.bindSelected(settings::ignoredIssuesEnabled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ class SnykToolWindowPanel(val project: Project) : JPanel(), Disposable {
.build()
)

getSnykTaskQueueService(project)?.scan()
getSnykTaskQueueService(project)?.scan(false)
}

fun displayAuthPanel() {
Expand Down
6 changes: 4 additions & 2 deletions src/main/kotlin/snyk/common/lsp/LanguageServerWrapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import io.snyk.plugin.getSnykTaskQueueService
import io.snyk.plugin.getUserAgentString
import io.snyk.plugin.isCliInstalled
import io.snyk.plugin.isSnykCodeLSEnabled
import io.snyk.plugin.isSnykIaCLSEnabled
import io.snyk.plugin.isSnykOSSLSEnabled
import io.snyk.plugin.pluginSettings
import io.snyk.plugin.toLanguageServerURL
import io.snyk.plugin.ui.SnykBalloonNotificationHelper
Expand Down Expand Up @@ -306,10 +308,10 @@ class LanguageServerWrapper(
fun getSettings(): LanguageServerSettings {
val ps = pluginSettings()
return LanguageServerSettings(
activateSnykOpenSource = false.toString(),
activateSnykOpenSource = isSnykOSSLSEnabled().toString(),
activateSnykCodeSecurity = (isSnykCodeLSEnabled() && ps.snykCodeSecurityIssuesScanEnable).toString(),
activateSnykCodeQuality = (isSnykCodeLSEnabled() && ps.snykCodeQualityIssuesScanEnable).toString(),
activateSnykIac = false.toString(),
activateSnykIac = isSnykIaCLSEnabled().toString(),
organization = ps.organization,
insecure = ps.ignoreUnknownCA.toString(),
endpoint = getEndpointUrl(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.snyk.plugin.services

import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.openapi.util.registry.Registry
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.replaceService
Expand All @@ -12,12 +13,14 @@ import io.mockk.mockkStatic
import io.mockk.spyk
import io.mockk.unmockkAll
import io.mockk.verify
import io.snyk.plugin.DEFAULT_TIMEOUT_FOR_SCAN_WAITING_MS
import io.snyk.plugin.getCliFile
import io.snyk.plugin.getContainerService
import io.snyk.plugin.getIacService
import io.snyk.plugin.getOssService
import io.snyk.plugin.getSnykCachedResults
import io.snyk.plugin.getSnykCliDownloaderService
import io.snyk.plugin.getSnykCode
import io.snyk.plugin.isCliInstalled
import io.snyk.plugin.isContainerEnabled
import io.snyk.plugin.isIacEnabled
Expand Down Expand Up @@ -92,7 +95,7 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() {
setupDummyCliFile()
val snykTaskQueueService = project.service<SnykTaskQueueService>()

snykTaskQueueService.scan()
snykTaskQueueService.scan(false)
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()

assertTrue(snykTaskQueueService.getTaskQueue().isEmpty)
Expand All @@ -103,13 +106,12 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() {
assertTrue(snykTaskQueueService.getTaskQueue().isEmpty)
assertNull(snykTaskQueueService.ossScanProgressIndicator)
}

fun testCliDownloadBeforeScanIfNeeded() {
setupAppSettingsForDownloadTests()
every { isCliInstalled() } returns true

val snykTaskQueueService = project.service<SnykTaskQueueService>()
snykTaskQueueService.scan()
snykTaskQueueService.scan(false)

PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()
assertTrue(snykTaskQueueService.getTaskQueue().isEmpty)
Expand All @@ -123,7 +125,7 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() {
val snykTaskQueueService = project.service<SnykTaskQueueService>()
every { isCliInstalled() } returns true

snykTaskQueueService.scan()
snykTaskQueueService.scan(false)

PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()
assertTrue(snykTaskQueueService.getTaskQueue().isEmpty)
Expand Down Expand Up @@ -169,7 +171,7 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() {
settings.snykCodeQualityIssuesScanEnable = true
settings.token = "testToken"

snykTaskQueueService.scan()
snykTaskQueueService.scan(false)
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()

verify { snykApiServiceMock.getSastSettings() }
Expand Down Expand Up @@ -202,7 +204,7 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() {
every { isCliInstalled() } returns true
every { getIacService(project)?.scan() } returns fakeIacResult

snykTaskQueueService.scan()
snykTaskQueueService.scan(false)
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()

assertEquals(fakeIacResult, getSnykCachedResults(project)?.currentIacResult)
Expand All @@ -225,11 +227,90 @@ class SnykTaskQueueServiceTest : LightPlatformTestCase() {

getSnykCachedResults(project)?.currentContainerResult = null

snykTaskQueueService.scan()
snykTaskQueueService.scan(false)
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()

await().atMost(2, TimeUnit.SECONDS).until {
getSnykCachedResults(project)?.currentContainerResult != null
}
}

fun testSnykTaskQueueServiceScanCodeOnStartupAndFailsWhenLS() {
val registryValue = Registry.get("snyk.preview.snyk.code.ls.enabled")
registryValue.setValue(false)

val snykTaskQueueService = project.service<SnykTaskQueueService>()
val settings = pluginSettings()
settings.ossScanEnable = true
settings.snykCodeSecurityIssuesScanEnable = true
settings.snykCodeQualityIssuesScanEnable = true
settings.token = "testToken"
settings.iacScanEnabled = true
settings.containerScanEnabled = true
getSnykCachedResults(project)?.currentOssResults = null
getSnykCachedResults(project)?.currentIacResult = null
getSnykCachedResults(project)?.currentContainerResult = null
getSnykCachedResults(project)?.currentSnykCodeResults = null

val fakeOSSResult = OssResult(emptyList())
val fakeIacResult = IacResult(emptyList())
val fakeContainerResult = ContainerResult(emptyList())

mockkStatic("io.snyk.plugin.UtilsKt")
every { isIacEnabled() } returns true
every { isCliInstalled() } returns true
every { getSnykCode(project)?.scan() } returns null
every { getOssService(project)?.scan() } returns fakeOSSResult
every { getIacService(project)?.scan() } returns fakeIacResult
every { getContainerService(project)?.scan() } returns fakeContainerResult

snykTaskQueueService.scan(true)
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()

assertEquals(fakeOSSResult, getSnykCachedResults(project)?.currentOssResults)
assertEquals(fakeIacResult, getSnykCachedResults(project)?.currentIacResult)
await().atMost(2, TimeUnit.SECONDS).until {
getSnykCachedResults(project)?.currentContainerResult != null
}
verify(exactly = 1) { getSnykCode(project)?.scan() }
}
fun testSnykTaskQueueServiceDoesNotScanCodeOnStartupWhenLS() {
val registryValue = Registry.get("snyk.preview.snyk.code.ls.enabled")
registryValue.setValue(true)

val snykTaskQueueService = project.service<SnykTaskQueueService>()
val settings = pluginSettings()
settings.ossScanEnable = true
settings.snykCodeSecurityIssuesScanEnable = true
settings.snykCodeQualityIssuesScanEnable = true
settings.token = "testToken"
settings.iacScanEnabled = true
settings.containerScanEnabled = true
getSnykCachedResults(project)?.currentOssResults = null
getSnykCachedResults(project)?.currentIacResult = null
getSnykCachedResults(project)?.currentContainerResult = null
getSnykCachedResults(project)?.currentSnykCodeResults = null

val fakeOSSResult = OssResult(emptyList())
val fakeIacResult = IacResult(emptyList())
val fakeContainerResult = ContainerResult(emptyList())

mockkStatic("io.snyk.plugin.UtilsKt")
every { isIacEnabled() } returns true
every { isCliInstalled() } returns true
every { getOssService(project)?.scan() } returns fakeOSSResult
every { getIacService(project)?.scan() } returns fakeIacResult
every { getContainerService(project)?.scan() } returns fakeContainerResult

snykTaskQueueService.scan(true)
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()

assertEquals(fakeOSSResult, getSnykCachedResults(project)?.currentOssResults)
assertEquals(fakeIacResult, getSnykCachedResults(project)?.currentIacResult)
await().atMost(2, TimeUnit.SECONDS).until {
getSnykCachedResults(project)?.currentContainerResult != null
}
verify(exactly = 0) { getSnykCode(project)?.scan() }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() {
} returns (iacGoofJson)
getIacService(project)?.setConsoleCommandRunner(mockRunner)

project.service<SnykTaskQueueService>().scan()
project.service<SnykTaskQueueService>().scan(false)
PlatformTestUtil.waitWhileBusy(toolWindowPanel.getTree())
}

Expand Down Expand Up @@ -598,7 +598,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() {
every { getIacService(project)?.scan() } returns iacResultWithError

// actual test run
project.service<SnykTaskQueueService>().scan()
project.service<SnykTaskQueueService>().scan(false)

PlatformTestUtil.waitWhileBusy(toolWindowPanel.getTree())

Expand Down Expand Up @@ -704,7 +704,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() {
setUpContainerTest(containerResultWithError)

// actual test run
project.service<SnykTaskQueueService>().scan()
project.service<SnykTaskQueueService>().scan(false)

PlatformTestUtil.waitWhileBusy(toolWindowPanel.getTree())

Expand All @@ -731,7 +731,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() {
setUpContainerTest(fakeContainerResult)

// actual test run
project.service<SnykTaskQueueService>().scan()
project.service<SnykTaskQueueService>().scan(false)
PlatformTestUtil.waitWhileBusy(toolWindowPanel.getTree())

// Assertions
Expand Down Expand Up @@ -765,7 +765,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() {
mockkObject(SnykBalloonNotificationHelper)

// actual test run
project.service<SnykTaskQueueService>().scan()
project.service<SnykTaskQueueService>().scan(false)
PlatformTestUtil.waitWhileBusy(toolWindowPanel.getTree())

// Assertions
Expand Down Expand Up @@ -797,7 +797,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() {
setUpContainerTest(fakeContainerResult)

// actual test run
project.service<SnykTaskQueueService>().scan()
project.service<SnykTaskQueueService>().scan(false)
PlatformTestUtil.waitWhileBusy(toolWindowPanel.getTree())

// Assertions
Expand Down Expand Up @@ -879,7 +879,7 @@ class SnykToolWindowPanelIntegTest : HeavyPlatformTestCase() {
setUpContainerTest(containerResult)

// actual test run
project.service<SnykTaskQueueService>().scan()
project.service<SnykTaskQueueService>().scan(false)
PlatformTestUtil.waitWhileBusy(toolWindowPanel.getTree())

return containerResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class SnykToolWindowPanelTest : LightPlatform4TestCase() {
true,
LocalCodeEngine(false, "", false),
)
justRun { taskQueueService.scan() }
justRun { taskQueueService.scan(false) }

cut = SnykToolWindowPanel(project)

Expand All @@ -135,7 +135,7 @@ class SnykToolWindowPanelTest : LightPlatform4TestCase() {
assertNotNull(descriptionPanel)
assertEquals(findOnePixelSplitter(vulnerabilityTree), descriptionPanel!!.parent)

verify(exactly = 1) { taskQueueService.scan() }
verify(exactly = 1) { taskQueueService.scan(false) }
verify(exactly = 1) { analyticsService.logAnalysisIsTriggered(any()) }
}

Expand Down

0 comments on commit eefaa7e

Please sign in to comment.