Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add testcontainers-go tests to DynamoDB and NATS #1574

Merged
merged 8 commits into from
Mar 20, 2025

Conversation

mdelapenya
Copy link
Contributor

@mdelapenya mdelapenya commented Mar 19, 2025

  • feat: use testcontainers-go's DynamoDB module
  • feat: use testcontainers-go's nats module

What does this PR do?

It follows the same strategy of adding testcontainers-go to make it possible running the integration tests for the storage layer in the local machine,
not needing to install the given storage technology in the host.

I'm copying the result of executing the gen-test-certs.sh into the testdata dir of the nats module, although I'm open to discuss whether it's worth it having them statically or dynamically.

Why is it important?

Run the tests exactly the same in the Ci as in the local machine, making it possible to test/debug locally.

Related PRs

Summary by CodeRabbit

  • Tests

    • Improved test environments with container-based setups for both DynamoDB and NATS, ensuring a more modular and robust testing process.
    • Enhanced error handling during test initialization for more reliable test execution.
  • Configuration

    • Updated TLS settings for NATS by correcting certificate and key file paths to maintain proper security configurations.

@mdelapenya mdelapenya requested a review from a team as a code owner March 19, 2025 11:34
@mdelapenya mdelapenya requested review from gaby, sixcolors, ReneWerner87 and efectn and removed request for a team March 19, 2025 11:34
Copy link
Contributor

coderabbitai bot commented Mar 19, 2025

Walkthrough

The changes refactor the testing setup for both DynamoDB and NATS. Each now uses a dedicated newTestStore function that leverages the testcontainers library to dynamically spin up the required container, replacing static global configurations. Error checking is performed immediately, and cleanup is deferred for robust management. Additionally, the NATS TLS configuration file has been updated to reference the correct certificate and key files.

Changes

File(s) Change Summary
dynamodb/dynamodb_test.go Added newTestStore to replace the global variable and integrate container initialization using testcontainers, with enhanced error handling and proper cleanup.
nats/nats_test.go Added newTestStore for a dynamic NATS container setup with TLS configuration; removed static configuration and added improved error checking and connection setup.
nats/testdata/nats-tls.conf Updated TLS configuration file: changed cert_file and key_file paths from /tls/redis.* to /tls/nats.*.

Sequence Diagram(s)

sequenceDiagram
    participant TF as Test Function
    participant TS as newTestStore
    participant TC as TestContainers

    TF->>TS: Call newTestStore(t)
    TS->>TC: Start container with DynamoDB/NATS image
    TC-->>TS: Return container details and connection info
    TS-->>TF: Return Storage instance and error
    TF->>TF: Check error and defer cleanup
Loading

Poem

I'm a rabbit, hopping through code with cheer,
Leaving old globals quietly in yesteryear.
Test containers bloom like carrots in the sun,
New stores spring up—oh, what fun!
My code now leaps free, full of hops and gear!


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 05d6677 and 585b3e9.

📒 Files selected for processing (2)
  • dynamodb/dynamodb_test.go (10 hunks)
  • nats/nats_test.go (11 hunks)

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 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 or @coderabbitai title 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
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

🧹 Nitpick comments (5)
nats/testdata/tls/redis.crt (1)

1-27: Review of Redis Certificate File

The TLS certificate appears to be correctly structured in PEM format. Since this certificate is intended for testing purposes (as evidenced by its placement in the testdata directory), please ensure it is clearly documented as a non-production, dummy certificate. This documentation would help prevent any potential misuse in a production environment.

nats/testdata/tls/ca.crt (1)

1-32: Review of CA Certificate File

The CA certificate is correctly structured in PEM format. As this certificate is intended to serve in a testing context (e.g., to validate test certificate chains), ensure it is clearly marked as being used solely for testing. Including a brief note at the top of the file could prevent any accidental reliance on it in production deployments.

nats/nats_test.go (3)

21-26: Minor copy-paste comment fix recommended.
The comment mentions "mysqlImage" while referring to natsImage. Update it to accurately reflect the NATS context.

- // mysqlImage is the default image used for running MySQL in tests.
+ // natsImage is the default image used for running NATS in tests.

28-40: Check naming consistency of embedded certificate files.
You're embedding files named redis.crt and redis.key in a NATS-specific test environment. This might be confusing or misleading. If they're NATS server certs, consider renaming them to reflect their actual usage.


