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

introduce integration tests #109

Merged
merged 20 commits into from
Mar 11, 2024
Merged

introduce integration tests #109

merged 20 commits into from
Mar 11, 2024

Conversation

shogo82148
Copy link
Owner

@shogo82148 shogo82148 commented Mar 10, 2024

Summary by CodeRabbit

  • New Features
    • Introduced a comprehensive setup for a CDK TypeScript project, including guidance on project structure and essential commands.
    • Added an AWS CDK application setup for creating cloud resources such as a VPC, Bastion EC2 instance, and an RDS cluster.
    • Implemented a new function to ensure database addresses always include a port, defaulting to 3306 if unspecified.
  • Tests
    • Added a test case for verifying the creation of an SQS queue in the integration stack.
  • Documentation
    • Updated README with an introduction and usage instructions for the CDK TypeScript project.
  • Chores
    • Configured Jest for TypeScript tests in a Node.js environment and updated .gitignore rules.

Copy link

coderabbitai bot commented Mar 10, 2024

Warning

Rate Limit Exceeded

@shogo82148 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 13 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.
Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.
Please see our FAQ for further information.

Commits Files that changed from the base of the PR and between f4e5b95 and 7ccf2aa.

Walkthrough

The changes encompass a holistic setup for a CDK TypeScript project emphasizing infrastructure integration, featuring a VPC, Bastion EC2 instance, and RDS cluster. Additionally, Jest is configured for TypeScript testing, and a .gitignore file is included for cleaner version control. The rdsmysql package is enhanced with ensureHavePort to ensure addresses include a port, optimizing the BuildAuthToken process.

Changes

Files Summary
_integration/.gitignore, _integration/jest.config.js Exclude specific files from version control and configure Jest for TypeScript tests.
_integration/README.md Provides an overview of the CDK TypeScript project, covering setup, structure, and commands.
_integration/bin/.../integration.ts, _integration/lib/.../integration-stack.ts Establish an AWS CDK application with a VPC, Bastion EC2, and RDS cluster.
_integration/test/.../_integration.test.ts Introduce a test case to verify SQS queue creation in the integration stack.
apply.go, apply_test.go Introduce ensureHavePort in rdsmysql for port handling and add testing utilities.
connector_test.go Add a test for Connector in rdsmysql to connect to RDS MySQL databases.

🐰✨
To the cloud, we hop and bound,
With stacks and queues, our playground.
Ports ensured, and tests well found,
In code, our dreams are unbound.
🌟🚀🌈

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

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>.
    • Generate unit-tests 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 tests 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

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 as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • 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/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link

@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.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 2692e7f and f23c74d.
Files ignored due to path filters (4)
  • _integration/cdk.json is excluded by: !**/*.json
  • _integration/package-lock.json is excluded by: !**/*.json
  • _integration/package.json is excluded by: !**/*.json
  • _integration/tsconfig.json is excluded by: !**/*.json
Files selected for processing (6)
  • _integration/.gitignore (1 hunks)
  • _integration/README.md (1 hunks)
  • _integration/bin/_integration.ts (1 hunks)
  • _integration/jest.config.js (1 hunks)
  • _integration/lib/_integration-stack.ts (1 hunks)
  • _integration/test/_integration.test.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • _integration/jest.config.js
Additional comments: 3
_integration/.gitignore (1)
  • 1-8: The .gitignore file is well-configured to ignore common Node.js and AWS CDK artifacts such as compiled JavaScript files, TypeScript declaration files, and the node_modules directory. Additionally, it correctly excludes the CDK asset staging directory and the cdk.out directory, which are specific to AWS CDK projects. This setup helps to keep the repository clean from unnecessary files and directories that should not be version-controlled.
_integration/lib/_integration-stack.ts (1)
  • 1-15: The IntegrationStack class is correctly set up as a foundational structure for defining AWS resources using the AWS CDK. The commented-out example of an SQS queue resource provides a useful starting point for developers to begin adding their resources. However, it's important to eventually remove or replace this commented-out code with actual resource definitions as the project evolves to avoid confusion and maintain code cleanliness.

Consider removing the commented-out code once actual resources are defined to keep the codebase clean and focused.

