Skip to content

Latest commit

 

History

History
113 lines (96 loc) · 9.06 KB

File metadata and controls

113 lines (96 loc) · 9.06 KB

Elasticsearch

Toolchain Snapshot

  • Java: JDK 25 via JAVA_HOME; use the bundled Gradle wrapper (./gradlew).
  • Build tooling: Gradle composite build with build-conventions, build-tools, and build-tools-internal; Docker is required for some packaging/tests.
  • OS packages: Packaging and QA jobs expect ephemeral hosts; do not run packaging suites on your workstation.
  • Security: Default dev clusters enable security; use elastic-admin:elastic-password or disable with -Dtests.es.xpack.security.enabled=false.
  • Cursor/Copilot rules: None provided in repo; follow this guide plus CONTRIBUTING.md.

Build & Run Commands

  • Refer to BUILDING.md, CONTRIBUTING.md & TESTING.asciidoc for comprehensive build/test instructions.

Verification & Lint Tasks

  • ./gradlew spotlessJavaCheck / spotlessApply (or :server:spotlessJavaCheck): enforce formatter profile in build-conventions/formatterConfig.xml.

Project Structure

The repository is organized into several key directories:

  • server: The core Elasticsearch server.
  • modules: Features shipped with Elasticsearch by default.
  • plugins: Officially supported plugins.
  • libs: Internal libraries used by other parts of the project.
  • qa: Integration and multi-version tests.
  • docs: Project documentation.
  • distribution: Logic for building distribution packages.
  • x-pack: Additional code modules and plugins under Elastic License.
  • build-conventions, build-tools, build-tools-internal: Gradle build logic. Refer to BUILDING.md for details on how these are structured and used.

Testing Cheatsheet

  • Standard suite: ./gradlew test (respects cached results; add -Dtests.timestamp=$(date +%s) to bypass caches when reusing seeds).
  • Single project: ./gradlew :server:test (or other subproject path).
  • Single class: ./gradlew :server:test --tests org.elasticsearch.package.ClassName.
  • Single package: ./gradlew :server:test --tests 'org.elasticsearch.package.*'.
  • Single method / repeated runs: ./gradlew :server:test --tests org.elasticsearch.package.ClassName.methodName -Dtests.iters=N.
  • Deterministic seed: append -Dtests.seed=DEADBEEF (each method uses derived seeds).
  • JVM tuning knobs: -Dtests.jvms=8, -Dtests.heap.size=4G, -Dtests.jvm.argline="-verbose:gc", -Dtests.output=always, etc.
  • Debugging: append --debug-jvm to the Gradle test task and attach a debugger on port 5005.
  • CI reproductions: copy the REPRODUCE WITH line from CI logs; it includes project path, seed, and JVM flags.
  • Yaml REST tests: ./gradlew ":rest-api-spec:yamlRestTest" --tests "org.elasticsearch.test.rest.ClientYamlTestSuiteIT.test {yaml=<relative_test_file_path>}"
  • Use the Elasticsearch testing framework where possible for unit and yaml tests and be consistent in style with other elasticsearch tests.
  • Use real classes over mocks or stubs for unit tests, unless the real class is complex then either a simplified subclass should be created within the test or, as a last resort, a mock or stub can be used. Unit tests must be as close to real-world scenarios as possible.
  • Ensure mocks or stubs are well-documented and clearly indicate why they were necessary.

Test Types

  • Unit Tests: Preferred. Extend ESTestCase.
  • Single Node: Extend ESSingleNodeTestCase (lighter than full integ test).
  • Integration: Extend ESIntegTestCase.
  • REST API: Extend ESRestTestCase or ESClientYamlSuiteTestCase. YAML based REST tests are preferred for integration/API testing.

Dependency Hygiene

  • Never add a dependency without checking for existing alternatives in the repo.

Formatting & Imports

  • Absolutely no wildcard imports; keep existing import order and avoid reordering untouched lines.

Types, Generics, and Suppressions

  • Prefer type-safe constructs; avoid raw types and unchecked casts.
  • If suppressing warnings, scope @SuppressWarnings narrowly (ideally a single statement or method).
  • Document non-obvious casts or type assumptions via Javadoc/comments for reviewers.

Naming Conventions

  • REST handlers typically use the Rest*Action pattern; transport-layer handlers mirror them with Transport*Action classes.
  • REST classes expose routes via RestHandler#routes; when adding endpoints ensure naming matches existing REST/Transport patterns to aid discoverability.
  • Transport ActionType strings encode scope (indices:data/read/..., cluster:admin/..., etc.); align new names with these conventions to integrate with privilege resolution.

Logging & Error Handling

  • Elasticsearch should prefer its own logger org.elasticsearch.logging.LogManager & org.elasticsearch.logging.Logger; declare private static final Logger logger = LogManager.getLogger(Class.class).
  • Always use parameterized logging (logger.debug("operation [{}]", value)); never build strings via concatenation.
  • Wrap expensive log-message construction in () -> Strings.format(...) suppliers when logging at TRACE/DEBUG to avoid unnecessary work.
  • Log levels:
    • TRACE: highly verbose developer diagnostics; usually read alongside code.
    • DEBUG: detailed production troubleshooting; ensure volume is bounded.
    • INFO: default-enabled operational milestones; prefer factual language.
    • WARN: actionable problems users must investigate; include context and, if needed, exception stack traces.
    • ERROR: reserve for unrecoverable states (e.g., storage health failures); prefer WARN otherwise.
  • Only log client-caused exceptions when the cluster admin can act on them; otherwise rely on API responses.
  • Tests can assert logging via MockLog for complex flows.

Javadoc & Comments

  • New packages/classes/public or abstract methods require Javadoc explaining the "why" rather than the implementation details.
  • Avoid documenting trivial getters/setters; focus on behavior, preconditions, or surprises.
  • For tests, Javadoc can describe scenario setup/expectations to aid future contributors.
  • Do not remove existing comments from code unless the code is also being removed or the comment has become incorrect.

License Headers

  • Default header (outside x-pack): Elastic License 2.0, SSPL v1, or AGPL v3—they are already codified at the top of Java files; copy from existing sources.
  • Files under x-pack require the Elastic License 2.0-only header; IDEs configured per CONTRIBUTING.md can insert correct text automatically.

Best Practices for Automation Agents

  • Never edit unrelated files; keep diffs tightly scoped to the task at hand.
  • Prefer Gradle tasks over ad-hoc scripts.
  • When scripting CLI sequences, leverage gradlew task.
  • Unrecognized changes: assume other agent; keep going; focus your changes. If it causes issues, stop + ask user.
  • Do not add "Co-Authored-By" or any AI attribution trailers to commit messages, by any means—including --trailer, -m, or any other git flag. commit messages should adhere to the 50/72 rule: use a maximum of 50 columns for the commit summary

Backwards compatibility

  • For changes to a Writeable implementation (writeTo and constructor from StreamInput), add a new public static final <UNIQUE_DESCRIPTIVE_NAME> = TransportVersion.fromName("<unique_descriptive_name>") and use it in the new code paths. Confirm the backport branches and then generate a new version file with ./gradlew generateTransportVersion.

CI failure triage with Buildkite and Gradle Enterprise build scans

  • Prefer Gradle Enterprise build scans (https://gradle-enterprise.elastic.co/s/<id>) over raw logs for root-cause analysis when available.
  • If given a Buildkite link, use the Buildkite MCP server first.
  • First call buildkite-list_annotations and inspect context=gradle-build-scans-failed (failed jobs only). If needed, inspect context=gradle-build-scans (all jobs).
  • If annotations are incomplete, call buildkite-get_build and map failed job IDs to meta_data keys: build-scan-<job_id> and build-scan-id-<job_id>.
  • Buildkite UI fallback (when MCP is unavailable): Build page -> Jobs -> Failures, then open/copy the Gradle Enterprise build scan links shown per failed job.
  • If given a Gradle Enterprise build scan link directly, start from that link instead of searching Buildkite logs first.
  • If dvcli is available, use it to extract failed tasks, exact failed tests, primary assertion/error, and reproduction details.
  • If dvcli is unavailable, do not block: continue with Buildkite MCP logs (buildkite-search_logs, buildkite-tail_logs, buildkite-read_logs), artifacts, and annotations.
  • If either tool is missing, suggest installation to the user for faster future triage:
    • dvcli / develocity-cli-client: https://github.com/breskeby/develocity-cli-client
    • Buildkite MCP setup for AI tools: https://buildkite.com/docs/apis/mcp-server/remote/configuring-ai-tools
  • For Buildkite URLs that include #<job_id>, prioritize that specific job and resolve its corresponding build-scan-<job_id> entry.
  • In reports, list exact failed tests first, then failed tasks and related build scan URLs.

Stay aligned with CONTRIBUTING.md, BUILDING.md, and TESTING.asciidoc; this AGENTS guide summarizes—but does not replace—those authoritative docs.