From c80ae0cafd6e8db9a5d136a49bbbd94c6a47d920 Mon Sep 17 00:00:00 2001 From: Miles Yucht Date: Mon, 25 Aug 2025 16:43:07 +0000 Subject: [PATCH 1/6] Fix selectSparkVersion() to use contains() instead of equals() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation of selectSparkVersion() was broken when sparkVersion is supplied. The code was requiring an exact match instead of using contains(), which never matched real Databricks Runtime version names like "12.2 LTS (includes Apache Spark 3.3.2, Scala 2.12)". This change aligns the Java SDK with the Go and Python SDK implementations, which both use contains()/in operations for sparkVersion matching. Fixes the issue described in PR #229. Added comprehensive unit tests covering: - Successful spark version matching with realistic API response data - Multiple matches with latest=true/false behavior - Integration with other selector parameters (ML, etc.) - Error cases for non-existent versions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../com/databricks/sdk/mixin/ClustersExt.java | 2 +- .../databricks/sdk/mixin/ClustersExtTest.java | 83 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/databricks-sdk-java/src/main/java/com/databricks/sdk/mixin/ClustersExt.java b/databricks-sdk-java/src/main/java/com/databricks/sdk/mixin/ClustersExt.java index 79be6c740..dc86da730 100644 --- a/databricks-sdk-java/src/main/java/com/databricks/sdk/mixin/ClustersExt.java +++ b/databricks-sdk-java/src/main/java/com/databricks/sdk/mixin/ClustersExt.java @@ -50,7 +50,7 @@ public String selectSparkVersion(SparkVersionSelector selector) throws IllegalAr matches = version.getName().contains("LTS") || version.getKey().contains("-esr-"); } if (matches && selector.sparkVersion != null) { - matches = ("Apache Spark " + selector.sparkVersion).equals(version.getName()); + matches = version.getName().contains("Apache Spark " + selector.sparkVersion); } if (matches) { versions.add(version.getKey()); diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java index 8c35de9e2..1335668d6 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java @@ -1,6 +1,7 @@ package com.databricks.sdk.mixin; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import com.databricks.sdk.core.ApiClient; import com.databricks.sdk.core.DatabricksConfig; @@ -118,4 +119,86 @@ void nullComparisonTest() { String nodeType = clustersExt.selectNodeType(new NodeTypeSelector().withLocalDisk()); assertEquals("testId1", nodeType); } + + private GetSparkVersionsResponse testGetSparkVersionsWithSparkVersion() { + Collection versions = new ArrayList<>(); + // Mock realistic Databricks Runtime versions based on actual API response format + versions.add(new SparkVersion() + .setName("12.2 LTS (includes Apache Spark 3.3.2, Scala 2.12)") + .setKey("12.2.x-scala2.12")); + versions.add(new SparkVersion() + .setName("13.3 LTS (includes Apache Spark 3.4.1, Scala 2.12)") + .setKey("13.3.x-scala2.12")); + versions.add(new SparkVersion() + .setName("14.3 LTS (includes Apache Spark 3.5.0, Scala 2.12)") + .setKey("14.3.x-scala2.12")); + versions.add(new SparkVersion() + .setName("14.2 ML (includes Apache Spark 3.5.0, Scala 2.12)") + .setKey("14.2.x-cpu-ml-scala2.12")); + // Add another version with same Spark version to create multiple matches + versions.add(new SparkVersion() + .setName("14.1 (includes Apache Spark 3.5.0, Scala 2.12)") + .setKey("14.1.x-scala2.12")); + return new GetSparkVersionsResponse().setVersions(versions); + } + + @Test + void sparkVersionWithSparkVersionParameter() { + ClustersExt clustersExt = new ClustersExt(clustersMock); + Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); + + // Test exact spark version match + String sparkVersion = clustersExt.selectSparkVersion( + new SparkVersionSelector().withSparkVersion("3.4.1")); + assertEquals("13.3.x-scala2.12", sparkVersion); + } + + @Test + void sparkVersionWithSparkVersionParameterMultipleMatches() { + ClustersExt clustersExt = new ClustersExt(clustersMock); + Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); + + // Test spark version with multiple matches - should return latest when latest=true is explicitly set + String sparkVersion = clustersExt.selectSparkVersion( + new SparkVersionSelector().withSparkVersion("3.5.0").withLatest()); + // Should return the highest version (14.3.x) when latest=true and multiple 3.5.0 versions match + assertEquals("14.3.x-scala2.12", sparkVersion); + } + + @Test + void sparkVersionWithSparkVersionParameterAndML() { + ClustersExt clustersExt = new ClustersExt(clustersMock); + Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); + + // Test spark version combined with ML requirement + String sparkVersion = clustersExt.selectSparkVersion( + new SparkVersionSelector().withSparkVersion("3.5.0").withML()); + assertEquals("14.2.x-cpu-ml-scala2.12", sparkVersion); + } + + @Test + void sparkVersionWithSparkVersionParameterNoMatch() { + ClustersExt clustersExt = new ClustersExt(clustersMock); + Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); + + // Test spark version that doesn't exist + assertThrows(IllegalArgumentException.class, () -> { + clustersExt.selectSparkVersion( + new SparkVersionSelector().withSparkVersion("2.4.5")); + }); + } + + @Test + void sparkVersionWithSparkVersionParameterMultipleMatchesLatestFalse() { + ClustersExt clustersExt = new ClustersExt(clustersMock); + Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); + + // Test spark version with multiple matches and latest=false (default) - should throw exception + SparkVersionSelector selector = new SparkVersionSelector().withSparkVersion("3.5.0"); + // latest defaults to false, so multiple matches should throw an exception + + assertThrows(IllegalArgumentException.class, () -> { + clustersExt.selectSparkVersion(selector); + }, "Expected exception when multiple versions match with latest=false (default)"); + } } From 049d7e089e70d7d5a53047767c3c24f050c59e8b Mon Sep 17 00:00:00 2001 From: Miles Yucht Date: Mon, 25 Aug 2025 16:50:27 +0000 Subject: [PATCH 2/6] Add changelog entry for selectSparkVersion fix --- NEXT_CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index a58fc01d6..57e3889d1 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -6,6 +6,8 @@ ### Bug Fixes +* Fixed `selectSparkVersion()` method to use contains() instead of equals() for spark version matching. + ### Documentation ### Internal Changes From efab08aa357bd285148e1e746c1adc2b2965cabb Mon Sep 17 00:00:00 2001 From: Miles Yucht Date: Mon, 25 Aug 2025 16:52:08 +0000 Subject: [PATCH 3/6] Apply code formatting to ClustersExtTest --- .../databricks/sdk/mixin/ClustersExtTest.java | 82 +++++++++++-------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java index 1335668d6..e2c1524ac 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java @@ -123,22 +123,27 @@ void nullComparisonTest() { private GetSparkVersionsResponse testGetSparkVersionsWithSparkVersion() { Collection versions = new ArrayList<>(); // Mock realistic Databricks Runtime versions based on actual API response format - versions.add(new SparkVersion() - .setName("12.2 LTS (includes Apache Spark 3.3.2, Scala 2.12)") - .setKey("12.2.x-scala2.12")); - versions.add(new SparkVersion() - .setName("13.3 LTS (includes Apache Spark 3.4.1, Scala 2.12)") - .setKey("13.3.x-scala2.12")); - versions.add(new SparkVersion() - .setName("14.3 LTS (includes Apache Spark 3.5.0, Scala 2.12)") - .setKey("14.3.x-scala2.12")); - versions.add(new SparkVersion() - .setName("14.2 ML (includes Apache Spark 3.5.0, Scala 2.12)") - .setKey("14.2.x-cpu-ml-scala2.12")); + versions.add( + new SparkVersion() + .setName("12.2 LTS (includes Apache Spark 3.3.2, Scala 2.12)") + .setKey("12.2.x-scala2.12")); + versions.add( + new SparkVersion() + .setName("13.3 LTS (includes Apache Spark 3.4.1, Scala 2.12)") + .setKey("13.3.x-scala2.12")); + versions.add( + new SparkVersion() + .setName("14.3 LTS (includes Apache Spark 3.5.0, Scala 2.12)") + .setKey("14.3.x-scala2.12")); + versions.add( + new SparkVersion() + .setName("14.2 ML (includes Apache Spark 3.5.0, Scala 2.12)") + .setKey("14.2.x-cpu-ml-scala2.12")); // Add another version with same Spark version to create multiple matches - versions.add(new SparkVersion() - .setName("14.1 (includes Apache Spark 3.5.0, Scala 2.12)") - .setKey("14.1.x-scala2.12")); + versions.add( + new SparkVersion() + .setName("14.1 (includes Apache Spark 3.5.0, Scala 2.12)") + .setKey("14.1.x-scala2.12")); return new GetSparkVersionsResponse().setVersions(versions); } @@ -146,10 +151,10 @@ private GetSparkVersionsResponse testGetSparkVersionsWithSparkVersion() { void sparkVersionWithSparkVersionParameter() { ClustersExt clustersExt = new ClustersExt(clustersMock); Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - + // Test exact spark version match - String sparkVersion = clustersExt.selectSparkVersion( - new SparkVersionSelector().withSparkVersion("3.4.1")); + String sparkVersion = + clustersExt.selectSparkVersion(new SparkVersionSelector().withSparkVersion("3.4.1")); assertEquals("13.3.x-scala2.12", sparkVersion); } @@ -157,10 +162,12 @@ void sparkVersionWithSparkVersionParameter() { void sparkVersionWithSparkVersionParameterMultipleMatches() { ClustersExt clustersExt = new ClustersExt(clustersMock); Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - - // Test spark version with multiple matches - should return latest when latest=true is explicitly set - String sparkVersion = clustersExt.selectSparkVersion( - new SparkVersionSelector().withSparkVersion("3.5.0").withLatest()); + + // Test spark version with multiple matches - should return latest when latest=true is + // explicitly set + String sparkVersion = + clustersExt.selectSparkVersion( + new SparkVersionSelector().withSparkVersion("3.5.0").withLatest()); // Should return the highest version (14.3.x) when latest=true and multiple 3.5.0 versions match assertEquals("14.3.x-scala2.12", sparkVersion); } @@ -169,10 +176,11 @@ void sparkVersionWithSparkVersionParameterMultipleMatches() { void sparkVersionWithSparkVersionParameterAndML() { ClustersExt clustersExt = new ClustersExt(clustersMock); Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - + // Test spark version combined with ML requirement - String sparkVersion = clustersExt.selectSparkVersion( - new SparkVersionSelector().withSparkVersion("3.5.0").withML()); + String sparkVersion = + clustersExt.selectSparkVersion( + new SparkVersionSelector().withSparkVersion("3.5.0").withML()); assertEquals("14.2.x-cpu-ml-scala2.12", sparkVersion); } @@ -180,25 +188,29 @@ void sparkVersionWithSparkVersionParameterAndML() { void sparkVersionWithSparkVersionParameterNoMatch() { ClustersExt clustersExt = new ClustersExt(clustersMock); Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - + // Test spark version that doesn't exist - assertThrows(IllegalArgumentException.class, () -> { - clustersExt.selectSparkVersion( - new SparkVersionSelector().withSparkVersion("2.4.5")); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + clustersExt.selectSparkVersion(new SparkVersionSelector().withSparkVersion("2.4.5")); + }); } @Test void sparkVersionWithSparkVersionParameterMultipleMatchesLatestFalse() { ClustersExt clustersExt = new ClustersExt(clustersMock); Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - + // Test spark version with multiple matches and latest=false (default) - should throw exception SparkVersionSelector selector = new SparkVersionSelector().withSparkVersion("3.5.0"); // latest defaults to false, so multiple matches should throw an exception - - assertThrows(IllegalArgumentException.class, () -> { - clustersExt.selectSparkVersion(selector); - }, "Expected exception when multiple versions match with latest=false (default)"); + + assertThrows( + IllegalArgumentException.class, + () -> { + clustersExt.selectSparkVersion(selector); + }, + "Expected exception when multiple versions match with latest=false (default)"); } } From 8599dfa82024544f6143503900dfdd319c2dad52 Mon Sep 17 00:00:00 2001 From: Miles Yucht Date: Mon, 25 Aug 2025 16:56:39 +0000 Subject: [PATCH 4/6] Simplify tests to focus only on contains() vs equals() fix --- .../databricks/sdk/mixin/ClustersExtTest.java | 79 ++----------------- 1 file changed, 5 insertions(+), 74 deletions(-) diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java index e2c1524ac..c8e8e1425 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java @@ -122,28 +122,12 @@ void nullComparisonTest() { private GetSparkVersionsResponse testGetSparkVersionsWithSparkVersion() { Collection versions = new ArrayList<>(); - // Mock realistic Databricks Runtime versions based on actual API response format - versions.add( - new SparkVersion() - .setName("12.2 LTS (includes Apache Spark 3.3.2, Scala 2.12)") - .setKey("12.2.x-scala2.12")); + // Mock realistic Databricks Runtime version based on actual API response format + // The key point: version name contains more than just "Apache Spark X.Y.Z" versions.add( new SparkVersion() .setName("13.3 LTS (includes Apache Spark 3.4.1, Scala 2.12)") .setKey("13.3.x-scala2.12")); - versions.add( - new SparkVersion() - .setName("14.3 LTS (includes Apache Spark 3.5.0, Scala 2.12)") - .setKey("14.3.x-scala2.12")); - versions.add( - new SparkVersion() - .setName("14.2 ML (includes Apache Spark 3.5.0, Scala 2.12)") - .setKey("14.2.x-cpu-ml-scala2.12")); - // Add another version with same Spark version to create multiple matches - versions.add( - new SparkVersion() - .setName("14.1 (includes Apache Spark 3.5.0, Scala 2.12)") - .setKey("14.1.x-scala2.12")); return new GetSparkVersionsResponse().setVersions(versions); } @@ -152,65 +136,12 @@ void sparkVersionWithSparkVersionParameter() { ClustersExt clustersExt = new ClustersExt(clustersMock); Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - // Test exact spark version match + // Test that sparkVersion parameter works with realistic API response format + // This tests the contains() fix - the version name is "13.3 LTS (includes Apache Spark 3.4.1, Scala 2.12)" + // not just "Apache Spark 3.4.1", so equals() would fail but contains() works String sparkVersion = clustersExt.selectSparkVersion(new SparkVersionSelector().withSparkVersion("3.4.1")); assertEquals("13.3.x-scala2.12", sparkVersion); } - @Test - void sparkVersionWithSparkVersionParameterMultipleMatches() { - ClustersExt clustersExt = new ClustersExt(clustersMock); - Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - - // Test spark version with multiple matches - should return latest when latest=true is - // explicitly set - String sparkVersion = - clustersExt.selectSparkVersion( - new SparkVersionSelector().withSparkVersion("3.5.0").withLatest()); - // Should return the highest version (14.3.x) when latest=true and multiple 3.5.0 versions match - assertEquals("14.3.x-scala2.12", sparkVersion); - } - - @Test - void sparkVersionWithSparkVersionParameterAndML() { - ClustersExt clustersExt = new ClustersExt(clustersMock); - Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - - // Test spark version combined with ML requirement - String sparkVersion = - clustersExt.selectSparkVersion( - new SparkVersionSelector().withSparkVersion("3.5.0").withML()); - assertEquals("14.2.x-cpu-ml-scala2.12", sparkVersion); - } - - @Test - void sparkVersionWithSparkVersionParameterNoMatch() { - ClustersExt clustersExt = new ClustersExt(clustersMock); - Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - - // Test spark version that doesn't exist - assertThrows( - IllegalArgumentException.class, - () -> { - clustersExt.selectSparkVersion(new SparkVersionSelector().withSparkVersion("2.4.5")); - }); - } - - @Test - void sparkVersionWithSparkVersionParameterMultipleMatchesLatestFalse() { - ClustersExt clustersExt = new ClustersExt(clustersMock); - Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); - - // Test spark version with multiple matches and latest=false (default) - should throw exception - SparkVersionSelector selector = new SparkVersionSelector().withSparkVersion("3.5.0"); - // latest defaults to false, so multiple matches should throw an exception - - assertThrows( - IllegalArgumentException.class, - () -> { - clustersExt.selectSparkVersion(selector); - }, - "Expected exception when multiple versions match with latest=false (default)"); - } } From cdf733b8ef0ae5b5db4e07eafac6fd851e5baa6a Mon Sep 17 00:00:00 2001 From: Miles Yucht Date: Tue, 26 Aug 2025 10:28:51 +0000 Subject: [PATCH 5/6] Apply code formatting --- CLAUDE.md | 136 ++++++++++++++++++ .../databricks/sdk/mixin/ClustersExtTest.java | 5 +- 2 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..ce17f8447 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,136 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Development Commands + +### Build and Test +- **Build**: `mvn clean compile` - Compiles the project +- **Test**: `mvn test` - Runs unit tests (excludes integration tests and benchmarks) +- **Integration Tests**: `mvn verify -Prun-integration-tests` - Runs integration tests +- **Format Code**: `mvn spotless:apply` or `make fmt` - Applies Google Java Format and organizes imports +- **Package**: `mvn package` - Creates JAR files +- **Coverage**: `mvn clean test jacoco:report` - Generates test coverage reports + +### Working with Single Tests +- **Run specific test**: `mvn test -Dtest=ClassNameTest` +- **Run specific test method**: `mvn test -Dtest=ClassNameTest#methodName` +- **Run integration test**: `mvn verify -Dit.test=ClassNameIT` + +### Build Profiles +- **Release Profile**: `mvn clean deploy -Prelease` - For releases with signing and javadocs +- **Integration Test Profile**: `-Prun-integration-tests` - Enables integration tests + +## Project Architecture + +### Core Structure +The SDK is organized into several key packages: + +**Main Clients**: +- `WorkspaceClient` - Entry point for workspace-level operations +- `AccountClient` - Entry point for account-level operations + +**Core Infrastructure** (`com.databricks.sdk.core`): +- `ApiClient` - HTTP client abstraction with retries and error handling +- `DatabricksConfig` - Configuration management with environment variable support +- `CredentialsProvider` - Authentication provider chain +- `HeaderFactory` - Request header management + +**Authentication** (`com.databricks.sdk.core.oauth`): +- Supports multiple auth flows: PAT tokens, OAuth, Azure Service Principal, Google credentials +- `TokenSource` implementations for different credential types +- `CachedTokenSource` for token caching and refresh + +**Service APIs** (`com.databricks.sdk.service.*`): +- Auto-generated service clients for all Databricks APIs +- Organized by service area (compute, catalog, jobs, etc.) +- Each service has API interface, implementation, and request/response POJOs + +**Mixins** (`com.databricks.sdk.mixin`): +- Extensions to generated APIs with convenience methods +- `ClustersExt`, `DbfsExt`, `JobsExt`, `SecretsExt` + +### Key Patterns + +**Configuration**: Uses annotation-driven config with `@ConfigAttribute` for environment variable binding + +**Error Handling**: Consistent exception hierarchy with retry strategies and error mapping + +**Pagination**: `Paginator` abstraction hides different pagination styles across APIs + +**Long-running Operations**: `Wait` interface for polling operations until completion + +**Serialization**: Jackson-based with custom serializers for special types + +## Testing Strategy + +### Test Organization +- **Unit Tests**: `src/test/java` - Fast tests with mocking +- **Integration Tests**: `src/test/java/.../integration` - Real API calls (suffix: `IT.java`) +- **Framework**: JUnit 5 with custom extensions for environment-based test execution + +### Integration Test Environment +- Uses `@EnvTest` extension for conditional test execution +- Environment contexts: `workspace`, `account`, `ucws` (Unity Catalog workspace), `ucacct` +- Supports both real credentials and mock environments via `debug-env.json` + +### Test Utilities +- `EnvTest` - JUnit extension for environment-based test execution +- `FixtureServer` - HTTP mock server for unit tests +- `DummyCredentialsProvider` - Test credentials provider + +## Code Generation +Many files are auto-generated from OpenAPI specs (marked with `DO NOT EDIT` header). If a change needs to be made here, +don't make the change and instead report an error indicating what needs to be changed. + +## Development Practices + +### Java Compatibility +- Target: Java 8+ +- CI tests on Java 8, 11, 17, and 20 + +### Code Style +- Uses Google Java Format via Spotless plugin +- Run `mvn spotless:apply` before committing +- Import organization and unused import removal enabled + +### Dependencies +- **HTTP Client**: Apache HttpComponents +- **JSON**: Jackson +- **Testing**: JUnit 5, Mockito +- **Utilities**: Apache Commons, Google Auto Value for value classes + +## Pull Request Guidelines + +### Creating Pull Requests +- **Always follow the GitHub PR template** located at `.github/PULL_REQUEST_TEMPLATE.md` +- Answer the **WHAT** and **WHY** questions thoroughly in the PR description +- Include comprehensive testing information - never skip the "How is this tested?" section +- Use descriptive titles that clearly indicate the change being made +- Reference related issues using "Fixes #issue-number" format + +### PR Description Best Practices +- Explain the context and motivation behind changes (the WHY is most important) +- Describe what changes are being made at a high level +- Provide evidence or examples when fixing bugs +- Don't exaggerate severity - describe issues accurately +- Include cross-references to related SDKs or implementations when relevant + +## Common Development Tasks + +### Adding New Authentication Provider +1. Implement `CredentialsProvider` interface +2. Add to `DefaultCredentialsProvider` chain +3. Add configuration attributes to `DatabricksConfig` +4. Add unit and integration tests + +### Working with Generated Services +- Service interfaces are in `com.databricks.sdk.service.*` +- Don't modify generated files directly +- Add extensions in `mixin` package if needed + +### Adding Integration Tests +1. Use `@EnvTest` extension +2. Choose appropriate context (`@EnvContext("workspace")`, etc.) +3. Use environment variable injection via `@EnvOrSkip` +4. Follow existing patterns in `integration/` package \ No newline at end of file diff --git a/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java b/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java index c8e8e1425..841d58956 100644 --- a/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java +++ b/databricks-sdk-java/src/test/java/com/databricks/sdk/mixin/ClustersExtTest.java @@ -1,7 +1,6 @@ package com.databricks.sdk.mixin; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; import com.databricks.sdk.core.ApiClient; import com.databricks.sdk.core.DatabricksConfig; @@ -137,11 +136,11 @@ void sparkVersionWithSparkVersionParameter() { Mockito.doReturn(testGetSparkVersionsWithSparkVersion()).when(clustersMock).sparkVersions(); // Test that sparkVersion parameter works with realistic API response format - // This tests the contains() fix - the version name is "13.3 LTS (includes Apache Spark 3.4.1, Scala 2.12)" + // This tests the contains() fix - the version name is "13.3 LTS (includes Apache Spark 3.4.1, + // Scala 2.12)" // not just "Apache Spark 3.4.1", so equals() would fail but contains() works String sparkVersion = clustersExt.selectSparkVersion(new SparkVersionSelector().withSparkVersion("3.4.1")); assertEquals("13.3.x-scala2.12", sparkVersion); } - } From 6d253e11b4249d6b8807180b2dc4fbf8050540ca Mon Sep 17 00:00:00 2001 From: Miles Yucht Date: Tue, 26 Aug 2025 14:24:55 +0000 Subject: [PATCH 6/6] Remove CLAUDE.md from git tracking --- CLAUDE.md | 136 ------------------------------------------------------ 1 file changed, 136 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index ce17f8447..000000000 --- a/CLAUDE.md +++ /dev/null @@ -1,136 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Development Commands - -### Build and Test -- **Build**: `mvn clean compile` - Compiles the project -- **Test**: `mvn test` - Runs unit tests (excludes integration tests and benchmarks) -- **Integration Tests**: `mvn verify -Prun-integration-tests` - Runs integration tests -- **Format Code**: `mvn spotless:apply` or `make fmt` - Applies Google Java Format and organizes imports -- **Package**: `mvn package` - Creates JAR files -- **Coverage**: `mvn clean test jacoco:report` - Generates test coverage reports - -### Working with Single Tests -- **Run specific test**: `mvn test -Dtest=ClassNameTest` -- **Run specific test method**: `mvn test -Dtest=ClassNameTest#methodName` -- **Run integration test**: `mvn verify -Dit.test=ClassNameIT` - -### Build Profiles -- **Release Profile**: `mvn clean deploy -Prelease` - For releases with signing and javadocs -- **Integration Test Profile**: `-Prun-integration-tests` - Enables integration tests - -## Project Architecture - -### Core Structure -The SDK is organized into several key packages: - -**Main Clients**: -- `WorkspaceClient` - Entry point for workspace-level operations -- `AccountClient` - Entry point for account-level operations - -**Core Infrastructure** (`com.databricks.sdk.core`): -- `ApiClient` - HTTP client abstraction with retries and error handling -- `DatabricksConfig` - Configuration management with environment variable support -- `CredentialsProvider` - Authentication provider chain -- `HeaderFactory` - Request header management - -**Authentication** (`com.databricks.sdk.core.oauth`): -- Supports multiple auth flows: PAT tokens, OAuth, Azure Service Principal, Google credentials -- `TokenSource` implementations for different credential types -- `CachedTokenSource` for token caching and refresh - -**Service APIs** (`com.databricks.sdk.service.*`): -- Auto-generated service clients for all Databricks APIs -- Organized by service area (compute, catalog, jobs, etc.) -- Each service has API interface, implementation, and request/response POJOs - -**Mixins** (`com.databricks.sdk.mixin`): -- Extensions to generated APIs with convenience methods -- `ClustersExt`, `DbfsExt`, `JobsExt`, `SecretsExt` - -### Key Patterns - -**Configuration**: Uses annotation-driven config with `@ConfigAttribute` for environment variable binding - -**Error Handling**: Consistent exception hierarchy with retry strategies and error mapping - -**Pagination**: `Paginator` abstraction hides different pagination styles across APIs - -**Long-running Operations**: `Wait` interface for polling operations until completion - -**Serialization**: Jackson-based with custom serializers for special types - -## Testing Strategy - -### Test Organization -- **Unit Tests**: `src/test/java` - Fast tests with mocking -- **Integration Tests**: `src/test/java/.../integration` - Real API calls (suffix: `IT.java`) -- **Framework**: JUnit 5 with custom extensions for environment-based test execution - -### Integration Test Environment -- Uses `@EnvTest` extension for conditional test execution -- Environment contexts: `workspace`, `account`, `ucws` (Unity Catalog workspace), `ucacct` -- Supports both real credentials and mock environments via `debug-env.json` - -### Test Utilities -- `EnvTest` - JUnit extension for environment-based test execution -- `FixtureServer` - HTTP mock server for unit tests -- `DummyCredentialsProvider` - Test credentials provider - -## Code Generation -Many files are auto-generated from OpenAPI specs (marked with `DO NOT EDIT` header). If a change needs to be made here, -don't make the change and instead report an error indicating what needs to be changed. - -## Development Practices - -### Java Compatibility -- Target: Java 8+ -- CI tests on Java 8, 11, 17, and 20 - -### Code Style -- Uses Google Java Format via Spotless plugin -- Run `mvn spotless:apply` before committing -- Import organization and unused import removal enabled - -### Dependencies -- **HTTP Client**: Apache HttpComponents -- **JSON**: Jackson -- **Testing**: JUnit 5, Mockito -- **Utilities**: Apache Commons, Google Auto Value for value classes - -## Pull Request Guidelines - -### Creating Pull Requests -- **Always follow the GitHub PR template** located at `.github/PULL_REQUEST_TEMPLATE.md` -- Answer the **WHAT** and **WHY** questions thoroughly in the PR description -- Include comprehensive testing information - never skip the "How is this tested?" section -- Use descriptive titles that clearly indicate the change being made -- Reference related issues using "Fixes #issue-number" format - -### PR Description Best Practices -- Explain the context and motivation behind changes (the WHY is most important) -- Describe what changes are being made at a high level -- Provide evidence or examples when fixing bugs -- Don't exaggerate severity - describe issues accurately -- Include cross-references to related SDKs or implementations when relevant - -## Common Development Tasks - -### Adding New Authentication Provider -1. Implement `CredentialsProvider` interface -2. Add to `DefaultCredentialsProvider` chain -3. Add configuration attributes to `DatabricksConfig` -4. Add unit and integration tests - -### Working with Generated Services -- Service interfaces are in `com.databricks.sdk.service.*` -- Don't modify generated files directly -- Add extensions in `mixin` package if needed - -### Adding Integration Tests -1. Use `@EnvTest` extension -2. Choose appropriate context (`@EnvContext("workspace")`, etc.) -3. Use environment variable injection via `@EnvOrSkip` -4. Follow existing patterns in `integration/` package \ No newline at end of file