_integration/bin/_integration.ts (1)
  • 1-21: The setup in _integration/bin/_integration.ts correctly instantiates the IntegrationStack and provides commented-out options for specifying deployment environments. This flexibility allows developers to easily configure the stack for different deployment scenarios. However, it's important to ensure that the commented-out options are clearly explained or documented elsewhere in the project to help developers understand when and how to use them.

Consider adding more detailed comments or documentation on how to use the environment configuration options to help developers understand their purpose and how to apply them for different deployment scenarios.

Comment on lines +1 to +14
# Welcome to your CDK TypeScript project

This is a blank project for CDK development with TypeScript.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Useful commands

* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template
Copy link

Choose a reason for hiding this comment

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

The README file effectively introduces the project and provides a concise list of useful commands for managing the CDK TypeScript project. However, there are minor formatting issues with extra whitespaces before some of the commands. Additionally, the file types mentioned (e.g., "js") should be capitalized for consistency.

- * `npm run build`   compile typescript to js
+ * `npm run build` compile typescript to JS
- * `npm run watch`   watch for changes and compile
+ * `npm run watch` watch for changes and compile
- * `npm run test`    perform the jest unit tests
+ * `npm run test` perform the jest unit tests

Consider removing extra whitespaces for a cleaner format and capitalizing file types for consistency.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
# Welcome to your CDK TypeScript project
This is a blank project for CDK development with TypeScript.
The `cdk.json` file tells the CDK Toolkit how to execute your app.
## Useful commands
* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template
# Welcome to your CDK TypeScript project
This is a blank project for CDK development with TypeScript.
The `cdk.json` file tells the CDK Toolkit how to execute your app.
## Useful commands
* `npm run build` compile typescript to JS
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template

Comment on lines +1 to +17
// import * as cdk from 'aws-cdk-lib';
// import { Template } from 'aws-cdk-lib/assertions';
// import * as Integration from '../lib/_integration-stack';

// example test. To run these tests, uncomment this file along with the
// example resource in lib/_integration-stack.ts
test('SQS Queue Created', () => {
// const app = new cdk.App();
// // WHEN
// const stack = new Integration.IntegrationStack(app, 'MyTestStack');
// // THEN
// const template = Template.fromStack(stack);

// template.hasResourceProperties('AWS::SQS::Queue', {
// VisibilityTimeout: 300
// });
});
Copy link

Choose a reason for hiding this comment

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

The commented-out test case provides a good example of how to write tests for AWS CDK stacks, specifically testing the creation of an SQS queue. However, for the test suite to be effective, it's important to uncomment and adapt these tests as actual resources are defined within the stack. Keeping test cases commented out will not provide any value in ensuring the correctness of the stack's configuration.

Consider uncommenting and adapting the test case to match the actual resources defined in your stack to ensure the correctness and reliability of your infrastructure as code.

@shogo82148 shogo82148 changed the title cdk init app --language typescript introduce integration tests Mar 10, 2024
@shogo82148
Copy link
Owner Author

cdk bootstrap aws://339712736426/ap-northeast-1

Copy link

@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.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between f23c74d and 295bcb1.
Files ignored due to path filters (2)
  • _integration/cdk.context.json is excluded by: !**/*.json
  • _integration/cdk.json is excluded by: !**/*.json
Files selected for processing (2)
  • _integration/bin/integration.ts (1 hunks)
  • _integration/lib/integration-stack.ts (1 hunks)

_integration/bin/integration.ts Show resolved Hide resolved
_integration/lib/integration-stack.ts Outdated Show resolved Hide resolved
Copy link

@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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 295bcb1 and da3e266.
Files selected for processing (1)
  • _integration/lib/integration-stack.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • _integration/lib/integration-stack.ts

Copy link

@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.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between da3e266 and 49b990c.
Files ignored due to path filters (2)
  • _integration/package-lock.json is excluded by: !**/*.json
  • _integration/package.json is excluded by: !**/*.json
Files selected for processing (1)
  • _integration/lib/integration-stack.ts (1 hunks)

Comment on lines 6 to 38
export class IntegrationStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

// VPC
const vpc = new ec2.Vpc(this, "MyVpc", {});

