Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration Test framework and an initial test for Document Code #1291

Closed
wants to merge 65 commits into from
Closed
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
b451326
broken integration test attempt
steveyegge Mar 22, 2024
b5d19c9
Make gradle integrationTests working
pkukielka Mar 22, 2024
ce239d6
initial steps towards putting Agent in integration test mode
steveyegge Mar 25, 2024
4d84e12
Removed experimental user setting for inline edits
steveyegge Mar 21, 2024
dacdd76
more work on integration tests
steveyegge Mar 27, 2024
ccfee5b
moved lens group visibility into the lens group
steveyegge Mar 30, 2024
932b1d2
got unblocked on the EDT issue
steveyegge Mar 30, 2024
7dc4b37
got first integration tests working
steveyegge Mar 30, 2024
cfac44d
fixed broken integration test
steveyegge Mar 30, 2024
bac793b
got integration tests working from cli/gradle
steveyegge Mar 30, 2024
ded891e
more work on integration test framework
steveyegge Mar 31, 2024
4edd3a1
fixed a deadlock in the tests
steveyegge Mar 31, 2024
5bc49ba
removed an accidental comment
steveyegge Mar 31, 2024
189dd04
fixed showing the Accept lens group
steveyegge Mar 31, 2024
fdff59f
added a TODO
steveyegge Apr 4, 2024
f2e011c
merged with main
steveyegge Apr 5, 2024
5efd0c5
merged from main and got tests (almost) working again
steveyegge Apr 5, 2024
1a946f7
lowered wait timeouts
steveyegge Apr 5, 2024
9eaa635
some better error logging on timeouts
steveyegge Apr 5, 2024
8cd8ffd
Got integration test working again
steveyegge Apr 6, 2024
16df516
improved a comment
steveyegge Apr 6, 2024
f8b8235
some hygiene and misc fixes
steveyegge Apr 7, 2024
a7243dd
some refactoring of the pubsub code
steveyegge Apr 7, 2024
9665434
renamed intTest to integrationTest
steveyegge Apr 7, 2024
829e6ab
removed code to kill existing agent process
steveyegge Apr 12, 2024
c1a0aba
merged with main
steveyegge Apr 12, 2024
288eeb4
minor refactoring
steveyegge Apr 12, 2024
766b463
more work on Document Code integration test
steveyegge Apr 16, 2024
27f4b5e
removed @-mention instructions for now
steveyegge Apr 16, 2024
6d30b56
added some more integration tests, and refactoring
steveyegge Apr 16, 2024
f32ec5a
some refactoring of the build test targets
steveyegge Apr 17, 2024
ae67ae2
put telemetry in testing mode for integration tests
steveyegge Apr 17, 2024
9778ff2
more work on integration tests and inline edits
steveyegge Apr 18, 2024
78de66c
fixed indentation
steveyegge Apr 19, 2024
17df15e
merged stevey/integration-tests with main
steveyegge May 3, 2024
1a6793a
a bit of work on error lenses
steveyegge May 4, 2024
366e3a3
fixed some compile errors from the merge
steveyegge May 5, 2024
05d7f4a
fixed an EDT error
steveyegge May 7, 2024
e1653c3
fixes for error lenses
steveyegge May 7, 2024
842d42d
initial work on integration tests
steveyegge May 10, 2024
ab26297
merged main
steveyegge May 10, 2024
131cb36
auto-accept on document changes
steveyegge May 10, 2024
b2252b7
minor refactoring cleanup in build file
steveyegge May 11, 2024
b5b2812
more work on integration tests
steveyegge May 13, 2024
f9697e6
some unfinished work on integrationTest
steveyegge May 15, 2024
4dd4bf5
removed unused submodule declaration for jetbrains-shared
steveyegge May 15, 2024
e0c1bd1
more work on integration tests
steveyegge May 15, 2024
da9dbb9
some refactoring of the integration test code
steveyegge May 15, 2024
374dfec
removed accidental redundant declaration
steveyegge May 15, 2024
926dc2b
added some assertions
steveyegge May 15, 2024
64a501c
moved .gitignore back to proper spot
steveyegge May 15, 2024
764dbf9
fixed problem with accidentally deleting our own source
steveyegge May 15, 2024
e763e34
Finished configuring integration tests from sources on disk
steveyegge May 16, 2024
14d07b9
added support for setting caret and selection range in test source files
steveyegge May 17, 2024
62c8d29
merged main
steveyegge May 18, 2024
7eeb1cd
fixed a compile error
steveyegge May 18, 2024
3f45fc1
fixed a bug where performing the inline edit was canceling the task
steveyegge May 18, 2024
c5c2744
comments
steveyegge May 19, 2024
4d61876
more work on integration test pubsub, not quite working yet
steveyegge May 20, 2024
940f5c3
merged main
steveyegge May 27, 2024
fe0865f
fixed another merge error
steveyegge May 27, 2024
8636991
fixed more merge errors
steveyegge May 27, 2024
1ebab91
another merge error slipped through
steveyegge May 27, 2024
7912614
fixed another post-merge bug
steveyegge May 27, 2024
f65fc55
merged origin/main
steveyegge May 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 32 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@ to use if you are uncertain which method to use for debugging. Option 2
is especially useful when you need to set a breakpoint very early in
the Agent startup.

