Skip to content

Commit

Permalink
Fix integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pkukielka committed Aug 5, 2024
1 parent 395e971 commit 9f6df79
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 121 deletions.
49 changes: 1 addition & 48 deletions src/integrationTest/kotlin/com/sourcegraph/cody/AllSuites.kt
Original file line number Diff line number Diff line change
@@ -1,55 +1,8 @@
package com.sourcegraph.cody

import com.sourcegraph.cody.agent.CodyAgentService
import com.sourcegraph.cody.edit.DocumentCodeTest
import com.sourcegraph.cody.util.CodyIntegrationTextFixture
import com.sourcegraph.cody.util.RepeatableSuite
import java.util.concurrent.TimeUnit
import org.junit.AfterClass
import org.junit.runner.RunWith
import org.junit.runners.Suite

/**
* We need a single tearDown() method running after all tests are complete, so agent can be closed
* gracefully and recordings can be saved properly.
*
* Due to the limitations of JUnit 4 this can be done only using SuiteClasses and AfterClass, and we
* are forced to use JUnit 4 because IntelliJ testing classes like `BasePlatformTestCase` are based
* on that version. JUnit 4 jar is part of the ideaIC package. We will upgrade to JUnit 5
* automatically after the platform version bump.
*
* Multiple recording files can be used, but each should have its own suite with tearDown() method
* nad define unique CODY_RECORDING_NAME.
*/
@RunWith(RepeatableSuite::class)
@Suite.SuiteClasses(DocumentCodeTest::class)
class AllSuites {
companion object {
@AfterClass
@JvmStatic
internal fun tearDown() {
CodyAgentService.withAgent(CodyIntegrationTextFixture.myProject!!) { agent ->
val errors = agent.server.testingRequestErrors().get()
// We extract polly.js errors to notify users about the missing recordings, if any
val missingRecordings = errors.filter { it.error?.contains("`recordIfMissing` is") == true }
missingRecordings.forEach { missing ->
System.err.println(
"""Recording is missing: ${missing.error}
|
|------------------------------------------------------------------------------------------
|To fix this problem please run `./gradlew :recordingIntegrationTest`.
|You need to export access tokens first, using script from the `sourcegraph/cody` repository:
|`agent/scripts/export-cody-http-recording-tokens.sh`
|------------------------------------------------------------------------------------------
"""
.trimMargin())
}

agent.server
.shutdown()
.get(CodyIntegrationTextFixture.ASYNC_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS)
agent.server.exit()
}
}
}
}
@RunWith(RepeatableSuite::class) @Suite.SuiteClasses(DocumentCodeTest::class) class AllSuites
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,7 @@ class DocumentCodeTest : CodyIntegrationTextFixture() {

runLensAction(acceptLens!!, EditAcceptAction.ID)
assertNoInlayShown()
assertThat(
myFixture.editor.document.text,
startsWith(
"""/**
| * Imports the necessary Java standard library classes for the Foo class, including the ArrayList class.
| */"""
.trimMargin()))
assertThat(myFixture.editor.document.text, startsWith("/**"))
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.testFramework.EditorTestUtil
import com.intellij.testFramework.HeavyPlatformTestCase
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.fixtures.BasePlatformTestCase
import com.intellij.testFramework.runInEdtAndWait
Expand All @@ -30,6 +31,7 @@ import java.nio.file.Paths
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit
import java.util.regex.Pattern
import kotlin.io.path.pathString

open class CodyIntegrationTextFixture : BasePlatformTestCase(), LensListener {
private val logger = Logger.getInstance(CodyIntegrationTextFixture::class.java)
Expand All @@ -48,26 +50,36 @@ open class CodyIntegrationTextFixture : BasePlatformTestCase(), LensListener {
override fun tearDown() {
try {
LensesService.getInstance(project).removeListener(this)
CodyAgentService.getInstance(myFixture.project).apply {
try {
stopAgent(project)
} catch (x: Exception) {
logger.warn("Error shutting down agent", x)

CodyAgentService.withAgent(project) { agent ->
val errors = agent.server.testingRequestErrors().get()
// We extract polly.js errors to notify users about the missing recordings, if any
val missingRecordings = errors.filter { it.error?.contains("`recordIfMissing` is") == true }
missingRecordings.forEach { missing ->
logger.error(
"""Recording is missing: ${missing.error}
|
|${missing.body}
|
|------------------------------------------------------------------------------------------
|To fix this problem please run `./gradlew :recordingIntegrationTest`.
|You need to export access tokens first, using script from the `sourcegraph/cody` repository:
|`agent/scripts/export-cody-http-recording-tokens.sh`
|------------------------------------------------------------------------------------------
"""
.trimMargin())
}

agent.shutdown().get(ASYNC_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS)
}
} finally {
val testDataPath = Paths.get(myFixture.testDataPath)
super.tearDown()
testDataPath.toFile().deleteRecursively()
}
}

private fun configureFixture() {
// If you don't specify this system property with this setting when running the tests,
// the tests will fail, because IntelliJ will run them from the EDT, which can't block.
// Setting this property invokes the tests from an executor pool thread, which lets us
// block/wait on potentially long-running operations during the integration test.
val policy = System.getProperty("idea.test.execution.policy")
assertTrue(policy == "com.sourcegraph.cody.test.NonEdtIdeaTestExecutionPolicy")

// This is wherever src/integrationTest/resources is on the box running the tests.
val testResourcesDir = File(System.getProperty("test.resources.dir"))
assertTrue(testResourcesDir.exists())
Expand All @@ -77,16 +89,17 @@ open class CodyIntegrationTextFixture : BasePlatformTestCase(), LensListener {
val workspaceRootUri = ConfigUtil.getWorkspaceRootPath(project)

// We copy the test resources there manually, bypassing Gradle, which is picky.
val testDataPath = Paths.get(workspaceRootUri.toString(), "src/").toFile()
testResourcesDir.copyRecursively(testDataPath, overwrite = true)
// We also ensure that all files are properly refreshed to the VFS.
val testDataPath = workspaceRootUri.resolve(name)
testResourcesDir.copyRecursively(testDataPath.toFile(), overwrite = true)
HeavyPlatformTestCase.synchronizeTempDirVfs(testDataPath)

// This useful setting lets us tell the fixture to look where we copied them.
myFixture.testDataPath = testDataPath.path
myFixture.testDataPath = testDataPath.pathString

// The file we pass to configureByFile must be relative to testDataPath.
val projectFile = "testProjects/documentCode/src/main/java/Foo.java"
val sourcePath = Paths.get(testDataPath.path, projectFile).toString()
assertTrue(File(sourcePath).exists())
assertTrue(testDataPath.resolve(projectFile).toFile().exists())
myFixture.configureByFile(projectFile)

initCredentialsAndAgent()
Expand Down Expand Up @@ -116,6 +129,13 @@ open class CodyIntegrationTextFixture : BasePlatformTestCase(), LensListener {
}

private fun checkInitialConditions() {
// If you don't specify this system property with this setting when running the tests,
// the tests will fail, because IntelliJ will run them from the EDT, which can't block.
// Setting this property invokes the tests from an executor pool thread, which lets us
// block/wait on potentially long-running operations during the integration test.
val policy = System.getProperty("idea.test.execution.policy")
assertTrue(policy == "com.sourcegraph.cody.test.NonEdtIdeaTestExecutionPolicy")

val project = myFixture.project

// Check if the project is in dumb mode
Expand Down
Loading

0 comments on commit 9f6df79

Please sign in to comment.