test: add hermetic unit suite + CI pipeline - #19
Conversation
Add a network-free JUnit test suite covering the provider factory dispatch, the AWS STS SigV4 signing / cloud-id envelope end-to-end (fake creds injected via system properties), Azure/GCP offline construction, plus a credentials-gated live-cloud e2e class that is skipped without secrets. Add a "Tests" GitHub Actions workflow that runs `mvn -B test` on push to all branches and on pull_request. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdded Maven and GitHub Actions test execution. Added offline tests for cloud-ID providers and factory behavior. Added credential-gated live tests for AWS, Azure, and GCP providers. ChangesCloud ID Testing
Estimated code review effort: 3 (Moderate) | ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/test.yml:
- Around line 15-16: Update the workflow’s actions/checkout@v4 step to set
persist-credentials to false, and add top-level permissions granting contents
read access. Keep the existing checkout behavior unchanged otherwise.
In `@src/test/java/io/akeyless/cloudid/LiveCloudIdE2ETest.java`:
- Around line 40-42: Update the live-test assumptions in
LiveCloudIdE2ETest.java: at lines 40-42 require both AWS_ACCESS_KEY_ID and
AWS_SECRET_ACCESS_KEY; at lines 47-49 require a complete Azure credential
configuration rather than only AZURE_CLIENT_ID; and at lines 54-56 verify the
GCP credential path exists and is readable or require an explicit live-test
opt-in before executing the provider checks.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8b0685be-1cf5-4610-85fd-d180e8956c4b
📒 Files selected for processing (7)
.github/workflows/test.ymlpom.xmlsrc/test/java/io/akeyless/cloudid/AwsCloudIdProviderTest.javasrc/test/java/io/akeyless/cloudid/AzureCloudIdProviderTest.javasrc/test/java/io/akeyless/cloudid/CloudProviderFactoryTest.javasrc/test/java/io/akeyless/cloudid/GcpCloudIdProviderTest.javasrc/test/java/io/akeyless/cloudid/LiveCloudIdE2ETest.java
| - name: Checkout repository | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- workflow files ---'
git ls-files '.github/workflows/*'
printf '%s\n' '--- test.yml with line numbers ---'
cat -n .github/workflows/test.yml
printf '%s\n' '--- workflow permission and checkout settings ---'
rg -n -C 3 '(^|[[:space:]])permissions:|contents:|actions/checkout|persist-credentials|mvn|maven' .github/workflowsRepository: akeylesslabs/akeyless-java-cloud-id
Length of output: 2706
🌐 Web query:
actions/checkout v4 persist-credentials default true README GitHub token permissions contents read workflow
💡 Result:
In the actions/checkout action (including v4), the persist-credentials input defaults to true [1][2][3]. When persist-credentials is set to true, the action configures the provided token or SSH key in the local git configuration [1][4][5]. This allows subsequent git commands run in your workflow steps to use these credentials for authenticated operations [1][6]. The action automatically removes these credentials during the post-job cleanup [1][4][5]. Regarding permissions: 1. Basic checkout: For the actions/checkout action to successfully clone the repository, the GITHUB_TOKEN requires read access to the repository's contents [7]. In workflows where you explicitly define permissions, you must set permissions: contents: read [7]. If you do not specify this, the default permissions for the GITHUB_TOKEN may be set to none (depending on your organization/repository settings), which will cause the checkout to fail [7]. 2. Pushing changes: If you intend to use the persisted credentials to perform git push operations, the GITHUB_TOKEN must have write access to the repository's contents [6]. In this case, you must set permissions: contents: write in your workflow configuration [6]. If persist-credentials is set to false, the action will not configure the token or SSH key in the git config, and subsequent git commands will not be authenticated using those credentials [6].
Citations:
- 1: https://github.com/actions/checkout/blob/v4/README.md
- 2: https://github.com/actions/checkout/blob/v4/action.yml
- 3: https://github.com/actions/checkout/blob/v4.1.1/action.yml
- 4: https://github.com/actions/checkout
- 5: https://github.com/marketplace/actions/checkout
- 6: https://latchkey.dev/learn/git/gcs-checkout-403-persist-credentials-in-ci
- 7: https://mickeygousset.com/posts/github-actions-checkout-fails-with-two-possible-error-messages/
Disable checkout credential persistence
Because Maven runs repository-controlled code, set persist-credentials: false on actions/checkout@v4. Add top-level permissions: contents: read.
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 15-16: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/test.yml around lines 15 - 16, Update the workflow’s
actions/checkout@v4 step to set persist-credentials to false, and add top-level
permissions granting contents read access. Keep the existing checkout behavior
unchanged otherwise.
Source: Linters/SAST tools
| assumeNotNull(System.getenv("AWS_ACCESS_KEY_ID")); | ||
| String cloudId = CloudProviderFactory.getCloudIdProvider("aws_iam").getCloudId(); | ||
| assertNonEmptyBase64(cloudId); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Gate live tests on usable credential configurations.
A single marker variable does not prove that a provider can authenticate. A partially configured runner will execute these tests and fail instead of skip. Gate on a complete, selected authentication configuration, or require an explicit live-test opt-in in a dedicated secret-bearing workflow.
src/test/java/io/akeyless/cloudid/LiveCloudIdE2ETest.java#L40-L42: requireAWS_SECRET_ACCESS_KEYwithAWS_ACCESS_KEY_IDbefore running the AWS test.src/test/java/io/akeyless/cloudid/LiveCloudIdE2ETest.java#L47-L49: require a complete Azure credential path, not onlyAZURE_CLIENT_ID.src/test/java/io/akeyless/cloudid/LiveCloudIdE2ETest.java#L54-L56: verify that the GCP credential path is present and readable, or use an explicit live-test opt-in.
📍 Affects 1 file
src/test/java/io/akeyless/cloudid/LiveCloudIdE2ETest.java#L40-L42(this comment)src/test/java/io/akeyless/cloudid/LiveCloudIdE2ETest.java#L47-L49src/test/java/io/akeyless/cloudid/LiveCloudIdE2ETest.java#L54-L56
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/test/java/io/akeyless/cloudid/LiveCloudIdE2ETest.java` around lines 40 -
42, Update the live-test assumptions in LiveCloudIdE2ETest.java: at lines 40-42
require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY; at lines 47-49 require
a complete Azure credential configuration rather than only AZURE_CLIENT_ID; and
at lines 54-56 verify the GCP credential path exists and is readable or require
an explicit live-test opt-in before executing the provider checks.
Summary
This repo previously had no tests and only a release workflow. This PR adds a thorough, hermetic (network-free, no real credentials) JUnit test suite plus a GitHub Actions test pipeline. No production source was changed.
Tests added (
src/test/java/io/akeyless/cloudid)CloudProviderFactoryTest(8 cases) — factory dispatchaws_iam->AwsCloudIdProvider,azure_ad->AzureCloudIdProvider,gcp->GcpCloudIdProvider(each also assertedinstanceof CloudIdProvider)null/ wrong-case types withRuntimeException("Unsupported type: ...")AwsCloudIdProviderTest(12 cases) — AWS path end-to-end, fully offlineaws.accessKeyId/aws.secretAccessKey/aws.sessionTokenJVM system properties, which the AWS SDKSystemPropertyCredentialsProvider(first link ofDefaultCredentialsProvider) reads with no network. SigV4 signing is a local computation, so STS is never contacted. Original property values are saved/restored around each test.sts_request_method/sts_request_url/sts_request_body/sts_request_headers, then the inner base64 fields.POST; urlhttps://sts.amazonaws.com/; bodyAction=GetCallerIdentity&Version=2011-06-15;AuthorizationisAWS4-HMAC-SHA256withSignature=andSignedHeaders=; credential scope/us-east-1/sts/aws4_requestreferencing the fake access key;Host: sts.amazonaws.com;X-Amz-DatematchesyyyyMMddTHHmmssZ;Content-Typeform-urlencoded.X-Amz-Security-Tokenpresent (and folded into the signature) when a session token is set, absent for basic creds.AzureCloudIdProviderTest(3 cases) — offline only: provider constructible +instanceof, factory wiring, andDefaultAzureCredentialBuilder().build()constructs with no network (mirrors whatgetCloudId()builds). No live token fetch is asserted.GcpCloudIdProviderTest(2 cases) — offline only: provider constructible +instanceof, factory wiring. (Live ADC exchange can't be exercised hermetically.)LiveCloudIdE2ETest(3 cases, credentials-gated) — real-cloud e2e that is skipped unless creds are present, so it never fails CI without secrets but runs when they exist:AWS_ACCESS_KEY_ID, Azure onAZURE_CLIENT_ID, GCP onGOOGLE_APPLICATION_CREDENTIALS(via JUnitAssume.assumeNotNull). Each asserts a non-empty, valid-base64 cloud id.CI added
.github/workflows/test.yml— workflow "Tests", onpushto all branches (**) and onpull_request, modeled on the go-cloud-idtest.yml. Sets up JDK 11 (Temurin, Maven cache) and runsmvn -B -Drevision=1.0.0-SNAPSHOT test. The-Drevisionmatches the pom's${revision}CI-friendly version scheme (as used by the lightweight sibling).pom changes
Added
junit:junit:4.13.2(test scope) and pinnedmaven-surefire-pluginto3.2.5. No change to compiler target (8) or runtime deps.Local verification
Result: BUILD SUCCESS —
Tests run: 28, Failures: 0, Errors: 0, Skipped: 3(the 3 skipped are the credentials-gated live e2e tests, correctly skipped locally with no secrets). All dependencies resolve from Maven Central, so the fullmvn testruns locally with no internal-artifact/JFrog access required; no direct-compile fallback was needed.Note: assigning/requesting review from @alikdolg.
🤖 Generated with Claude Code
Summary by CodeRabbit
Tests
Chores