### Using VS Code to debug the Agent

The setup described here also works with VS Code as your debugger and/or
launcher. Both configurations work with IntelliJ and VS Code on the Cody
side, and the VS Code Cody extension has both configurations available
in its default run configurations.

VS Code is usually the better choice for a debugger, because the JetBrains
TypeScript plugin gets very confused over our TypeScript code base, and
cannot search for files or symbols.

Sometimes using JetBrains is more convenient, so we describe both options.

## How to set up Run Configurations

Run configurations are basically IDEA's launcher scripts. You will need
Expand Down Expand Up @@ -381,3 +394,22 @@ see the configuration dropdown at the top.
- Workaround is to exit the target gracefully by quitting each time,
using the menus or hotkeys, rather than force-stopping it.

# Integration Testing

Run the integration tests at the command line with:

```
./gradlew integrationTest
```

If you pass in an access token, it will use the default production LLM
dominiccooney marked this conversation as resolved.
Show resolved Hide resolved
rather than a mock LLM, which can be useful when updating the test if
the protocol changes.

```
CODY_INTEGRATION_TEST_TOKEN=sgp_asdfasdfasdfasdfasdfasdfasdf
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a script in sourcegraph/cody, agent/scripts/export-cody-http-recording-tokens.sh . Can we standardize on using those tokens? Everyone has access to them and there are different variants for rate limited tokens, etc. if we need them down the road.

```

You can run and debug the integration tests, including the Agent node
process, with the instructions above by making new run configurations
for the test.
109 changes: 95 additions & 14 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import java.nio.file.Paths
import java.nio.file.SimpleFileVisitor
import java.nio.file.StandardCopyOption
import java.nio.file.attribute.BasicFileAttributes
import java.util.EnumSet
import java.util.*
import java.util.jar.JarFile
import java.util.zip.ZipFile
import kotlin.script.experimental.jvm.util.hasParentNamed
import org.jetbrains.changelog.markdownToHTML
import org.jetbrains.intellij.tasks.RunPluginVerifierTask.FailureLevel
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
Expand All @@ -27,28 +28,25 @@ val isForceCodeSearchBuild = isForceBuild || properties("forceCodeSearchBuild")

plugins {
id("java")
id("jvm-test-suite")
// Dependencies are locked at this version to work with JDK 11 on CI.
id("org.jetbrains.kotlin.jvm") version "1.9.22"
id("org.jetbrains.kotlin.jvm") version "1.9.22" // Also change in gradle.properties
id("org.jetbrains.intellij") version "1.17.2"
id("org.jetbrains.changelog") version "1.3.1"
id("com.diffplug.spotless") version "6.25.0"
}

val kotlinVersion: String by project
val platformVersion: String by project
val javaVersion: String by project

group = properties("pluginGroup")

version = properties("pluginVersion")

repositories { mavenCentral() }

intellij {
pluginName.set(properties("pluginName"))
version.set(properties("platformVersion"))
type.set(properties("platformType"))

// Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file.
plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty))

updateSinceUntilBuild.set(false)
repositories {
maven { url = uri("https://www.jetbrains.com/intellij-repository/releases") }
mavenCentral()
}

dependencies {
Expand All @@ -57,6 +55,10 @@ dependencies {
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.21.0")
implementation("com.googlecode.java-diff-utils:diffutils:1.3.0")
testImplementation("org.awaitility:awaitility-kotlin:4.2.0")
testImplementation("org.junit.jupiter:junit-jupiter:5.7.0")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:1.9.22")
implementation("org.mockito:mockito-all:1.10.19")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.3.1")
}

spotless {
Expand All @@ -74,9 +76,21 @@ spotless {
ktfmt()
trimTrailingWhitespace()
target("src/**/*.kt")
toggleOffOn()
}
}

intellij {
pluginName.set(properties("pluginName"))
version.set(platformVersion)
type.set(properties("platformType"))

// Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file.
plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty))

updateSinceUntilBuild.set(false)
}

java {
toolchain {
// Always compile the codebase with Java 11 regardless of what Java
Expand All @@ -86,6 +100,8 @@ java {
}
}

tasks.named("classpathIndexCleanup") { dependsOn("compileIntegrationTestKotlin") }

fun download(url: String, output: File) {
if (output.exists()) {
println("Cached $output")
Expand Down Expand Up @@ -158,7 +174,7 @@ fun unzip(input: File, output: File, excludeMatcher: PathMatcher? = null) {
}
}

val githubArchiveCache =
val githubArchiveCache: File =
Paths.get(System.getProperty("user.home"), ".sourcegraph", "caches", "jetbrains").toFile()

tasks {
Expand Down Expand Up @@ -344,6 +360,7 @@ tasks {
systemProperty(
"cody.autocomplete.enableFormatting",
project.property("cody.autocomplete.enableFormatting") ?: "true")
environment("CODY_JETBRAINS_FEATURES", "cody.feature.inline-edits=true")

val platformRuntimeVersion = project.findProperty("platformRuntimeVersion")
if (platformRuntimeVersion != null) {
Expand Down Expand Up @@ -401,4 +418,68 @@ tasks {
}

test { dependsOn(project.tasks.getByPath("buildCody")) }

configurations {
create("integrationTestImplementation") { extendsFrom(configurations.testImplementation.get()) }
create("integrationTestRuntimeClasspath") { extendsFrom(configurations.testRuntimeOnly.get()) }
}

sourceSets {
create("integrationTest") {
kotlin.srcDir("src/integrationTest/kotlin")
compileClasspath += main.get().output
runtimeClasspath += main.get().output
}
}

// Common configuration for integration tests.
val sharedIntegrationTestConfig: Test.() -> Unit = {
group = "verification"
testClassesDirs = sourceSets["integrationTest"].output.classesDirs
classpath = sourceSets["integrationTest"].runtimeClasspath

include { it.file.hasParentNamed("integrationTest") }

useJUnit()

systemProperty("cody.integration.testing", "true")
systemProperty(
"idea.test.execution.policy", // For now, should be used by all tests
dominiccooney marked this conversation as resolved.
Show resolved Hide resolved
"com.sourcegraph.cody.test.NonEdtIdeaTestExecutionPolicy")

environment("CODY_JETBRAINS_FEATURES", "cody.feature.inline-edits=true")
environment("CODY_RECORDING_MODE", "replay")
environment("CODY_RECORDING_DIRECTORY", "recordings")
environment("CODY_RECORD_IF_MISSING", "false") // Polly needs this to record at all.

dependsOn("buildCody")
}

register<Test>("integrationTest") {
description = "Runs the integration tests."
applySharedConfiguration(sharedIntegrationTestConfig)
}

// Make sure to set CODY_INTEGRATION_TEST_TOKEN when using this task.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    onlyIf {
        System.env['CODY_INTEGRATION_TEST_TOKEN'] != null
    }

or let's conditionally print an error or something.

Ditto below.

register<Test>("passthroughIntegrationTest") {
description = "Runs the integration tests, passing everything through to the LLM."
applySharedConfiguration(sharedIntegrationTestConfig)
environment("CODY_RECORDING_MODE", "passthrough")
}

// Make sure to set CODY_INTEGRATION_TEST_TOKEN when using this task.
register<Test>("recordingIntegrationTest") {
description = "Runs the integration tests and records the responses."
applySharedConfiguration(sharedIntegrationTestConfig)

environment("CODY_RECORDING_MODE", "record")
environment("CODY_RECORDING_NAME", "integration-tests")
environment("CODY_RECORD_IF_MISSING", "true") // Polly needs this to record at all.
}

named("check") { dependsOn("integrationTest") }
}

fun Test.applySharedConfiguration(sharedConfig: Test.() -> Unit) {
sharedConfig()
}
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ platformPlugins=Git4Idea,PerforceDirectPlugin,java
javaVersion=11
# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion=8.1.1
kotlinVersion=1.9.22 // Also change this in build.gradle.kts plugins section
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noob question from me about Kotlin versioning... IntelliJ Platform also has some Kotlin pieces. What's the versioning constraints between our build and the IntelliJ hosts?

According to https://plugins.jetbrains.com/docs/intellij/using-kotlin.html#kotlin-standard-library , 2024.1 bundles 1.9.22. But I noticed "thing" that is our debug target, Main/Duke Icon, is 2022.something.

Does this mean we need to kotlin.stdlib.default.dependency=true? What does that mean if we're using IntelliJ's kotlin-isms (I was just looking at using their Kotlin Coroutine integration for the background task autocompleting repo names...)

# Opt-out flag for bundling Kotlin standard library.
# See https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library for details.
# suppress inspection "UnusedProperty"
Expand Down