// Bastion EC2 Instance
const bastionSG = new ec2.SecurityGroup(this, "BastionSG", {
vpc,
});
const bastion = new ec2.BastionHostLinux(this, "Bastion", {
vpc,
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T4G,
ec2.InstanceSize.MICRO
),
machineImage: new ec2.AmazonLinux2023ImageSsmParameter({
cpuType: ec2.AmazonLinuxCpuType.ARM_64,
}),
securityGroup: bastionSG,
});

// Relational Database Service
const cluster = new rds.DatabaseCluster(this, "Database", {
engine: rds.DatabaseClusterEngine.auroraMysql({
version: rds.AuroraMysqlEngineVersion.VER_3_05_2,
}),
writer: rds.ClusterInstance.serverlessV2("writer"),
vpc,
});
}
}
Copy link

Choose a reason for hiding this comment

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

The IntegrationStack class is well-structured and follows best practices for defining AWS infrastructure using the CDK. However, there are a few areas where improvements can be made:

  1. VPC Configuration (Line 11): The VPC is created with default settings. Depending on the integration test requirements, you might want to customize the VPC configuration, such as specifying the number of AZs or enabling/disabling NAT Gateways.

  2. Security Group for Bastion (Lines 14-16): The Security Group for the Bastion host is created without any inbound or outbound rules. It's essential to define the necessary rules to control access to the Bastion host securely.

  3. Bastion Host Configuration (Lines 17-27): The Bastion host is configured with an ARM-based instance type and the latest Amazon Linux version. Ensure that this configuration aligns with your testing requirements. Additionally, consider specifying the blockDevices property to define the EBS volume size if the default size does not meet your needs.

  4. RDS Database Cluster (Lines 30-36): The Database Cluster is configured with Aurora MySQL and a serverless writer instance. Ensure that the chosen database engine and version are compatible with your application. Also, consider specifying additional properties such as instanceProps to define the instance size and vpcSubnets to control the subnets used by the database instances.

  5. Error Handling and Cleanup: Ensure that there are mechanisms in place to handle failures during the stack deployment and to clean up resources to avoid unnecessary costs.

  6. Documentation: Adding comments to explain the purpose of each resource and any specific configuration choices can improve maintainability and make it easier for new team members to understand the infrastructure setup.

Consider these suggestions to refine the stack configuration and ensure it meets your integration testing requirements.

Copy link

@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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 49b990c and 8f08c67.
Files selected for processing (1)
  • _integration/lib/integration-stack.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • _integration/lib/integration-stack.ts

Copy link

@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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 8f08c67 and afb6169.
Files selected for processing (1)
  • _integration/lib/integration-stack.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • _integration/lib/integration-stack.ts

Copy link

@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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between afb6169 and 5e78187.
Files selected for processing (1)
  • _integration/lib/integration-stack.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • _integration/lib/integration-stack.ts

Copy link

@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.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 5e78187 and 43de0ff.
Files selected for processing (2)
  • apply_test.go (1 hunks)
  • internal/testutils/testutils.go (1 hunks)
Additional comments: 1
internal/testutils/testutils.go (1)
  • 35-37: The use of t.Fatal(err) within the db.PingContext(context.Background()) call is appropriate for failing the test immediately upon encountering an error. However, it's worth considering the context in which this function is used. Given that this is an integration test setup function, failing here indicates an inability to connect to the database, which is critical for the success of any dependent tests.

In addition to logging the error, you might want to include more context in the error message to aid in troubleshooting. For example, you could log the database host and user (without the password for security reasons) to provide immediate insights into the connection attempt's configuration.

apply_test.go Outdated Show resolved Hide resolved
Comment on lines +32 to +33
db := sql.OpenDB(conn)
defer db.Close()
Copy link

Choose a reason for hiding this comment

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

While you are correctly closing the database connection with defer db.Close(), it's important to note that sql.OpenDB does not actually open a new connection but rather returns a *DB object configured to open a connection when needed. Therefore, it's possible for sql.OpenDB to return a non-nil *DB object even when there are configuration issues or other problems that would prevent a successful connection.

Consider adding error handling after sql.OpenDB to check for potential issues early. For example, you could attempt a simple query to validate the connection. This would ensure that any misconfiguration or connectivity issue is caught immediately, rather than at a later stage when the db.PingContext is called.

Copy link

@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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 43de0ff and ce2555d.
Files selected for processing (1)
  • internal/testutils/testutils.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • internal/testutils/testutils.go

Copy link

@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.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between ce2555d and 3b45836.
Files selected for processing (2)
  • apply_test.go (1 hunks)
  • internal/testutils/testutils.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • apply_test.go
Additional comments: 1
internal/testutils/testutils.go (1)
  • 38-39: While you are correctly closing the database connection with defer db.Close(), it's important to note that sql.OpenDB does not actually open a new connection but rather returns a *DB object configured to open a connection when needed. Therefore, it's possible for sql.OpenDB to return a non-nil *DB object even when there are configuration issues or other problems that would prevent a successful connection.

Consider adding error handling after sql.OpenDB to check for potential issues early. For example, you could attempt a simple query to validate the connection. This would ensure that any misconfiguration or connectivity issue is caught immediately, rather than at a later stage when the db.PingContext is called.

return nil // already initialized
}

_, err := db.ExecContext(ctx, "CREATE USER '"+User+"' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'")
Copy link

@coderabbitai coderabbitai bot Mar 11, 2024

Choose a reason for hiding this comment

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

Using string concatenation in SQL queries can lead to SQL injection vulnerabilities. Although the User variable is a hard-coded string, reducing the immediate risk, it's a best practice to use parameterized queries to ensure the security of your application. Consider refactoring this query to use parameterized statements.

- _, err := db.ExecContext(ctx, "CREATE USER '"+User+"' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'")
+ _, err := db.ExecContext(ctx, "CREATE USER ? IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'", User)

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
_, err := db.ExecContext(ctx, "CREATE USER '"+User+"' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'")
_, err := db.ExecContext(ctx, "CREATE USER ? IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'", User)

Copy link
Owner Author

Choose a reason for hiding this comment

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

We can't use placeholder here.

Copy link

Choose a reason for hiding this comment

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

@shogo82148: Thank you for pointing that out. You're correct; the CREATE USER statement in MySQL does not support the use of placeholders for certain parameters, including the username. This is a limitation of the SQL syntax for Data Definition Language (DDL) operations. Given that the User variable is hard-coded, the risk of SQL injection is mitigated in this context. It's always good practice to validate or sanitize inputs when constructing SQL queries dynamically, but it seems you've handled this scenario appropriately. Your expertise and attention to detail are much appreciated.

Copy link