331-342: Effective performance benchmark for Set.
Ensuring the store is initialized once per benchmark iteration can improve reliability and consistency. The code logic is correct.

To avoid potential interference among runs, consider scoping each benchmark iteration with fresh keys or resetting the store between runs.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c1933ed and d569495.

⛔ Files ignored due to path filters (7)
  • .github/workflows/benchmark.yml is excluded by !**/*.yml
  • .github/workflows/test-dynamodb.yml is excluded by !**/*.yml
  • .github/workflows/test-nats.yml is excluded by !**/*.yml
  • dynamodb/go.mod is excluded by !**/*.mod
  • dynamodb/go.sum is excluded by !**/*.sum, !**/*.sum
  • nats/go.mod is excluded by !**/*.mod
  • nats/go.sum is excluded by !**/*.sum, !**/*.sum
📒 Files selected for processing (7)
  • dynamodb/dynamodb_test.go (8 hunks)
  • nats/nats_test.go (9 hunks)
  • nats/testdata/tls/ca.crt (1 hunks)
  • nats/testdata/tls/client.crt (1 hunks)
  • nats/testdata/tls/client.key (1 hunks)
  • nats/testdata/tls/redis.crt (1 hunks)
  • nats/testdata/tls/redis.key (1 hunks)
🧰 Additional context used
🪛 Gitleaks (8.21.2)
nats/testdata/tls/redis.key

1-28: Identified a Private Key, which may compromise cryptographic security and sensitive data encryption.

(private-key)

🔇 Additional comments (25)
nats/testdata/tls/client.crt (1)

1-27: Review of Client Certificate File

The client certificate is properly formatted in PEM. As this file is meant to support secure communication in test scenarios, confirm that its usage is strictly limited to testing, and consider adding a header comment in the file to clearly indicate its test-only purpose.

nats/testdata/tls/client.key (1)

1-29:

❓ Verification inconclusive

Critical: Private Key Exposure in Client Key

This file contains a private key in PEM format. Storing private keys in plaintext—even for testing—poses a potential security risk if they are ever misused. Please verify that this key is a dummy key intended solely for integration tests and is not used in any production scenario. It may be beneficial to add a header comment explicitly stating its test-only nature.


Below is a shell script that you can run to verify that the exposed key is used only in test code and to inspect its contents:

#!/bin/bash
# 1. Search for references to 'nats/testdata/tls/client.key' outside of test directories.
echo "Searching for references to 'nats/testdata/tls/client.key' outside test files..."
rg "nats/testdata/tls/client.key" --glob "!.*/testdata/.*" -n .

# 2. Display the first 30 lines of the key file to verify its contents.
echo "Displaying the first 30 lines of nats/testdata/tls/client.key:"
head -n 30 nats/testdata/tls/client.key

Please execute this script and review the output. The first step checks that the key isn't referenced in production or non-test code, ensuring it’s isolated for integration tests only. The output from the second step should confirm that the file contents match the dummy key provided.

Once you have verified:

  • That the key is used solely within test contexts.
  • That the key itself is clearly a dummy/test key.

You can then address (or dismiss) the review comment accordingly.

If after running the script you confirm that the key is only used in tests and is dummy by nature, you may add a header comment to the file specifying its test-only purpose to make the intent explicit.

nats/testdata/tls/redis.key (1)

1-29:

❓ Verification inconclusive

Critical: Private Key Exposure in Redis Key

Similar to the client key, this file contains a private key in PEM format. Confirm that it is a non-production, dummy key for testing purposes only. Storing a private key publicly, even for tests, can be flagged by static analysis tools (e.g., Gitleaks), so please ensure that its usage is safe and appropriately documented.


Action Required: Verify Dummy Private Key in Test Data

It appears that the file at nats/testdata/tls/redis.key contains a private key in PEM format. Since it’s located under a test data folder, it is likely intended solely for non-production testing. However, please verify the following:

  • Confirm that this key is a dummy key used exclusively for testing.
  • Ensure its usage is clearly documented so that static analysis tools (e.g., Gitleaks) don’t flag it as a security risk.
  • Double-check that no production system inadvertently relies on this key.

Once confirmed, please update the documentation (or add comments within the test configuration) to explicitly state its safe, non-production usage.

🧰 Tools
🪛 Gitleaks (8.21.2)

1-28: Identified a Private Key, which may compromise cryptographic security and sensitive data encryption.

(private-key)

nats/nats_test.go (9)

114-125: Good usage of the newTestStore in test.
This test pattern with defer testStore.Close() ensures containers are cleaned up. The logic for setting keys and verifying them is correct.


132-137: Appropriate approach to test overwriting keys.
Reusing the same key with a new value is straightforward and is tested thoroughly.


167-177: Well-structured TTL (expiration) test for NATS.
Sleeping for slightly over one second confirms correct expiration. Clear usage.


239-246: No issues for getting non-existent keys.
This test ensures retrieving a non-existent key returns empty. Good coverage.


253-279: Proper delete coverage.
Test scenario for delete is correct, verifying key removal.


281-312: Bulk reset test is comprehensive.
Test scenario ensures all keys are wiped, covering the general reset behavior.


345-359: Straightforward get benchmark.
Logic is correct and ensures repeated retrieval.


362-376: Benchmark set and delete operations.
The approach is valid. Ensuring repeated set and deletes can measure throughput effectively.


42-112:

❓ Verification inconclusive

Validate container readiness and cleanup flow.
The newTestStore function properly starts a NATS container with TLS and registers cleanup. Overall logic looks good. However, consider verifying that the container is fully ready before proceeding with further steps (for instance, having a health check or a more robust wait strategy).

If you’d like to confirm the container is indeed ready for TLS-based connections, you can expand the wait strategy to ensure that the TLS port is responsive.


🏁 Script executed:

#!/bin/bash
# Example approach: Checking logs for the final "Server is ready" message if present.
rg "Server is ready" nats/nats.go -A 10

Length of output: 41


Ensure complete container readiness for TLS connections.
The newTestStore function correctly initializes a NATS container with TLS and handles cleanup. However, relying solely on the log message "Listening for client connections on 0.0.0.0:4443" may not fully guarantee that the container is ready for TLS-based interactions. Consider enhancing the wait strategy—such as by verifying that the TLS port is responsive or by checking for an explicit readiness log like "Server is ready."

Please manually verify that the container is indeed fully ready before proceeding with TLS operations.

dynamodb/dynamodb_test.go (13)

13-17: Accurate environment variable usage.
The constants and environment variable logic for the DynamoDB image is correct and consistent with testcontainers best practices.


19-52: newTestStore function is well-structured.
Running a local DynamoDB container with testcontainers is properly set up. Cleanup logic using testcontainers.CleanupContainer ensures containers don’t linger. Error returns are handled.


60-63: Appropriate test instantiation.
Creating a new store per test prevents cross-test contamination.


74-77: Overwriting keys scenario is tested.
Verifies the same key is set again, ensuring proper coverage.


91-101: Valid GET test logic.
Confirms the store retrieval is consistent.


103-111: Nonexistent key coverage.
Properly verifies that missing keys return no data.


119-132: Deleting entries scenario is validated.
Key is confirmed removed, ensuring the data is wiped as expected.


137-157: Full reset coverage.
Confirms that all keys are removed in a single operation.


159-164: No concerns with closing logic.
Ensures resources are properly freed.


167-172: Conn() function usage is verified.
Checks for a valid connection instance. Straightforward.


178-186: Set benchmark structure.
Uses testcontainers approach for an isolated test environment. Code logic is sound.


189-202: Get benchmark logic is consistent.
Proper approach for repeated retrieval. No issues.


209-220: Set and delete benchmark covers typical usage pattern.
Repeatedly sets and deletes the same key, providing coverage for throughput analysis.

@mdelapenya mdelapenya requested a review from gaby March 19, 2025 13:31
Copy link
Member

@gaby gaby left a comment

Choose a reason for hiding this comment

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

LGTM, just a few comments

@mdelapenya mdelapenya requested a review from gaby March 20, 2025 12:24
Copy link
Member

@gaby gaby left a comment

Choose a reason for hiding this comment

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

👍 LGTM

@mdelapenya
Copy link
Contributor Author

@gaby now that I'm part of the org, what's the policy for merging: waiting for +2 approvals? Is it any of you, me the one merging?

@gaby
Copy link
Member

gaby commented Mar 20, 2025

@mdelapenya Yes, 2 people excluding the one creating the PR.

I posted a link to the PR to the "ready for review channel", but all the maintainers are in different timezones.

@ReneWerner87 ReneWerner87 merged commit 5b03e3c into gofiber:main Mar 20, 2025
15 checks passed
@mdelapenya mdelapenya deleted the tc-go-adoption-3 branch March 21, 2025 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants