From 07d854ad48ba215cf2daf5145ecd62a08cb1b88b Mon Sep 17 00:00:00 2001 From: Will Lo Date: Tue, 22 Oct 2024 00:53:59 -0700 Subject: [PATCH 1/5] patch #4978 --- .../services/amazonq/project/ProjectContextController.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt index 2169a5bbad6..e40b25ea571 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt @@ -12,7 +12,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.warn -import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings @Service(Service.Level.PROJECT) class ProjectContextController(private val project: Project, private val cs: CoroutineScope) : Disposable { @@ -20,9 +19,7 @@ class ProjectContextController(private val project: Project, private val cs: Cor private val projectContextProvider: ProjectContextProvider = ProjectContextProvider(project, encoderServer, cs) init { cs.launch { - if (CodeWhispererSettings.getInstance().isProjectContextEnabled()) { - encoderServer.downloadArtifactsAndStartServer() - } + encoderServer.downloadArtifactsAndStartServer() } } From abd2e7a4bedfeffb5deb96c3d8ff298d3ab03b58 Mon Sep 17 00:00:00 2001 From: Will Lo Date: Tue, 22 Oct 2024 02:32:04 -0700 Subject: [PATCH 2/5] tst --- .../context/ProjectContextControllerTest.kt | 82 +++++++++++++++++++ .../project/ProjectContextController.kt | 9 +- 2 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt new file mode 100644 index 00000000000..e525ca752af --- /dev/null +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt @@ -0,0 +1,82 @@ +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.workspace.context + +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.testFramework.ProjectExtension +import com.intellij.testFramework.junit5.TestDisposable +import com.intellij.testFramework.replaceService +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.test.runTest +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.RegisterExtension +import org.mockito.Mockito.mockConstruction +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.times +import org.mockito.kotlin.verify +import software.aws.toolkits.jetbrains.core.coroutines.EDT +import software.aws.toolkits.jetbrains.services.amazonq.project.EncoderServer +import software.aws.toolkits.jetbrains.services.amazonq.project.ProjectContextController +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings + +class ProjectContextControllerTest { + lateinit var sut: ProjectContextController + + val project: Project + get() = projectExtension.project + + @BeforeEach + fun setup() {} + + @Test + fun `should start encoderServer if chat project context is disabled`(@TestDisposable disposable: Disposable) = runTest { + ApplicationManager.getApplication() + .replaceService( + CodeWhispererSettings::class.java, + mock { on { isProjectContextEnabled() } doReturn false }, + disposable + ) + + assertEncoderServerStarted() + } + + @Test + fun `should start encoderServer if chat project context is enabled`(@TestDisposable disposable: Disposable) = runTest { + ApplicationManager.getApplication() + .replaceService( + CodeWhispererSettings::class.java, + mock { on { isProjectContextEnabled() } doReturn true }, + disposable + ) + + assertEncoderServerStarted() + } + + private fun assertEncoderServerStarted() = runTest { + mockConstruction(EncoderServer::class.java).use { +// val cs = TestScope(context = StandardTestDispatcher()) // not works and the test never finish + val cs = CoroutineScope(EDT) // works + + assertThat(it.constructed()).isEmpty() + sut = ProjectContextController(project, cs) + assertThat(it.constructed()).hasSize(1) + +// cs.advanceUntilIdle() + sut.initJob.join() + val encoderServer = it.constructed().first() + verify(encoderServer, times(1)).downloadArtifactsAndStartServer() + } + } + + private companion object { + @JvmField + @RegisterExtension + val projectExtension = ProjectExtension() + } +} diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt index e40b25ea571..aeaabff547a 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt @@ -9,18 +9,19 @@ import com.intellij.openapi.components.service import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job import kotlinx.coroutines.launch import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.warn @Service(Service.Level.PROJECT) class ProjectContextController(private val project: Project, private val cs: CoroutineScope) : Disposable { + // TODO: Ideally we should inject dependencies via constructor for easier testing, refer to how [TelemetryService] inject publisher and batcher private val encoderServer: EncoderServer = EncoderServer(project) private val projectContextProvider: ProjectContextProvider = ProjectContextProvider(project, encoderServer, cs) - init { - cs.launch { - encoderServer.downloadArtifactsAndStartServer() - } + + val initJob: Job = cs.launch { + encoderServer.downloadArtifactsAndStartServer() } fun getProjectContextIndexComplete() = projectContextProvider.isIndexComplete.get() From 73db245a9962a0bcc8ef5b832162463164e19b61 Mon Sep 17 00:00:00 2001 From: Will Lo Date: Tue, 22 Oct 2024 11:17:24 -0700 Subject: [PATCH 3/5] patch --- .../context/ProjectContextControllerTest.kt | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt index e525ca752af..ef3a78f5795 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt @@ -12,7 +12,6 @@ import com.intellij.testFramework.replaceService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.RegisterExtension import org.mockito.Mockito.mockConstruction @@ -31,8 +30,11 @@ class ProjectContextControllerTest { val project: Project get() = projectExtension.project - @BeforeEach - fun setup() {} + private companion object { + @JvmField + @RegisterExtension + val projectExtension = ProjectExtension() + } @Test fun `should start encoderServer if chat project context is disabled`(@TestDisposable disposable: Disposable) = runTest { @@ -73,10 +75,4 @@ class ProjectContextControllerTest { verify(encoderServer, times(1)).downloadArtifactsAndStartServer() } } - - private companion object { - @JvmField - @RegisterExtension - val projectExtension = ProjectExtension() - } } From 2f5f80b0b5fa52e4c4a26b63c77759954fe3ab4c Mon Sep 17 00:00:00 2001 From: Will Lo Date: Tue, 22 Oct 2024 12:32:30 -0700 Subject: [PATCH 4/5] empty commit From cd8d651549c5f0905f7c2bf53222fc2ff750cb20 Mon Sep 17 00:00:00 2001 From: Will Lo Date: Tue, 22 Oct 2024 13:36:38 -0700 Subject: [PATCH 5/5] fix test freeze --- .../workspace/context/ProjectContextControllerTest.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt index ef3a78f5795..385d269bee9 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextControllerTest.kt @@ -19,7 +19,7 @@ import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.times import org.mockito.kotlin.verify -import software.aws.toolkits.jetbrains.core.coroutines.EDT +import software.aws.toolkits.jetbrains.core.coroutines.getCoroutineBgContext import software.aws.toolkits.jetbrains.services.amazonq.project.EncoderServer import software.aws.toolkits.jetbrains.services.amazonq.project.ProjectContextController import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings @@ -62,8 +62,9 @@ class ProjectContextControllerTest { private fun assertEncoderServerStarted() = runTest { mockConstruction(EncoderServer::class.java).use { + // TODO: figure out how to make this testScope work // val cs = TestScope(context = StandardTestDispatcher()) // not works and the test never finish - val cs = CoroutineScope(EDT) // works + val cs = CoroutineScope(getCoroutineBgContext()) // works assertThat(it.constructed()).isEmpty() sut = ProjectContextController(project, cs)