@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.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 3b45836 and 9e0ac27.
Files selected for processing (3)
  • apply.go (3 hunks)
  • apply_test.go (1 hunks)
  • internal/testutils/testutils.go (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • apply_test.go
  • internal/testutils/testutils.go
Additional comments: 1
apply.go (1)
  • 32-34: The update to the Apply function to use ensureHavePort for appending a default port if one is not specified is a practical enhancement for database connectivity. This change ensures that the BuildAuthToken call always receives an address with a port, aligning with the expected format. However, it's important to ensure that this change does not introduce any unexpected behavior in scenarios where the config.Addr might already include a port or in cases where a non-default port is used. Testing this change with various address formats would be beneficial to confirm its robustness.

Comment on lines +48 to +54
// ensureHavePort ensures that addr has a port.
func ensureHavePort(addr string) string {
if _, _, err := net.SplitHostPort(addr); err != nil {
return net.JoinHostPort(addr, "3306")
}
return addr
}
Copy link

Choose a reason for hiding this comment

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

The ensureHavePort function is a good addition to ensure that the address always includes a port, defaulting to 3306 if not specified. However, there are a couple of points to consider for improvement:

  1. Error Handling: The current implementation silently defaults to port 3306 if net.SplitHostPort fails for any reason. It might be beneficial to log this event or handle specific error types differently, especially if the error is not related to the absence of a port but other issues with the address format.
  2. Hardcoded Port: The default port 3306 is hardcoded. Consider defining it as a constant at the beginning of the file. This makes the code more maintainable and readable, especially if the default port needs to be changed in the future or reused elsewhere in the code.
+ const defaultMySQLPort = "3306"
  ...
-		return net.JoinHostPort(addr, "3306")
+		return net.JoinHostPort(addr, defaultMySQLPort)

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// ensureHavePort ensures that addr has a port.
func ensureHavePort(addr string) string {
if _, _, err := net.SplitHostPort(addr); err != nil {
return net.JoinHostPort(addr, "3306")
}
return addr
}
// ensureHavePort ensures that addr has a port.
const defaultMySQLPort = "3306"
func ensureHavePort(addr string) string {
if _, _, err := net.SplitHostPort(addr); err != nil {
return net.JoinHostPort(addr, defaultMySQLPort)
}
return addr
}

Copy link

@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.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 9e0ac27 and fe44fe8.
Files selected for processing (2)
  • apply_test.go (1 hunks)
  • connector_test.go (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • apply_test.go

Comment on lines +14 to +34
func TestConnector(t *testing.T) {
testutils.Setup(t)

awsConfig := aws.NewConfig().WithRegion(testutils.Region)
awsSession := session.Must(session.NewSession(awsConfig))

config := mysql.NewConfig()
config.User = testutils.User
config.Addr = testutils.Host
connector := &Connector{
Session: awsSession,
Config: config,
MaxConnsPerSecond: 10,
}

db := sql.OpenDB(connector)
defer db.Close()

if err := db.PingContext(context.Background()); err != nil {
t.Error(err)
}
Copy link

Choose a reason for hiding this comment

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

The test function TestConnector is well-structured and follows a clear setup, execute, and teardown pattern. However, there are a few areas that could be improved for better maintainability and robustness:

  1. Error Handling for sql.OpenDB: The call to sql.OpenDB(connector) returns a *DB and an error, but the error is not being checked. It's important to handle this error to catch any issues with database connection initialization early.

  2. Context Timeout for db.PingContext: Using context.Background() provides no timeout, which means if the database connection hangs, the test could run indefinitely. It's a good practice to use a timeout context here to ensure the test fails gracefully after a reasonable amount of time if it cannot establish a connection.

  3. Asserting Test Outcome: The current test uses t.Error(err) to report errors, which is fine for logging the error. However, consider using t.Fatalf instead of t.Error for critical failures like failing to ping the database. This will immediately stop the test, which is usually desirable for critical setup errors.

Here's a suggested improvement incorporating these points:

- db := sql.OpenDB(connector)
+ db, err := sql.OpenDB(connector)
+ if err != nil {
+     t.Fatalf("Failed to open database: %v", err)
+ }
  defer db.Close()
- if err := db.PingContext(context.Background()); err != nil {
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := db.PingContext(ctx); err != nil {
-     t.Error(err)
+     t.Fatalf("Failed to ping database: %v", err)
  }

Additionally, ensure that the time package is imported to use the WithTimeout function.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func TestConnector(t *testing.T) {
testutils.Setup(t)
awsConfig := aws.NewConfig().WithRegion(testutils.Region)
awsSession := session.Must(session.NewSession(awsConfig))
config := mysql.NewConfig()
config.User = testutils.User
config.Addr = testutils.Host
connector := &Connector{
Session: awsSession,
Config: config,
MaxConnsPerSecond: 10,
}
db := sql.OpenDB(connector)
defer db.Close()
if err := db.PingContext(context.Background()); err != nil {
t.Error(err)
}
func TestConnector(t *testing.T) {
testutils.Setup(t)
awsConfig := aws.NewConfig().WithRegion(testutils.Region)
awsSession := session.Must(session.NewSession(awsConfig))
config := mysql.NewConfig()
config.User = testutils.User
config.Addr = testutils.Host
connector := &Connector{
Session: awsSession,
Config: config,
MaxConnsPerSecond: 10,
}
db, err := sql.OpenDB(connector)
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
defer db.Close()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := db.PingContext(ctx); err != nil {
t.Fatalf("Failed to ping database: %v", err)
}

Copy link

@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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between fe44fe8 and f4e5b95.
Files selected for processing (1)
  • cmd/rdsmysql/main_test.go (1 hunks)
Additional comments: 1
cmd/rdsmysql/main_test.go (1)
  • 10-20: The test TestRun is well-structured and follows good practices by separating test setup, execution, and assertion. However, it only tests a single scenario. Consider adding more test cases to cover different inputs, error paths, and edge cases to ensure comprehensive testing of the run function.

@shogo82148 shogo82148 merged commit 52cecf1 into main Mar 11, 2024
18 checks passed
@shogo82148 shogo82148 deleted the introduce-integration-test branch March 11, 2024 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant