Skip to content

Conversation

IvanHunters
Copy link
Collaborator

@IvanHunters IvanHunters commented Jul 28, 2025

What this PR does

Introduced automated end-to-end testing for SeaweedFS bucket creation and verification in Kubernetes environments.

Release note

[seaweed] add tests for S3 buckets

Summary by CodeRabbit

  • New Features
    • Introduced an end-to-end test for SeaweedFS Bucket resources, including creation, credential verification, file upload, and cleanup.
  • Chores
    • Updated test scripts to include SeaweedFS in tenant configuration and extended wait times for application readiness.
    • Enhanced test environment by adding the MinIO client to the Docker image for improved S3 compatibility testing.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
Copy link
Contributor

coderabbitai bot commented Jul 28, 2025

Walkthrough

A new end-to-end test for SeaweedFS Bucket resources was introduced, leveraging the BATS framework and the MinIO client. The root tenant configuration test script was updated to enable the "seaweedfs" component, adjust HelmRelease waits, and extend timeouts. The e2e-sandbox Docker image now includes the MinIO client (mc).

Changes

Cohort / File(s) Change Summary
SeaweedFS Bucket E2E Test
hack/e2e-apps/bucket.bats
Added a BATS test script for creating, verifying, and cleaning up a SeaweedFS Bucket via Kubernetes and MinIO.
Tenant Install E2E Test Update
hack/e2e-install-cozystack.bats
Updated to enable the SeaweedFS component, wait for its HelmRelease, and increased wait timeouts.
E2E Sandbox Image Update
packages/core/testing/images/e2e-sandbox/Dockerfile
Added installation of the MinIO client (mc) binary to the Docker image for use in end-to-end tests.

Sequence Diagram(s)

sequenceDiagram
    participant Tester as BATS Test Script
    participant K8s as Kubernetes API
    participant Helm as HelmRelease Controller
    participant S3 as SeaweedFS S3
    participant MC as MinIO Client

    Tester->>K8s: Apply Bucket CR
    K8s->>Helm: Reconcile Bucket, create HelmRelease
    Tester->>K8s: Wait for HelmRelease, BucketClaims, BucketAccesses ready
    Tester->>K8s: Get bucket credentials Secret
    Tester->>S3: Port-forward S3 endpoint
    Tester->>MC: Configure alias with credentials
    MC->>S3: Upload credentials.json to bucket
    MC->>S3: List uploaded file
    MC->>S3: Remove uploaded file
    Tester->>K8s: Delete Bucket CR
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Suggested reviewers

  • kvaps

Poem

A bucket appears, the tests commence,
With MinIO’s help, we scale the fence.
SeaweedFS waits, credentials in hand,
Port-forwarding magic, all as planned.
Uploads and listings, clean-up in tow—
E2E rabbits, onward we go! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/seaweed-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @IvanHunters, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances our automated testing capabilities by introducing a comprehensive end-to-end test for SeaweedFS bucket functionality within our Kubernetes environments. It ensures that SeaweedFS can be properly provisioned and utilized, covering the full lifecycle of a bucket from creation to data operations and cleanup.

Highlights

  • New End-to-End Test: I've added a new end-to-end test (hack/e2e-apps/bucket.bats) specifically for SeaweedFS. This test automates the creation of a SeaweedFS bucket, verifies its readiness, retrieves credentials, performs S3 operations (upload, list, delete a file) using the MinIO client (mc), and finally cleans up the created bucket.
  • SeaweedFS Enablement in E2E Setup: The hack/e2e-install-cozystack.bats script has been updated to enable SeaweedFS for the root tenant during the e2e environment setup. This ensures that the SeaweedFS HelmRelease is properly deployed and ready before the new bucket tests are executed.
  • MinIO Client Integration: The packages/core/testing/images/e2e-sandbox/Dockerfile now includes the MinIO client (mc). This client is essential for the new SeaweedFS bucket test, as it's used to interact with the SeaweedFS S3-compatible endpoint to perform file operations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This PR introduces an e2e test for SeaweedFS bucket functionality. The changes to enable SeaweedFS in the test environment and update the test image are correct. However, the new test script hack/e2e-apps/bucket.bats has several critical and high-severity issues. The S3 client commands are incorrect and won't test the intended functionality. Additionally, the script lacks proper resource cleanup, which can lead to flaky tests and resource leaks. I've provided specific suggestions to fix these issues and improve the test's robustness.

mc alias set local https://localhost:8333 $ACCESS_KEY $SECRET_KEY --insecure

# Upload file to bucket
mc cp bucket-test-credentials.json $BUCKET_NAME/bucket-test-credentials.json

Choose a reason for hiding this comment

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

critical

The mc cp command is missing the S3 alias in the destination path. Without the local/ prefix, mc will treat the destination as a local filesystem path instead of an S3 object path. This means the test is not actually uploading the file to SeaweedFS, which is a critical flaw in the test's logic.

mc cp bucket-test-credentials.json local/$BUCKET_NAME/bucket-test-credentials.json

mc cp bucket-test-credentials.json $BUCKET_NAME/bucket-test-credentials.json

# Verify file was uploaded
mc ls $BUCKET_NAME/bucket-test-credentials.json

Choose a reason for hiding this comment

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

critical

Similar to the mc cp command, the mc ls command is missing the local/ alias prefix. As a result, this command will not check for the file in the S3 bucket, and the verification step is ineffective.

mc ls local/$BUCKET_NAME/bucket-test-credentials.json

mc ls $BUCKET_NAME/bucket-test-credentials.json

# Clean up uploaded file
mc rm $BUCKET_NAME/bucket-test-credentials.json

Choose a reason for hiding this comment

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

critical

The mc rm command is also missing the local/ alias prefix. This means the test will not remove the file from the S3 bucket, failing to clean up the test object.

mc rm local/$BUCKET_NAME/bucket-test-credentials.json

Comment on lines +3 to +47
@test "Create and Verify Seeweedfs Bucket" {
# Create the bucket resource
name='test'
kubectl apply -f - <<EOF
apiVersion: apps.cozystack.io/v1alpha1
kind: Bucket
metadata:
name: ${name}
namespace: tenant-test
spec: {}
EOF

# Wait for the bucket to be ready
kubectl -n tenant-test wait hr bucket-${name} --timeout=100s --for=condition=ready
kubectl -n tenant-test wait bucketclaims.objectstorage.k8s.io bucket-${name} --timeout=300s --for=jsonpath='{.status.bucketReady}'
kubectl -n tenant-test wait bucketaccesses.objectstorage.k8s.io bucket-${name} --timeout=300s --for=jsonpath='{.status.accessGranted}'

# Get and decode credentials
kubectl -n tenant-test get secret bucket-${name} -ojsonpath='{.data.BucketInfo}' | base64 -d > bucket-test-credentials.json

# Get credentials from the secret
ACCESS_KEY=$(jq -r '.spec.secretS3.accessKeyID' bucket-test-credentials.json)
SECRET_KEY=$(jq -r '.spec.secretS3.accessSecretKey' bucket-test-credentials.json)
BUCKET_NAME=$(jq -r '.spec.bucketName' bucket-test-credentials.json)

# Start port-forwarding
bash -c 'timeout 100s kubectl port-forward service/seaweedfs-s3 -n tenant-root 8333:8333 > /dev/null 2>&1 &'

# Wait for port-forward to be ready
timeout 30 sh -ec 'until nc -z localhost 8333; do sleep 1; done'

# Set up MinIO alias with error handling
mc alias set local https://localhost:8333 $ACCESS_KEY $SECRET_KEY --insecure

# Upload file to bucket
mc cp bucket-test-credentials.json $BUCKET_NAME/bucket-test-credentials.json

# Verify file was uploaded
mc ls $BUCKET_NAME/bucket-test-credentials.json

# Clean up uploaded file
mc rm $BUCKET_NAME/bucket-test-credentials.json

kubectl -n tenant-test delete bucket.apps.cozystack.io ${name}
}

Choose a reason for hiding this comment

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

high

This test creates several resources (a temporary file, a background process, and a Kubernetes resource) that are not guaranteed to be cleaned up if the test fails before its completion. This can lead to resource leaks and cause subsequent test runs to be flaky.

It is highly recommended to use a trap at the beginning of the test to ensure all resources are cleaned up upon exit, regardless of whether the test succeeds or fails. The cleanup logic should handle:

  • Killing the port-forward background process.
  • Removing the temporary credentials file.
  • Deleting the bucket.apps.cozystack.io resource (the kubectl delete on line 46 should be moved into the trap).

BUCKET_NAME=$(jq -r '.spec.bucketName' bucket-test-credentials.json)

# Start port-forwarding
bash -c 'timeout 100s kubectl port-forward service/seaweedfs-s3 -n tenant-root 8333:8333 > /dev/null 2>&1 &'

Choose a reason for hiding this comment

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

high

The ampersand (&) to background the port-forward command is inside the single-quoted string passed to bash -c. This causes the timeout process to be orphaned and disconnected from the test's process tree, making it difficult to manage and clean up.

The & should be placed outside the single quotes to correctly background the bash -c command. This allows the parent shell to capture its PID for proper cleanup.

bash -c 'timeout 100s kubectl port-forward service/seaweedfs-s3 -n tenant-root 8333:8333 > /dev/null 2>&1' &


@test "Create and Verify Seeweedfs Bucket" {
# Create the bucket resource
name='test'

Choose a reason for hiding this comment

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

medium

Using a static name like 'test' for the bucket can lead to conflicts if tests are run in parallel or if a previous test run failed to clean up its resources properly. To make the test more robust, it's better to use a unique name for each test run.

name="test-$(date +%s)-${RANDOM}"

timeout 30 sh -ec 'until nc -z localhost 8333; do sleep 1; done'

# Set up MinIO alias with error handling
mc alias set local https://localhost:8333 $ACCESS_KEY $SECRET_KEY --insecure

Choose a reason for hiding this comment

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

medium

The mc alias set command modifies the default configuration file in the user's home directory (~/.mc/config.json). If multiple tests run concurrently, they could overwrite each other's configuration, leading to race conditions and flaky tests.

To ensure test isolation, you should use the --config-dir flag with a temporary directory for all mc commands. This directory should be created at the start of the test and cleaned up in a trap.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (7)
hack/e2e-apps/bucket.bats (7)

5-5: Use unique bucket name to avoid test conflicts.

Using a static name like 'test' for the bucket can lead to conflicts if tests are run in parallel or if a previous test run failed to clean up its resources properly.


29-29: Fix backgrounding of port-forward command.

The ampersand (&) to background the port-forward command is inside the single-quoted string, causing the timeout process to be orphaned and disconnected from the test's process tree.


35-35: Ensure test isolation for MinIO client configuration.

The mc alias set command modifies the default configuration file which could cause race conditions if multiple tests run concurrently.


38-38: Fix missing S3 alias in mc cp command.

The mc cp command is missing the S3 alias in the destination path. Without the local/ prefix, the file will not be uploaded to SeaweedFS.


41-41: Fix missing S3 alias in mc ls command.

The mc ls command is missing the local/ alias prefix, so it will not check for the file in the S3 bucket.


44-44: Fix missing S3 alias in mc rm command.

The mc rm command is missing the local/ alias prefix, so it will not remove the file from the S3 bucket.


3-47: Add proper resource cleanup with trap.

The test creates several resources that are not guaranteed to be cleaned up if the test fails before completion, which can cause subsequent test runs to be flaky.

🧹 Nitpick comments (1)
hack/e2e-apps/bucket.bats (1)

3-3: Fix typo in test function name.

The test function name contains a typo: "Seeweedfs" should be "SeaweedFS".

-@test "Create and Verify Seeweedfs Bucket" {
+@test "Create and Verify SeaweedFS Bucket" {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e47e1e and 730584b.

📒 Files selected for processing (3)
  • hack/e2e-apps/bucket.bats (1 hunks)
  • hack/e2e-install-cozystack.bats (1 hunks)
  • packages/core/testing/images/e2e-sandbox/Dockerfile (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
packages/core/testing/images/e2e-sandbox/Dockerfile (1)

Learnt from: NickVolynkin
PR: #1117
File: packages/apps/mysql/Makefile:8-8
Timestamp: 2025-06-26T04:29:24.830Z
Learning: The cozystack project uses yq v4+ on their CI runner, so yq v4 syntax (-o json --indent 4) is compatible and version checks are not needed.

🧬 Code Graph Analysis (1)
hack/e2e-apps/bucket.bats (1)
hack/e2e-apps/run-kubernetes.sh (1)
  • run_kubernetes_test (1-104)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install Cozystack
🔇 Additional comments (4)
hack/e2e-install-cozystack.bats (2)

126-126: LGTM! SeaweedFS component enabled correctly.

The addition of "seaweedfs": true to the tenant specification is properly formatted and follows the established pattern for enabling components in the root tenant configuration.


128-129: LGTM! Proper wait configuration for SeaweedFS.

The addition of seaweedfs to the HelmRelease wait commands and the timeout increase to 4 minutes are appropriate changes that ensure SeaweedFS is fully deployed before proceeding with subsequent tests.

packages/core/testing/images/e2e-sandbox/Dockerfile (1)

22-23: LGTM! MinIO client installation follows established patterns.

The addition of the MinIO client (mc) is properly implemented using the same pattern as other CLI tool installations in the Dockerfile. The use of TARGETOS and TARGETARCH variables ensures cross-platform compatibility, and the executable permissions are correctly set.

hack/e2e-apps/bucket.bats (1)

15-18: Well-structured readiness checks.

The test properly waits for the HelmRelease, BucketClaims, and BucketAccesses to be ready before proceeding, which is good practice for ensuring test reliability.

@kvaps kvaps added the backport Should change be backported on previus release label Aug 1, 2025
@kvaps kvaps changed the title [seaweed] add tests [seaweed] add tests for S3 buckets Aug 1, 2025
@kvaps kvaps merged commit 8567200 into main Aug 1, 2025
20 checks passed
@kvaps kvaps deleted the feat/seaweed-tests branch August 1, 2025 10:52
Copy link

github-actions bot commented Aug 1, 2025

Successfully created backport PR for release-0.34:

kvaps added a commit that referenced this pull request Aug 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport Should change be backported on previus release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants