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: optimize sqlserver test #652

Merged
merged 8 commits into from
Sep 21, 2024
Merged

feat: optimize sqlserver test #652

merged 8 commits into from
Sep 21, 2024

Conversation

hwbrzzl
Copy link
Contributor

@hwbrzzl hwbrzzl commented Sep 20, 2024

📑 Description

Can't connect the sqlserver docker in Github action, but local is normal. Switch the sqlserver image to another one.

image

Summary by CodeRabbit

  • New Features

    • Updated password storage for improved security.
    • Introduced a new function to detect GitHub Actions environment.
  • Bug Fixes

    • Enhanced SQL Server connection logic to ensure database creation if it does not exist.
  • Tests

    • Updated test configurations to use dynamic variables instead of hardcoded values for better flexibility.

Copy link
Contributor

coderabbitai bot commented Sep 20, 2024

Walkthrough

The changes involve updates to various files related to Docker and database configurations. Key modifications include changing hardcoded database credentials to use variables, updating the SQL Server Docker image repository, enhancing connection logic, and adding a new function to check for the GitHub Action environment. These changes improve flexibility and maintainability in the codebase.

Changes

Files Change Summary
support/docker/docker.go Updated the password constant from "Goravel123" to "Framework!123".
support/docker/postgres_test.go Replaced hardcoded database configuration values with variables in the PostgresImpl initialization and assertions.
support/docker/sqlite_test.go Modified the database name assertion in the TestBuild function to use a variable instead of a hardcoded string.
support/docker/sqlserver.go Changed SQL Server Docker image repository and updated connection logic to create a database and user if it does not exist. Extended connection attempts from 60 to 100.
support/docker/sqlserver_test.go Replaced hardcoded database configuration values with variables in the TestBuild assertions.
support/env/env.go Added a new function IsGithub to check for the GITHUB_ACTION environment variable and updated import statements.
testing/docker/database_test.go Updated testPassword from "Goravel123" to "Framework!123" and replaced local variables with new test variables for database connection setups.

Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 8d7df98 and ff1e323.

Files selected for processing (1)
  • testing/docker/database_test.go (7 hunks)
Additional comments not posted (4)
testing/docker/database_test.go (4)

27-27: LGTM!

The password change to a stronger value is a good security practice.


56-58: Excellent refactoring!

Using global variables for test configurations promotes consistency and maintainability. If the test configurations need to be changed in the future, it can be done in one place instead of updating in multiple places. This is a great improvement in the test code.

Also applies to: 75-77, 94-96, 113-115, 132-134, 151-153


65-65: LGTM!

Using global variables for database driver configurations ensures that the correct test configurations are used. This change is consistent with the usage of global variables for test configurations and should not have any negative impact on the functionality.

Also applies to: 84-84, 103-103, 122-122, 141-141


Line range hint 1-270: Great job with the test file!

The test cases are comprehensive, covering different scenarios and database drivers. The usage of global variables for test configurations is a good practice for maintainability. The code follows good practices such as mocking dependencies and asserting expectations.

Overall, the test file seems to be well-structured and maintainable, providing good coverage for database connection functionality using Docker.


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

@hwbrzzl hwbrzzl changed the title feat: cancel sqlserver test feat: optimize sqlserver test Sep 20, 2024
Copy link

codecov bot commented Sep 20, 2024

Codecov Report

Attention: Patch coverage is 48.00000% with 13 lines in your changes missing coverage. Please review.

Project coverage is 70.08%. Comparing base (a0d1a1a) to head (ff1e323).
Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
support/docker/sqlserver.go 54.54% 5 Missing and 5 partials ⚠️
support/env/env.go 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #652      +/-   ##
==========================================
- Coverage   70.14%   70.08%   -0.07%     
==========================================
  Files         184      184              
  Lines       11340    11357      +17     
==========================================
+ Hits         7955     7959       +4     
- Misses       2803     2811       +8     
- Partials      582      587       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@hwbrzzl hwbrzzl marked this pull request as ready for review September 20, 2024 15:46
@hwbrzzl hwbrzzl requested a review from a team as a code owner September 20, 2024 15:46
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: 3

Outside diff range and nitpick comments (2)
support/docker/sqlserver.go (2)

124-161: Security concern: Using the 'sa' account for initial setup.

Connecting to the SQL Server using the 'sa' account can pose security risks. It's generally recommended to use a less privileged account for database operations when possible.

Consider creating a dedicated administration user with the minimal required privileges to perform setup tasks, reducing the reliance on the 'sa' account.


122-162: Potential race conditions during setup in concurrent environments.

If multiple instances of this setup run concurrently, there may be race conditions when checking for the existence of the database and user. This could lead to errors or inconsistent states.

Implement locking mechanisms or use idempotent queries to handle concurrent executions safely. SQL Server supports application locks that can be used to serialize access.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 634b3a1 and 8d7df98.

Files selected for processing (6)
  • support/docker/docker.go (1 hunks)
  • support/docker/postgres_test.go (2 hunks)
  • support/docker/sqlite_test.go (1 hunks)
  • support/docker/sqlserver.go (2 hunks)
  • support/docker/sqlserver_test.go (1 hunks)
  • support/env/env.go (2 hunks)
Additional comments not posted (11)
support/env/env.go (2)

3-6: LGTM!

Grouping related packages together improves code readability. The import statements look good.


44-50: LGTM!

The IsGithub() function is implemented correctly and the documentation is clear. This function can be useful for environment-specific configurations or behaviors.

support/docker/sqlite_test.go (1)

39-39: Ensure the database variable is defined and assigned correctly.

The change to use a database variable instead of a hardcoded string makes the test more flexible and configurable, which is a positive improvement.

However, the database variable is not defined or assigned a value within the provided code context. This could lead to a compilation error or unexpected behavior during test execution.

Please ensure that the database variable is properly defined and assigned the expected value before using it in the assertion.

Also, verify if the database variable is defined and assigned correctly in other parts of the codebase that may be setting up or configuring the test environment.

support/docker/sqlserver_test.go (3)

40-40: LGTM!

The assertion correctly verifies that the database name in the SQL Server configuration matches the database variable. This change enhances flexibility by allowing the use of dynamic values instead of hardcoded strings.


41-41: LGTM!

The assertion correctly verifies that the username in the SQL Server configuration matches the username variable. This change enhances flexibility by allowing the use of dynamic values instead of hardcoded strings.


42-42: LGTM!

The assertion correctly verifies that the password in the SQL Server configuration matches the password variable. This change enhances flexibility by allowing the use of dynamic values instead of hardcoded strings.

support/docker/postgres_test.go (4)

40-40: LGTM!

The assertion for the database name has been correctly updated to use the database variable, aligning with the change made in the NewPostgresImpl function call.


41-41: LGTM!

The assertion for the username has been correctly updated to use the username variable, aligning with the change made in the NewPostgresImpl function call.


42-42: LGTM!

The assertion for the password has been correctly updated to use the password variable, aligning with the change made in the NewPostgresImpl function call.


30-30: Verify the variable definitions and assignments.

The database, username, and password variables used in the NewPostgresImpl function call are not defined within the provided code context. Ensure that these variables are properly defined and assigned appropriate values to avoid runtime errors or unexpected behavior.

Run the following script to verify the variable definitions:

Verification successful

To further investigate the usage of the database, username, and password variables in the postgres_test.go file, we need to examine its contents. Let's run another script to view the file:


The variable usage is correct, but their definitions are in a different file.

The database, username, and password variables are correctly used in the NewPostgresImpl function call within the SetupTest method of the PostgresTestSuite. These variables are also used in assertions to verify the postgres configuration.

However, these variables are not defined within postgres_test.go. They are likely defined as package-level variables in another file within the docker package, possibly in docker.go. This is a common practice for sharing test configurations across multiple test files in the same package.

To improve code clarity, consider one of the following:

  • Add a comment near the variable usage explaining where they are defined.
  • If possible, import these variables explicitly to make the dependency clear.
  • Consider using a configuration struct passed to the test suite to make the test setup more explicit.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the variable definitions for `database`, `username`, and `password`.

# Test: Search for the variable definitions. Expect: Variable definitions with appropriate values.
rg --type go -A 5 $'(database|username|password)\s*='

Length of output: 3392


Script:

#!/bin/bash
# Description: Examine the contents of postgres_test.go

# Display the contents of the file
cat support/docker/postgres_test.go

# Search for import statements and variable usages
echo "--- Imports and variable usages ---"
rg --type go -n "(import|\b(database|username|password)\b)" support/docker/postgres_test.go

Length of output: 2553

support/docker/sqlserver.go (1)

31-35: Verify the correctness of the Docker image and environment variables.

The Docker image has been updated to "mcr.microsoft.com/mssql/server", and the environment variable MSSQL_SA_PASSWORD is used to set the SA password. Ensure that this environment variable is correct for the new image and that the image tag "latest" is appropriate for your needs.

Run the following script to confirm that MSSQL_SA_PASSWORD is the correct variable and that the SQL Server starts as expected:

Verification successful

Docker configuration for SQL Server is correct, with a minor suggestion.

The Docker configuration for SQL Server in support/docker/sqlserver.go is correct and follows best practices:

  • Uses the official Microsoft Container Registry image: "mcr.microsoft.com/mssql/server"
  • Sets required environment variables: ACCEPT_EULA and MSSQL_SA_PASSWORD
  • Exposes the default SQL Server port: 1433

Minor suggestion:

  • Consider pinning the image to a specific version instead of using "latest" for better reproducibility in production environments.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Test the SQL Server Docker image with the specified environment variable.

# Test: Run the Docker image and check if it's accepting connections.
docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=YourStrong!Passw0rd' -p 1433:1433 -d mcr.microsoft.com/mssql/server:latest

# Give the server time to start
sleep 15

# Check the SQL Server logs for any errors.
docker logs $(docker ps -q --filter ancestor=mcr.microsoft.com/mssql/server:latest)

Length of output: 447


Script:

#!/bin/bash
# Search for Docker configuration related to SQL Server
rg --type go "mcr.microsoft.com/mssql/server" -A 10

# Check for environment variables related to SQL Server
rg --type go "ACCEPT_EULA" -A 5
rg --type go "MSSQL_SA_PASSWORD" -A 5

# Look for port configuration
rg --type go "1433" -C 5

Length of output: 2314

@@ -9,7 +9,7 @@ import (
type ContainerType string

const (
password = "Goravel123"
password = "Framework!123"
Copy link
Contributor

Choose a reason for hiding this comment

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

Tip

Codebase Verification

Update approved, but action required for test files

The password change in support/docker/docker.go has been successfully implemented. However, there are a few important points to address:

  1. The old password "Goravel123" is still present in testing/docker/database_test.go. Please update these test cases to use either the new password or a different test password to avoid confusion and potential test failures.

  2. The password constant is used in various parts of the application, particularly in database-related code. Ensure that all components using this constant are still functioning correctly after the change.

  3. If there's any documentation referencing the old password, make sure to update it accordingly.

Action items:

  • Update the password in testing/docker/database_test.go
  • Verify the functionality of all components using the password constant
  • Update any relevant documentation
Analysis chain

Verify the password change across the codebase.

The password change looks good. However, please ensure that this new password is updated in all relevant places, such as:

  • Configuration files
  • Documentation
  • Any other code references

Also, communicate this change to the team to avoid any disruptions.

Run the following script to verify the usage of the password constant:

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the `password` constant across the codebase.

# Test: Search for the `password` constant usage. Expect: Only occurrences with the new value.
rg --type go -A 5 $'password = "Framework!123"'

Length of output: 370


Script:

#!/bin/bash
# Description: Further verify the password change across the codebase.

# Test 1: Search for any remaining instances of the old password.
echo "Searching for old password:"
rg --type go -A 5 "Goravel123"

# Test 2: Look for uses of the 'password' constant.
echo "Searching for uses of 'password' constant:"
ast-grep --lang go --pattern 'password'

Length of output: 5396

Comment on lines +122 to +162
for i := 0; i < 100; i++ {
instance, err = gormio.Open(sqlserver.New(sqlserver.Config{
DSN: fmt.Sprintf("sqlserver://%s:%s@%s:%d?database=%s",
receiver.username, receiver.password, receiver.host, receiver.port, receiver.database),
DSN: fmt.Sprintf("sqlserver://%s:%s@%s:%d?database=master",
"sa", receiver.password, receiver.host, receiver.port),
}))

if err == nil {
// Check if database exists
var exists bool
query := fmt.Sprintf("SELECT CASE WHEN EXISTS (SELECT * FROM sys.databases WHERE name = '%s') THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END", receiver.database)
if err := instance.Raw(query).Scan(&exists).Error; err != nil {
return nil, err
}

if !exists {
// Create User database
if err := instance.Exec(fmt.Sprintf("CREATE DATABASE %s", receiver.database)).Error; err != nil {
return nil, err
}

// Create User account
if err := instance.Exec(fmt.Sprintf("CREATE LOGIN %s WITH PASSWORD = '%s'", receiver.username, receiver.password)).Error; err != nil {
return nil, err
}

// Create DB account for User
if err := instance.Exec(fmt.Sprintf("USE %s; CREATE USER %s FOR LOGIN %s", receiver.database, receiver.username, receiver.username)).Error; err != nil {
return nil, err
}

// Add permission
if err := instance.Exec(fmt.Sprintf("USE %s; ALTER ROLE db_owner ADD MEMBER %s", receiver.database, receiver.username)).Error; err != nil {
return nil, err
}
}

instance, err = gormio.Open(sqlserver.New(sqlserver.Config{
DSN: fmt.Sprintf("sqlserver://%s:%s@%s:%d?database=%s",
receiver.username, receiver.password, receiver.host, receiver.port, receiver.database),
}))

Copy link
Contributor

Choose a reason for hiding this comment

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

Enhance error handling in the connection logic.

The connection logic has been extended to include database and user creation. However, if any of these steps fail, the error handling could be improved to provide more detailed information and ensure resources are cleaned up appropriately.

Consider adding more descriptive error messages and handling partial failures. For example:

// After each operation, check for errors and provide context
if err := instance.Exec(fmt.Sprintf("CREATE DATABASE %s", receiver.database)).Error; err != nil {
    return nil, fmt.Errorf("failed to create database '%s': %v", receiver.database, err)
}

// Similarly for other operations

Comment on lines +132 to +156
if err := instance.Raw(query).Scan(&exists).Error; err != nil {
return nil, err
}

if !exists {
// Create User database
if err := instance.Exec(fmt.Sprintf("CREATE DATABASE %s", receiver.database)).Error; err != nil {
return nil, err
}

// Create User account
if err := instance.Exec(fmt.Sprintf("CREATE LOGIN %s WITH PASSWORD = '%s'", receiver.username, receiver.password)).Error; err != nil {
return nil, err
}

// Create DB account for User
if err := instance.Exec(fmt.Sprintf("USE %s; CREATE USER %s FOR LOGIN %s", receiver.database, receiver.username, receiver.username)).Error; err != nil {
return nil, err
}

// Add permission
if err := instance.Exec(fmt.Sprintf("USE %s; ALTER ROLE db_owner ADD MEMBER %s", receiver.database, receiver.username)).Error; err != nil {
return nil, err
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Optimize database and user creation queries.

Currently, the code executes multiple SQL statements separately to set up the database and user. This can be optimized by combining statements and using transactions to ensure atomicity.

You can refactor the SQL commands into a single script:

script := fmt.Sprintf(`
IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = N'%s')
BEGIN
    CREATE DATABASE [%s];
END;

USE [%s];

IF NOT EXISTS (SELECT * FROM sys.sql_logins WHERE name = N'%s')
BEGIN
    CREATE LOGIN [%s] WITH PASSWORD = N'%s';
END;

IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N'%s')
BEGIN
    CREATE USER [%s] FOR LOGIN [%s];
    ALTER ROLE db_owner ADD MEMBER [%s];
END;
`, receiver.database, receiver.database, receiver.database, receiver.username, receiver.username, receiver.password, receiver.username, receiver.username, receiver.username, receiver.username)

if err := instance.Exec(script).Error; err != nil {
    return nil, fmt.Errorf("failed to set up database and user: %v", err)
}

This approach reduces the number of round trips to the database and ensures that the setup is only performed if necessary.

devhaozi
devhaozi previously approved these changes Sep 20, 2024
Copy link
Member

@devhaozi devhaozi left a comment

Choose a reason for hiding this comment

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

LGTM

@hwbrzzl hwbrzzl merged commit 9e9c677 into master Sep 21, 2024
9 of 12 checks passed
@hwbrzzl hwbrzzl deleted the bowen/cancel-sqlserver branch September 21, 2024 08:01
This was referenced Sep 25, 2024
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.

2 participants