From 6c7050ccff6b69d2ec578c457728b4514b873b04 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Thu, 15 Jan 2026 10:51:59 +0100 Subject: [PATCH] feat(doc): Update onboarding documentation and scripts --- BUILDING.md | 133 ++++++++++++++------------------------------ docs/how_to_test.md | 34 ++++------- setup.ps1 | 100 ++++++++++++++++++++++++--------- setup.sh | 66 ++++++++++++++++------ 4 files changed, 176 insertions(+), 157 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 526a24e608b..9927e37d33a 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -5,7 +5,7 @@ This documentation provides information for developers to set up their environme * [Development environment](#development-environment) * [Quick check](#quick-check) * [Requirements](#requirements) - * [Install the required JDKs](#install-the-required-jdks) + * [Install JDK](#install-jdk) * [Install git](#install-git) * [Install Docker Desktop](#install-docker-desktop) * [Configure Akka Token](#configure-akka-token) @@ -31,7 +31,13 @@ Your output should look something like the following: ``` ℹ️ Checking required JVM: ✅ JAVA_HOME is set to /Library/Java/JavaVirtualMachines/zulu-21.jdk/Contents/Home. -ℹ️ Other JDK versions will be automatically downloaded by Gradle toolchain resolver. +ℹ️ Checking other JVMs available for testing: +✅ Azul Zulu JDK 1.8.0_462-b08 from /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home. +✅ Azul Zulu JDK 11.0.28+6-LTS from /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home. +✅ Azul Zulu JDK 17.0.16+8-LTS from /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home. +✅ Azul Zulu JDK 21.0.8+9-LTS from /Library/Java/JavaVirtualMachines/zulu-21.jdk/Contents/Home. +✅ Azul Zulu JDK 25+36-LTS from /Library/Java/JavaVirtualMachines/zulu-25.jdk/Contents/Home. +✅ GraalVM Community JDK 17.0.9+9-jvmci-23.0-b22 from /Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.3.1/Contents/Home. ℹ️ Checking git configuration: ✅ The git command line is installed. ✅ pre-commit hook is installed in repository. @@ -42,100 +48,56 @@ Your output should look something like the following: ✅ The Docker server is running. ``` -If there is any issue with your output, check the requirements above and use the following guide to install and configure the required tools. +If there is any issue with your output, check the requirements below and use the following guide to install and configure the required tools. ### Requirements Requirements to build the full project: -* The `git` command line must be installed. +* A recent version (21+) of JDK, +* The `git` command line must be installed, * A container runtime environment must be available to run all tests (e.g. Docker Desktop). -### Install the required JDK +### Install JDK -Gradle auto-provision needed JDKs locally. However, it still is possible to manage the JDK via other tools. +Java is required to run Gradle, the project build tool. +Gradle will find any locally installed JDK and can download any missing JDK versions needed for the project build and testing. #### macOS -The following steps demonstrate how to use `brew`, but other version managers -such as [mise](https://mise.jdx.dev/) or [sdkman](https://sdkman.io/) work as well. - -* Install the required JDKs using `brew`: - ```shell - brew install --cask zulu@8 zulu@11 zulu@17 zulu@21 zulu@25 - ``` - - and if GraalVM is needed (17, 21, 25) - ```shell - brew install graalvm/tap/graalvm-community-java17 graalvm/tap/graalvm-community-jdk21 graalvm/tap/graalvm-community-jdk25 - ``` -* Identify your local version of GraalVM: - ``` - ls /Library/Java/JavaVirtualMachines | grep graalvm - ``` - Example: `graalvm-community-openjdk-17` - - Use this version in the following command to fix the GraalVM installation by [removing the quarantine flag](https://www.graalvm.org/latest/docs/getting-started/macos/), e.g. : - - ```shell - xattr -r -d com.apple.quarantine "/Library/Java/JavaVirtualMachines/graalvm-community-openjdk-17" - ``` -* Restart your shell after applying the changes if you appended the command to your shell configuration file. - -> [!NOTE] -> ARM users: there is no Oracle JDK v8 for ARM. -> It's recommended to use [Azul's Zulu](https://www.azul.com/downloads/?version=java-8-lts&architecture=arm-64-bit&package=jdk#zulu) builds of Java 8. -> [Amazon Corretto](https://aws.amazon.com/corretto/) builds have also been proven to work. - -> [!NOTE] -> macOS users: remember that `/usr/libexec/java_home` may control which JDK is in your path. +Install a recent (21+) JDK using `brew`: +```shell +brew install --cask zulu@21 +``` #### Linux -Use your JDK manager ([mise](https://mise.jdx.dev/), [sdkman](https://sdkman.io/), etc.) or manually install the required JDKs. - -* Download and extract JDK 8, 11, 17, 21, and 25 from [Eclipse Temurin releases](https://adoptium.net/temurin/releases/) and GraalVM 17 from [Oracle downloads](https://www.graalvm.org/downloads/). -* Install the GraalVM native image requirements for native builds by following [the GraalVM official documentation](https://www.graalvm.org/latest/reference-manual/native-image/#prerequisites). -* Add the `JAVA_HOME` environment variable to your shell using the `export` command. You can permanently set it by appending the `export` command to your shell configuration file `~/.zshrc` or `~/.bashrc` or other. - ```shell - export JAVA_HOME=//jdk-21. - ``` +Use your distribution package manager to install a recent (21+) JDK: +```shell +apt install openjdk-21-jdk +``` +Alternatively, manually download and install it from [Eclipse Temurin releases](https://adoptium.net/temurin/releases/). - Gradle should automatically detect the JDK in usual places. As a fallback it can automatically provision them. -* Restart your shell after applying the changes if you appended the commands to your shell configuration file. +Add the `JAVA_HOME` environment variable to your shell using the `export` command. +You can permanently set it by appending the `export` command to your shell configuration file such as `~/.zshrc`, `~/.bashrc` or similar. +```shell +export JAVA_HOME=//jdk-21.x.x +``` +Restart your shell after applying the changes if you appended the commands to your shell configuration file. #### Windows -* Download and install JDK 8, 11, 17, 21, and 25 from [Eclipse Temurin releases](https://adoptium.net/temurin/releases/). - -
- Alternatively, install JDKs using winget or scoop. (click here to expand) - - ```pwsh - winget install --id EclipseAdoptium.Temurin.8.JDK - winget install --id EclipseAdoptium.Temurin.11.JDK - winget install --id EclipseAdoptium.Temurin.17.JDK - winget install --id EclipseAdoptium.Temurin.21.JDK - winget install --id EclipseAdoptium.Temurin.25.JDK - ``` - - ```pwsh - scoop bucket add java - scoop install temurin8-jdk - scoop install temurin11-jdk - scoop install temurin17-jdk - scoop install temurin21-jdk - scoop install temurin25-jdk - ``` - -
+Install a recent (21+) JDK using the Windows package manager `winget`: +```pwsh +winget install --id EclipseAdoptium.Temurin.21.JDK +``` +Or manually download and install it from [Eclipse Temurin releases](https://adoptium.net/temurin/releases/). -* Set the `JAVA_HOME` environment variable, replacing the path with your JDK 21 installation: - ```pwsh - [Environment]::SetEnvironmentVariable("JAVA_HOME", "C:\Program Files\Eclipse Adoptium\jdk-21.0.5.11-hotspot", [EnvironmentVariableTarget]::User) - ``` +Set the `JAVA_HOME` environment variable, replacing the path with your JDK 21 installation: +```pwsh +[Environment]::SetEnvironmentVariable("JAVA_HOME", "C:\Program Files\Eclipse Adoptium\jdk-21.x.x-hotspot", [EnvironmentVariableTarget]::User) +``` - Gradle should automatically detect the JDK in usual places. As a fallback it can automatically provision them. ### Install git @@ -147,26 +109,17 @@ If not installed, the terminal will prompt you to install it. #### Linux ```shell -apt-get install git +apt install git ``` #### Windows -Download and install the installer from [the official website](https://git-scm.com/download/win). - -
-Alternatively, install git using winget or scoop. (click here to expand) +Download and install the installer from [the official website](https://git-scm.com/download/win) or install it using the Windows package manager `winget`: ```pwsh winget install --id git.git ``` -```pwsh -scoop install git -``` - -
- ### Install Docker Desktop > [!NOTE] @@ -213,8 +166,8 @@ winget install --id Docker.DockerDesktop > You can alternatively use the `core.hooksPath` configuration to point to the `.githooks` folder using `git config --local core.hooksPath .githooks` if you don't already have a hooks path defined system-wide. > [!NOTE] -> The git hooks will check that your code is properly formatted before commiting. -> This is done both to avoid future merge conflict and ensure uniformity inside the code base. +> The git hooks will check that your code is properly formatted before committing. +> This is done both to avoid future merge conflicts and ensure uniformity inside the code base. * Configure git to automatically update submodules. ```shell @@ -246,7 +199,7 @@ To enable access to Akka artifacts hosted on Lightbend’s private repository, y ## Building the project -After everything is properly set up, you can move on to the next section to start a build or check [the contribution guidelines](CONTRIBUTING.md). +After everything is properly set up, you can build the project or check [the contribution guidelines](CONTRIBUTING.md). To build the project without running tests, run: ```shell diff --git a/docs/how_to_test.md b/docs/how_to_test.md index 2dcc6c89bc7..d38986f8645 100644 --- a/docs/how_to_test.md +++ b/docs/how_to_test.md @@ -2,7 +2,7 @@ ## The Different Types of Tests -The project leverages different types of test: +The project leverages different types of tests: 1. The most common ones are **unit tests**. They are intended to test a single isolated feature, and rely on [JUnit 5 framework](https://junit.org/junit5/docs/current/user-guide/) or [Spock 2 framework](https://spockframework.org/spock/docs/). @@ -24,24 +24,24 @@ The project leverages different types of test: They are dedicated to test the java agent (`:dd-java-agent`) behavior against demo applications to prevent any regression. All smoke tests are located into the `:dd-smoke-tests` module. 6. The last type of test is **system tests**. - They are intended to test behavior consistency between all the client libraries, and rely on [their on GitHub repository](https://github.com/DataDog/system-tests). + They are intended to test behavior consistency between all the client libraries, and rely on [their own GitHub repository](https://github.com/DataDog/system-tests). > [!TIP] > Most of the instrumented tests and integration tests are instrumentation tests. ### Forked Tests -Independently of the type of test, test can be run in another (forked) JVM than the one running Gradle. +Independent of the type of test, test can be run in another (forked) JVM than the one running Gradle. This behavior is implicit when the test class name is suffixed by `ForkedTest` (eg `SomeFeatureForkedTest`). This mechanism exists to make sure either java agent state or static data are reset between test runs. > [!NOTE] -> Forked tests are not run part of the gradle `test` task. +> Forked tests are not run as part of the gradle `test` task. > In order to run them, you need to use the `forkedTest` task instead. ### Flaky Tests -If a test runs unreliably, or doesn't have a fully deterministic behavior, this will lead into recurrent unexpected errors in continuous integration. +If a test runs unreliably, or doesn't have a fully deterministic behavior, this will lead to recurrent unexpected errors in continuous integration. In order to identify such tests and avoid the continuous integration to fail, they are marked as _flaky_ and must be annotated with the `@Flaky` annotation. > [!TIP] @@ -62,25 +62,16 @@ Instead, you can run tests for a specific module (ex. `:dd-java-agent:instrument ### Running Tests on Another JVM -To run tests on a different JVM than the one used for doing the build, you need two things: +To run tests on a different JVM than the one used for the build, you can specify it using the `-PtestJvm=` command line option to the Gradle task: -1) An environment variable pointing to the JVM to use on the form `JAVA_[JDKNAME]_HOME`, - e.g. `JAVA_ZULU15_HOME`, `JAVA_GRAALVM17_HOME` - -2) A command line option to the gradle task on the form `-PtestJvm=[JDKNAME]`, - e.g. `-PtestJvm=ZULU15`, `-PtestJvm=GRAALVM17` - -> [!NOTE] -> Please note that the JDK name needs to end with the JDK version, e.g. `11`, `ZULU15`, `ORACLE8`, `GRAALVM17`, etc. +* `-PtestJvm=X` like `-PtestJvm=8`, `-PtestJvm=25` to run with a specific JDK version, +* `-PtestJvm=/path/to/jdk` to run with a given JDK, ### Running System Tests -The system tests are setup to run on continuous integration as pull request check. - -If you would like to run them locally, you would have to grab [a local copy of the system tests](https://github.com/DataDog/system-tests), and run them from there. -You can make them use your development version of `dd-trace-java` by [dropping the built artifacts to the `/binaries` folder](https://github.com/DataDog/system-tests/blob/main/docs/execute/binaries.md#java-library) of your local copy of the system tests. - -In the CI System tests will be run with the pipeline defined [`DataDog/system-tests/blob/main/.github/workflows/system-tests.yml`](https://github.com/DataDog/system-tests/blob/main/.github/workflows/system-tests.yml) +The system tests are setup to run on continuous integration (CI) as pull request check using [a dedicated workflow]((https://github.com/DataDog/system-tests/blob/main/.github/workflows/system-tests.yml)). +To run them locally, grab a local copy of [the system tests](https://github.com/DataDog/system-tests) and run them from there. +You can make them use your development version of `dd-trace-java` by [dropping the built artifacts to the `/binaries` folder](https://github.com/DataDog/system-tests/blob/main/docs/execute/binaries.md#java-library) of your local copy of the system tests. ### The APM test agent @@ -90,8 +81,7 @@ handling all traces during test runs and performing a number of `Trace Checks`. Trace Check results are returned within the `Get APM Test Agent Trace Check Results` step for all instrumentation test jobs. Check [trace invariant checks](https://github.com/DataDog/dd-apm-test-agent#trace-invariant-checks) for more information. -The APM Test Agent also emits helpful logging, including logging received traces' headers, spans, errors encountered, -ands information on trace checks being performed. +The APM Test Agent also emits helpful logging, including logging received traces' headers, spans, errors encountered, and information on trace checks being performed. Logs can be viewed in GitLab within the Test-Agent container step for all instrumentation test suites, e.g. the `test_inst` jobs. Read more about [the APM Test Agent](https://github.com/datadog/dd-apm-test-agent#readme). diff --git a/setup.ps1 b/setup.ps1 index 3fbe956eeb3..ba1fdb0611b 100644 --- a/setup.ps1 +++ b/setup.ps1 @@ -8,44 +8,90 @@ Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' # Check for required JDKs -function TestJvm { - param ($JavaHomeName, $ExpectedJavaVersion) +function Get-JavaMajorVersion { + param ($javaCommand) - if (-not (Test-Path "env:$JavaHomeName")) { - Write-Host "❌ $JavaHomeName is not set. Please set $JavaHomeName to refer to a JDK $ExpectedJavaVersion installation." -ForegroundColor Red + try { + $ErrorActionPreference = 'Continue' + $javaVersionOutput = & $javaCommand -version 2>&1 + } + catch { + return $null + } + finally { + $ErrorActionPreference = 'Stop' + } + + # Extract version from output like 'version "21.0.1"' or 'version "1.8.0_392"' + if ($javaVersionOutput[0] -match 'version "1\.(\d+)') { + # Old versioning scheme (Java 8 and earlier): 1.X.Y_Z -> major version is X + return [int]$matches[1] + } + elseif ($javaVersionOutput[0] -match 'version "(\d+)') { + # New versioning scheme (Java 9+): X.Y.Z -> major version is X + return [int]$matches[1] + } + + return $null +} + +function Test-Jdk { + param ($javaCommand, $minJavaVersion) + + $javaVersion = Get-JavaMajorVersion $javaCommand + + if ($null -eq $javaVersion) { + Write-Host "❌ Could not determine Java version from $javaCommand." -ForegroundColor Red exit 1 } + elseif ($javaVersion -lt $minJavaVersion) { + Write-Host "🟨 $javaCommand refers to JDK $javaVersion but JDK $minJavaVersion or above is recommended." + } else { - $javaHome = Get-Item "env:$JavaHomeName" | Select-Object -ExpandProperty Value - - try { - # try to handle differences between PowerShell 7 and Windows PowerShell 5 - $ErrorActionPreference = 'Continue' - $javaVersionOutput = & "$javaHome\bin\java.exe" -version 2>&1 - } - catch { - Write-Host "❌ Error running `"$javaHome\bin\java.exe -version`". Please check that $JavaHomeName is set to a JDK $ExpectedJavaVersion installation." - exit 1 - } - finally { - $ErrorActionPreference = 'Stop' - } + Write-Host "✅ $javaCommand is set to JDK $javaVersion." + } +} - if ($javaVersionOutput[0] -notmatch "version `"$ExpectedJavaVersion") { - Write-Host "❌ $JavaHomeName is set to $javaHome, but it does not refer to a JDK $ExpectedJavaVersion installation." -ForegroundColor Red - exit 1 - } - else { - Write-Host "✅ $JavaHomeName is set to $javaHome." +function Show-AvailableJdks { + try { + $ErrorActionPreference = 'Continue' + $javaToolchainsOutput = & .\gradlew.bat -q javaToolchains 2>&1 + + $jdkName = '' + foreach ($line in $javaToolchainsOutput) { + if ($line -match '^ \+ (.+)$') { + $jdkName = $matches[1] + } + elseif ($line -match '^\s+\| Location:\s+(.+)$') { + if ($jdkName) { + Write-Host "✅ $jdkName from $($matches[1])." + $jdkName = '' + } + } } } + catch { + Write-Host "⚠️ Could not retrieve available JDKs from Gradle." + } + finally { + $ErrorActionPreference = 'Stop' + } } -Write-Host 'ℹ️ Checking required JVM:' +Write-Host 'ℹ️ Checking JDK:' if (Test-Path 'env:JAVA_HOME') { - TestJvm 'JAVA_HOME' '21' + $javaHome = Get-Item 'env:JAVA_HOME' | Select-Object -ExpandProperty Value + Test-Jdk "$javaHome\bin\java.exe" 21 +} +elseif (Get-Command java -ErrorAction SilentlyContinue) { + Test-Jdk 'java' 21 +} +else { + Write-Host "❌ No Java installation found. Please install JDK 21 or above." -ForegroundColor Red + exit 1 } -Write-Host 'ℹ️ Other JDK versions will be automatically downloaded by Gradle toolchain resolver.' +Write-Host 'ℹ️ Checking other JDKs available for testing:' +Show-AvailableJdks # Check for required commands (e.g., git, docker) function TestCommand { diff --git a/setup.sh b/setup.sh index 5a978e9f45c..6f5985e479a 100755 --- a/setup.sh +++ b/setup.sh @@ -4,35 +4,65 @@ # Check required JVM. # -function check-jvm() { - local JAVA_HOME_NAME=$1 - local EXPECTED_JAVA_VERSION=$2 - if [ -z "${!JAVA_HOME_NAME}" ]; then - echo "❌ $JAVA_HOME_NAME is not set. Please set $JAVA_HOME_NAME to refer to a JDK $EXPECTED_JAVA_VERSION installation." >&2 - exit 1 - elif ! "${!JAVA_HOME_NAME}/bin/java" -version 2>&1 | grep -q "version \"$EXPECTED_JAVA_VERSION" ; then - echo "❌ $JAVA_HOME_NAME is set to ${!JAVA_HOME_NAME}, but it does not refer to a JDK $EXPECTED_JAVA_VERSION installation." >&2 - exit 1 +function get-java-major-version() { + local JAVA_COMMAND=$1 + local VERSION_STRING + VERSION_STRING=$("$JAVA_COMMAND" -version 2>&1 | grep version | head -n 1) + + # Extract version number from output like 'version "21.0.1"' or 'version "1.8.0_392"' + if echo "$VERSION_STRING" | grep -q 'version "1\.'; then + # Old versioning scheme (Java 8 and earlier): 1.X.Y_Z -> major version is X + echo "$VERSION_STRING" | sed -n 's/.*version "1\.\([0-9]*\).*/\1/p' else - echo "✅ $JAVA_HOME_NAME is set to $(readlink -f "${!JAVA_HOME_NAME}")." + # New versioning scheme (Java 9+): X.Y.Z -> major version is X + echo "$VERSION_STRING" | sed -n 's/.*version "\([0-9]*\).*/\1/p' fi } -function check-jvm-from-path() { - local EXPECTED_JAVA_VERSION=$1 - if java -version 2>&1 | grep version | grep -q -v "version \"$EXPECTED_JAVA_VERSION"; then - echo "❌ The java command from path is not $EXPECTED_JAVA_VERSION. Please set JAVA_HOME environment varible to a JDK $EXPECTED_JAVA_VERSION." >&2 +function check-jdk() { + local JAVA_COMMAND=$1 + local MIN_JAVA_VERSION=$2 + local JAVA_VERSION + JAVA_VERSION=$(get-java-major-version "$JAVA_COMMAND") + + if [ -z "$JAVA_VERSION" ]; then + echo "❌ Could not determine Java version from $JAVA_COMMAND." >&2 exit 1 + elif [ "$JAVA_VERSION" -lt "$MIN_JAVA_VERSION" ]; then + echo "🟨 $JAVA_COMMAND refers to JDK $JAVA_VERSION but JDK $MIN_JAVA_VERSION or above is recommended." >&2 + else + echo "✅ $JAVA_COMMAND is set to JDK $JAVA_VERSION." fi } -echo "ℹ️ Checking required JVM:" +function show-available-jdks() { + ./gradlew -q javaToolchains | awk ' + /^ \+ / { + # Extract JDK name from lines starting with " + " + jdk_name = substr($0, 4) + } + /^ \| Location:/ { + # Extract location and print with JDK name + sub(/^ \| Location: +/, "") + if (jdk_name != "") { + print "✅ " jdk_name " from " $0 "." + jdk_name = "" + } + } + ' +} + +echo "ℹ️ Checking JDK:" if [ -e "$JAVA_HOME" ]; then - check-jvm "JAVA_HOME" "21" + check-jdk "$JAVA_HOME/bin/java" "21" elif command -v java &> /dev/null; then - check-jvm-from-path "21" + check-jdk "java" "21" +else + echo "❌ No Java installation found. Please install JDK 21 or above." >&2 + exit 1 fi -echo "ℹ️ Other JDK versions will be automatically downloaded by Gradle toolchain resolver." +echo "ℹ️ Checking other JDKs available for testing:" +show-available-jdks #