From 773ef6f33e9dca3abab11fa67cff91bf9ce2d82d Mon Sep 17 00:00:00 2001 From: kgala2 Date: Tue, 29 Apr 2025 15:08:26 -0700 Subject: [PATCH 1/9] chore: add JDBC MySQL MCP tests --- .ci/cloudbuild.yaml | 124 +++++++++++------- .github/workflows/tests.yml | 8 ++ ...JdbcMysqlJ8MCPIamAuthIntegrationTests.java | 99 ++++++++++++++ .../mysql/JdbcMysqlJ8MCPIntegrationTests.java | 98 ++++++++++++++ 4 files changed, 282 insertions(+), 47 deletions(-) create mode 100644 jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java create mode 100644 jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java diff --git a/.ci/cloudbuild.yaml b/.ci/cloudbuild.yaml index 4b5fc9dec..5b9a33219 100644 --- a/.ci/cloudbuild.yaml +++ b/.ci/cloudbuild.yaml @@ -18,57 +18,87 @@ steps: env: - "IP_TYPE=${_IP_TYPE}" - "JOB_TYPE=integration" - secretEnv: ["MYSQL_CONNECTION_NAME", "MYSQL_USER", "MYSQL_IAM_USER", "MYSQL_PASS", "MYSQL_DB", "POSTGRES_CONNECTION_NAME", "POSTGRES_USER", "POSTGRES_IAM_USER", "POSTGRES_PASS", "POSTGRES_DB", "POSTGRES_CAS_CONNECTION_NAME", "POSTGRES_CAS_PASS", "POSTGRES_CUSTOMER_CAS_CONNECTION_NAME", "POSTGRES_CUSTOMER_CAS_PASS", "POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME","POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME","SQLSERVER_CONNECTION_NAME", "SQLSERVER_USER", "SQLSERVER_PASS", "SQLSERVER_DB", "QUOTA_PROJECT", "IMPERSONATED_USER"] + secretEnv: + [ + "MYSQL_CONNECTION_NAME", + "MYSQL_USER", + "MYSQL_IAM_USER", + "MYSQL_PASS", + "MYSQL_DB", + "MYSQL_MCP_CONNECTION_NAME", + "MYSQL_MCP_PASS", + "POSTGRES_CONNECTION_NAME", + "POSTGRES_USER", + "POSTGRES_IAM_USER", + "POSTGRES_PASS", + "POSTGRES_DB", + "POSTGRES_CAS_CONNECTION_NAME", + "POSTGRES_CAS_PASS", + "POSTGRES_CUSTOMER_CAS_CONNECTION_NAME", + "POSTGRES_CUSTOMER_CAS_PASS", + "POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME", + "POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME", + "SQLSERVER_CONNECTION_NAME", + "SQLSERVER_USER", + "SQLSERVER_PASS", + "SQLSERVER_DB", + "QUOTA_PROJECT", + "IMPERSONATED_USER" + ] args: - "-c" - | ./.github/scripts/run_tests.sh -availableSecrets: - secretManager: - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_CONNECTION_NAME/versions/latest' - env: 'MYSQL_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_USER/versions/latest' - env: 'MYSQL_USER' - - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_MYSQL_IAM_USER/versions/latest' - env: 'MYSQL_IAM_USER' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_PASS/versions/latest' - env: 'MYSQL_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_DB/versions/latest' - env: 'MYSQL_DB' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CONNECTION_NAME/versions/latest' - env: 'POSTGRES_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_USER/versions/latest' - env: 'POSTGRES_USER' - - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_POSTGRES_IAM_USER/versions/latest' - env: 'POSTGRES_IAM_USER' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_PASS/versions/latest' - env: 'POSTGRES_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_DB/versions/latest' - env: 'POSTGRES_DB' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_CONNECTION_NAME/versions/latest' - env: 'POSTGRES_CAS_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_PASS/versions/latest' - env: 'POSTGRES_CAS_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_CONNECTION_NAME/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_CONNECTION_NAME/versions/latest' - env: 'SQLSERVER_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_USER/versions/latest' - env: 'SQLSERVER_USER' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_PASS/versions/latest' - env: 'SQLSERVER_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_DB/versions/latest' - env: 'SQLSERVER_DB' - - versionName: 'projects/$PROJECT_ID/secrets/QUOTA_PROJECT/versions/latest' - env: 'QUOTA_PROJECT' - - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_SA/versions/latest' - env: 'IMPERSONATED_USER' + availableSecrets: + secretManager: + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_CONNECTION_NAME/versions/latest' + env: 'MYSQL_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_USER/versions/latest' + env: 'MYSQL_USER' + - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_MYSQL_IAM_USER/versions/latest' + env: 'MYSQL_IAM_USER' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_PASS/versions/latest' + env: 'MYSQL_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_DB/versions/latest' + env: 'MYSQL_DB' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_MCP_CONNECTION_NAME/versions/latest' + env: 'MYSQL_MCP_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_MCP_PASS/versions/latest' + env: 'MYSQL_MCP_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CONNECTION_NAME/versions/latest' + env: 'POSTGRES_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_USER/versions/latest' + env: 'POSTGRES_USER' + - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_POSTGRES_IAM_USER/versions/latest' + env: 'POSTGRES_IAM_USER' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_PASS/versions/latest' + env: 'POSTGRES_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_DB/versions/latest' + env: 'POSTGRES_DB' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_CONNECTION_NAME/versions/latest' + env: 'POSTGRES_CAS_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_PASS/versions/latest' + env: 'POSTGRES_CAS_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_CONNECTION_NAME/versions/latest' + env: 'POSTGRES_CUSTOMER_CAS_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS/versions/latest' + env: 'POSTGRES_CUSTOMER_CAS_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME/versions/latest' + env: 'POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME/versions/latest' + env: 'POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_CONNECTION_NAME/versions/latest' + env: 'SQLSERVER_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_USER/versions/latest' + env: 'SQLSERVER_USER' + - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_PASS/versions/latest' + env: 'SQLSERVER_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_DB/versions/latest' + env: 'SQLSERVER_DB' + - versionName: 'projects/$PROJECT_ID/secrets/QUOTA_PROJECT/versions/latest' + env: 'QUOTA_PROJECT' + - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_SA/versions/latest' + env: 'IMPERSONATED_USER' substitutions: _MAVEN_VERSION: ${_VERSION} _IP_TYPE: ${_IP_TYPE} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5ad020ba9..f20b48693 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -130,6 +130,8 @@ jobs: MYSQL_USER:${{ vars.GOOGLE_CLOUD_PROJECT }}/MYSQL_USER MYSQL_PASS:${{ vars.GOOGLE_CLOUD_PROJECT }}/MYSQL_PASS MYSQL_DB:${{ vars.GOOGLE_CLOUD_PROJECT }}/MYSQL_DB + MYSQL_MCP_CONNECTION_NAME:${{ vars.GOOGLE_CLOUD_PROJECT}}/MYSQL_MCP_CONNECTION_NAME + MYSQL_MCP_PASS:${{ vars.GOOGLE_CLOUD_PROJECT}}/MYSQL_MCP_PASS MYSQL_IAM_USER_JAVA:${{ vars.GOOGLE_CLOUD_PROJECT }}/MYSQL_USER_IAM_JAVA POSTGRES_CONNECTION_NAME:${{ vars.GOOGLE_CLOUD_PROJECT }}/POSTGRES_CONNECTION_NAME POSTGRES_USER:${{ vars.GOOGLE_CLOUD_PROJECT }}/POSTGRES_USER @@ -154,6 +156,8 @@ jobs: MYSQL_USER: "${{ steps.secrets.outputs.MYSQL_USER }}" MYSQL_PASS: "${{ steps.secrets.outputs.MYSQL_PASS }}" MYSQL_DB: "${{ steps.secrets.outputs.MYSQL_DB }}" + MYSQL_MCP_CONNECTION_NAME: "${{ steps.secrets.outputs.MYSQL_MCP_CONNECTION_NAME }}" + MYSQL_MCP_PASS: "${{ steps.secrets.outputs.MYSQL_MCP_PASS }}" MYSQL_IAM_USER: "${{ steps.secrets.outputs.MYSQL_IAM_USER_JAVA }}" POSTGRES_CONNECTION_NAME: "${{ steps.secrets.outputs.POSTGRES_CONNECTION_NAME }}" POSTGRES_USER: "${{ steps.secrets.outputs.POSTGRES_USER }}" @@ -237,6 +241,8 @@ jobs: MYSQL_USER:${{ vars.GOOGLE_CLOUD_PROJECT }}/MYSQL_USER MYSQL_PASS:${{ vars.GOOGLE_CLOUD_PROJECT }}/MYSQL_PASS MYSQL_DB:${{ vars.GOOGLE_CLOUD_PROJECT }}/MYSQL_DB + MYSQL_MCP_CONNECTION_NAME:${{ vars.GOOGLE_CLOUD_PROJECT}}/MYSQL_MCP_CONNECTION_NAME + MYSQL_MCP_PASS:${{ vars.GOOGLE_CLOUD_PROJECT}}/MYSQL_MCP_PASS MYSQL_IAM_USER_JAVA:${{ vars.GOOGLE_CLOUD_PROJECT }}/MYSQL_USER_IAM_JAVA POSTGRES_CONNECTION_NAME:${{ vars.GOOGLE_CLOUD_PROJECT }}/POSTGRES_CONNECTION_NAME POSTGRES_USER:${{ vars.GOOGLE_CLOUD_PROJECT }}/POSTGRES_USER @@ -262,6 +268,8 @@ jobs: MYSQL_USER: "${{ steps.secrets.outputs.MYSQL_USER }}" MYSQL_PASS: "${{ steps.secrets.outputs.MYSQL_PASS }}" MYSQL_DB: "${{ steps.secrets.outputs.MYSQL_DB }}" + MYSQL_MCP_CONNECTION_NAME: "${{ steps.secrets.outputs.MYSQL_MCP_CONNECTION_NAME }}" + MYSQL_MCP_PASS: "${{ steps.secrets.outputs.MYSQL_MCP_PASS }}" MYSQL_IAM_USER: "${{ steps.secrets.outputs.MYSQL_IAM_USER_JAVA }}" POSTGRES_CONNECTION_NAME: "${{ steps.secrets.outputs.POSTGRES_CONNECTION_NAME }}" POSTGRES_USER: "${{ steps.secrets.outputs.POSTGRES_USER }}" diff --git a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java new file mode 100644 index 000000000..5de1d2695 --- /dev/null +++ b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java @@ -0,0 +1,99 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.sql.mysql; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.common.collect.ImmutableList; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class JdbcMysqlJ8MCPIamAuthIntegrationTests { + + private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); + private static final String DB_NAME = System.getenv("MYSQL_DB"); + private static final String DB_USER = System.getenv("MYSQL_IAM_USER"); + private static final String IP_TYPE = + System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); + + private static final ImmutableList requiredEnvVars = + ImmutableList.of("MYSQL_IAM_USER", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); + @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); + private HikariDataSource connectionPool; + + @BeforeClass + public static void checkEnvVars() { + // Check that required env vars are set + requiredEnvVars.forEach( + (varName) -> + assertWithMessage( + String.format( + "Environment variable '%s' must be set to perform these tests.", varName)) + .that(System.getenv(varName)) + .isNotEmpty()); + } + + @Before + public void setUpPool() throws SQLException { + // Set up URL parameters + String jdbcURL = String.format("jdbc:mysql:///%s", DB_NAME); + Properties connProps = new Properties(); + connProps.setProperty("user", DB_USER); + connProps.setProperty("sslmode", "disable"); + connProps.setProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory"); + connProps.setProperty("cloudSqlInstance", CONNECTION_NAME); + connProps.setProperty("ipTypes", IP_TYPE); + connProps.setProperty("enableIamAuth", "true"); + + // Initialize connection pool + HikariConfig config = new HikariConfig(); + config.setJdbcUrl(jdbcURL); + config.setDataSourceProperties(connProps); + config.setConnectionTimeout(10000); // 10s + + this.connectionPool = new HikariDataSource(config); + } + + @Test + public void pooledConnectionTest() throws SQLException { + + List rows = new ArrayList<>(); + try (Connection conn = connectionPool.getConnection()) { + try (PreparedStatement selectStmt = conn.prepareStatement("SELECT NOW() as TS")) { + ResultSet rs = selectStmt.executeQuery(); + while (rs.next()) { + rows.add(rs.getTimestamp("TS")); + } + } + } + assertThat(rows.size()).isEqualTo(1); + } +} diff --git a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java new file mode 100644 index 000000000..64acac39c --- /dev/null +++ b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java @@ -0,0 +1,98 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.sql.mysql; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.common.collect.ImmutableList; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class JdbcMysqlJ8MCPIntegrationTests { + + private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); + private static final String DB_NAME = System.getenv("MYSQL_DB"); + private static final String DB_USER = System.getenv("MYSQL_USER"); + private static final String DB_PASSWORD = System.getenv("MYSQL_MCP_PASS"); + private static final String IP_TYPE = + System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); + private static final ImmutableList requiredEnvVars = + ImmutableList.of("MYSQL_USER", "MYSQL_MCP_PASS", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); + @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); + private HikariDataSource connectionPool; + + @BeforeClass + public static void checkEnvVars() { + // Check that required env vars are set + requiredEnvVars.forEach( + (varName) -> + assertWithMessage( + String.format( + "Environment variable '%s' must be set to perform these tests.", varName)) + .that(System.getenv(varName)) + .isNotEmpty()); + } + + @Before + public void setUpPool() throws SQLException { + // Set up URL parameters + String jdbcURL = String.format("jdbc:mysql://db.example.com/%s", DB_NAME); + Properties connProps = new Properties(); + connProps.setProperty("user", DB_USER); + connProps.setProperty("password", DB_PASSWORD); + connProps.setProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory"); + connProps.setProperty("ipTypes", IP_TYPE); + connProps.setProperty("cloudSqlInstance", CONNECTION_NAME); + + // Initialize connection pool + HikariConfig config = new HikariConfig(); + config.setJdbcUrl(jdbcURL); + config.setDataSourceProperties(connProps); + config.setConnectionTimeout(10000); // 10s + + this.connectionPool = new HikariDataSource(config); + } + + @Test + public void pooledConnectionTest() throws SQLException { + + List rows = new ArrayList<>(); + try (Connection conn = connectionPool.getConnection()) { + try (PreparedStatement selectStmt = conn.prepareStatement("SELECT NOW() as TS")) { + ResultSet rs = selectStmt.executeQuery(); + while (rs.next()) { + rows.add(rs.getTimestamp("TS")); + } + } + } + assertThat(rows.size()).isEqualTo(1); + } +} From 9b23c56dd5bfec13fefda5e03ee8dfaa95200b4e Mon Sep 17 00:00:00 2001 From: kgala2 Date: Tue, 29 Apr 2025 15:12:02 -0700 Subject: [PATCH 2/9] chore: reactor available secrests section of cloudbuild file --- .ci/cloudbuild.yaml | 100 ++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/.ci/cloudbuild.yaml b/.ci/cloudbuild.yaml index 5b9a33219..3176771e9 100644 --- a/.ci/cloudbuild.yaml +++ b/.ci/cloudbuild.yaml @@ -49,56 +49,56 @@ steps: - "-c" - | ./.github/scripts/run_tests.sh - availableSecrets: - secretManager: - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_CONNECTION_NAME/versions/latest' - env: 'MYSQL_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_USER/versions/latest' - env: 'MYSQL_USER' - - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_MYSQL_IAM_USER/versions/latest' - env: 'MYSQL_IAM_USER' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_PASS/versions/latest' - env: 'MYSQL_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_DB/versions/latest' - env: 'MYSQL_DB' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_MCP_CONNECTION_NAME/versions/latest' - env: 'MYSQL_MCP_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_MCP_PASS/versions/latest' - env: 'MYSQL_MCP_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CONNECTION_NAME/versions/latest' - env: 'POSTGRES_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_USER/versions/latest' - env: 'POSTGRES_USER' - - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_POSTGRES_IAM_USER/versions/latest' - env: 'POSTGRES_IAM_USER' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_PASS/versions/latest' - env: 'POSTGRES_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_DB/versions/latest' - env: 'POSTGRES_DB' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_CONNECTION_NAME/versions/latest' - env: 'POSTGRES_CAS_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_PASS/versions/latest' - env: 'POSTGRES_CAS_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_CONNECTION_NAME/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_CONNECTION_NAME/versions/latest' - env: 'SQLSERVER_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_USER/versions/latest' - env: 'SQLSERVER_USER' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_PASS/versions/latest' - env: 'SQLSERVER_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_DB/versions/latest' - env: 'SQLSERVER_DB' - - versionName: 'projects/$PROJECT_ID/secrets/QUOTA_PROJECT/versions/latest' - env: 'QUOTA_PROJECT' - - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_SA/versions/latest' - env: 'IMPERSONATED_USER' +availableSecrets: + secretManager: + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_CONNECTION_NAME/versions/latest' + env: 'MYSQL_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_USER/versions/latest' + env: 'MYSQL_USER' + - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_MYSQL_IAM_USER/versions/latest' + env: 'MYSQL_IAM_USER' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_PASS/versions/latest' + env: 'MYSQL_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_DB/versions/latest' + env: 'MYSQL_DB' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_MCP_CONNECTION_NAME/versions/latest' + env: 'MYSQL_MCP_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_MCP_PASS/versions/latest' + env: 'MYSQL_MCP_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CONNECTION_NAME/versions/latest' + env: 'POSTGRES_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_USER/versions/latest' + env: 'POSTGRES_USER' + - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_POSTGRES_IAM_USER/versions/latest' + env: 'POSTGRES_IAM_USER' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_PASS/versions/latest' + env: 'POSTGRES_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_DB/versions/latest' + env: 'POSTGRES_DB' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_CONNECTION_NAME/versions/latest' + env: 'POSTGRES_CAS_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_PASS/versions/latest' + env: 'POSTGRES_CAS_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_CONNECTION_NAME/versions/latest' + env: 'POSTGRES_CUSTOMER_CAS_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS/versions/latest' + env: 'POSTGRES_CUSTOMER_CAS_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME/versions/latest' + env: 'POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME/versions/latest' + env: 'POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_CONNECTION_NAME/versions/latest' + env: 'SQLSERVER_CONNECTION_NAME' + - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_USER/versions/latest' + env: 'SQLSERVER_USER' + - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_PASS/versions/latest' + env: 'SQLSERVER_PASS' + - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_DB/versions/latest' + env: 'SQLSERVER_DB' + - versionName: 'projects/$PROJECT_ID/secrets/QUOTA_PROJECT/versions/latest' + env: 'QUOTA_PROJECT' + - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_SA/versions/latest' + env: 'IMPERSONATED_USER' substitutions: _MAVEN_VERSION: ${_VERSION} _IP_TYPE: ${_IP_TYPE} From b655bd2cc17226ba952f3703ab3504fa66ded7aa Mon Sep 17 00:00:00 2001 From: kgala2 Date: Tue, 29 Apr 2025 15:26:32 -0700 Subject: [PATCH 3/9] chore: change ' to " --- .ci/cloudbuild.yaml | 96 ++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/.ci/cloudbuild.yaml b/.ci/cloudbuild.yaml index 3176771e9..cdc0886f4 100644 --- a/.ci/cloudbuild.yaml +++ b/.ci/cloudbuild.yaml @@ -51,54 +51,54 @@ steps: ./.github/scripts/run_tests.sh availableSecrets: secretManager: - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_CONNECTION_NAME/versions/latest' - env: 'MYSQL_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_USER/versions/latest' - env: 'MYSQL_USER' - - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_MYSQL_IAM_USER/versions/latest' - env: 'MYSQL_IAM_USER' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_PASS/versions/latest' - env: 'MYSQL_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_DB/versions/latest' - env: 'MYSQL_DB' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_MCP_CONNECTION_NAME/versions/latest' - env: 'MYSQL_MCP_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/MYSQL_MCP_PASS/versions/latest' - env: 'MYSQL_MCP_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CONNECTION_NAME/versions/latest' - env: 'POSTGRES_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_USER/versions/latest' - env: 'POSTGRES_USER' - - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_POSTGRES_IAM_USER/versions/latest' - env: 'POSTGRES_IAM_USER' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_PASS/versions/latest' - env: 'POSTGRES_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_DB/versions/latest' - env: 'POSTGRES_DB' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_CONNECTION_NAME/versions/latest' - env: 'POSTGRES_CAS_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CAS_PASS/versions/latest' - env: 'POSTGRES_CAS_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_CONNECTION_NAME/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME/versions/latest' - env: 'POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_CONNECTION_NAME/versions/latest' - env: 'SQLSERVER_CONNECTION_NAME' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_USER/versions/latest' - env: 'SQLSERVER_USER' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_PASS/versions/latest' - env: 'SQLSERVER_PASS' - - versionName: 'projects/$PROJECT_ID/secrets/SQLSERVER_DB/versions/latest' - env: 'SQLSERVER_DB' - - versionName: 'projects/$PROJECT_ID/secrets/QUOTA_PROJECT/versions/latest' - env: 'QUOTA_PROJECT' - - versionName: 'projects/$PROJECT_ID/secrets/CLOUD_BUILD_SA/versions/latest' - env: 'IMPERSONATED_USER' + - versionName: "projects/$PROJECT_ID/secrets/MYSQL_CONNECTION_NAME/versions/latest" + env: "MYSQL_CONNECTION_NAME" + - versionName: "projects/$PROJECT_ID/secrets/MYSQL_USER/versions/latest" + env: "MYSQL_USER" + - versionName: "projects/$PROJECT_ID/secrets/CLOUD_BUILD_MYSQL_IAM_USER/versions/latest" + env: "MYSQL_IAM_USER" + - versionName: "projects/$PROJECT_ID/secrets/MYSQL_PASS/versions/latest" + env: "MYSQL_PASS" + - versionName: "projects/$PROJECT_ID/secrets/MYSQL_DB/versions/latest" + env: "MYSQL_DB" + - versionName: "projects/$PROJECT_ID/secrets/MYSQL_MCP_CONNECTION_NAME/versions/latest" + env: "MYSQL_MCP_CONNECTION_NAME" + - versionName: "projects/$PROJECT_ID/secrets/MYSQL_MCP_PASS/versions/latest" + env: "MYSQL_MCP_PASS" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_CONNECTION_NAME/versions/latest" + env: "POSTGRES_CONNECTION_NAME" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_USER/versions/latest" + env: "POSTGRES_USER" + - versionName: "projects/$PROJECT_ID/secrets/CLOUD_BUILD_POSTGRES_IAM_USER/versions/latest" + env: "POSTGRES_IAM_USER" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_PASS/versions/latest" + env: "POSTGRES_PASS" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_DB/versions/latest" + env: "POSTGRES_DB" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_CAS_CONNECTION_NAME/versions/latest" + env: "POSTGRES_CAS_CONNECTION_NAME" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_CAS_PASS/versions/latest" + env: "POSTGRES_CAS_PASS" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_CONNECTION_NAME/versions/latest" + env: "POSTGRES_CUSTOMER_CAS_CONNECTION_NAME" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS/versions/latest" + env: "POSTGRES_CUSTOMER_CAS_PASS" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME/versions/latest" + env: "POSTGRES_CUSTOMER_CAS_PASS_VALID_DOMAIN_NAME" + - versionName: "projects/$PROJECT_ID/secrets/POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME/versions/latest" + env: "POSTGRES_CUSTOMER_CAS_PASS_INVALID_DOMAIN_NAME" + - versionName: "projects/$PROJECT_ID/secrets/SQLSERVER_CONNECTION_NAME/versions/latest" + env: "SQLSERVER_CONNECTION_NAME" + - versionName: "projects/$PROJECT_ID/secrets/SQLSERVER_USER/versions/latest" + env: "SQLSERVER_USER" + - versionName: "projects/$PROJECT_ID/secrets/SQLSERVER_PASS/versions/latest" + env: "SQLSERVER_PASS" + - versionName: "projects/$PROJECT_ID/secrets/SQLSERVER_DB/versions/latest" + env: "SQLSERVER_DB" + - versionName: "projects/$PROJECT_ID/secrets/QUOTA_PROJECT/versions/latest" + env: "QUOTA_PROJECT" + - versionName: "projects/$PROJECT_ID/secrets/CLOUD_BUILD_SA/versions/latest" + env: "IMPERSONATED_USER" substitutions: _MAVEN_VERSION: ${_VERSION} _IP_TYPE: ${_IP_TYPE} From 24bf89d9a91474df3f6803af822d26879677f655 Mon Sep 17 00:00:00 2001 From: kgala2 Date: Tue, 29 Apr 2025 16:02:09 -0700 Subject: [PATCH 4/9] chore: test R2DBC MySQL MCP tests --- .../R2dbcMysqlMCPIamAuthIntegrationTests.java | 107 ++++++++++++++++++ .../core/R2dbcMysqlMCPIntegrationTests.java | 91 +++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIamAuthIntegrationTests.java create mode 100644 r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIntegrationTests.java diff --git a/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIamAuthIntegrationTests.java b/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIamAuthIntegrationTests.java new file mode 100644 index 000000000..ead29aa2d --- /dev/null +++ b/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIamAuthIntegrationTests.java @@ -0,0 +1,107 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.sql.core; + +import static com.google.cloud.sql.core.GcpConnectionFactoryProvider.ENABLE_IAM_AUTH; +import static com.google.cloud.sql.core.GcpConnectionFactoryProvider.IP_TYPES; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static io.r2dbc.spi.ConnectionFactoryOptions.DATABASE; +import static io.r2dbc.spi.ConnectionFactoryOptions.DRIVER; +import static io.r2dbc.spi.ConnectionFactoryOptions.HOST; +import static io.r2dbc.spi.ConnectionFactoryOptions.PROTOCOL; +import static io.r2dbc.spi.ConnectionFactoryOptions.USER; + +import com.google.common.collect.ImmutableList; +import io.r2dbc.pool.ConnectionPool; +import io.r2dbc.pool.ConnectionPoolConfiguration; +import io.r2dbc.spi.ConnectionFactories; +import io.r2dbc.spi.ConnectionFactory; +import io.r2dbc.spi.ConnectionFactoryOptions; +import java.time.Instant; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import reactor.core.publisher.Mono; + +@RunWith(JUnit4.class) +public class R2dbcMysqlMCPIamAuthIntegrationTests { + + private static final ImmutableList requiredEnvVars = + ImmutableList.of("MYSQL_IAM_USER", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); + + private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); + private static final String DB_NAME = System.getenv("MYSQL_DB"); + private static final String DB_USER = System.getenv("MYSQL_IAM_USER"); + private static final String IP_TYPE = + System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); + + @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); + + private ConnectionPool connectionPool; + + @Before + public void setUpPool() { + // Check that required env vars are set + requiredEnvVars.forEach( + (varName) -> + assertWithMessage( + String.format( + "Environment variable '%s' must be set to perform these tests.", varName)) + .that(System.getenv(varName)) + .isNotEmpty()); + + // [START cloud_sql_connector_mysql_r2dbc_iam_auth] + // Set up ConnectionFactoryOptions + ConnectionFactoryOptions options = + ConnectionFactoryOptions.builder() + .option(DRIVER, "gcp") + .option(PROTOCOL, "mysql") + .option(USER, DB_USER) + .option(DATABASE, DB_NAME) + .option(HOST, CONNECTION_NAME) + .option(IP_TYPES, IP_TYPE) + .option(ENABLE_IAM_AUTH, true) + .build(); + + // Initialize connection pool + ConnectionFactory connectionFactory = ConnectionFactories.get(options); + ConnectionPoolConfiguration configuration = + ConnectionPoolConfiguration.builder(connectionFactory).build(); + + this.connectionPool = new ConnectionPool(configuration); + // [END cloud_sql_connector_mysql_r2dbc_iam_auth] + + } + + @Test + public void pooledConnectionTest() { + List rows = + Mono.from(this.connectionPool.create()) + .flatMapMany(connection -> connection.createStatement("SELECT NOW() as TS").execute()) + .flatMap(result -> result.map((r, meta) -> r.get("TS", Instant.class))) + .collectList() + .block(); + + assertThat(rows.size()).isEqualTo(1); + } +} diff --git a/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIntegrationTests.java b/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIntegrationTests.java new file mode 100644 index 000000000..9868714cd --- /dev/null +++ b/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIntegrationTests.java @@ -0,0 +1,91 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.sql.core; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.common.collect.ImmutableList; +import io.r2dbc.pool.ConnectionPool; +import io.r2dbc.pool.ConnectionPoolConfiguration; +import io.r2dbc.spi.ConnectionFactories; +import io.r2dbc.spi.ConnectionFactory; +import java.time.Instant; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import reactor.core.publisher.Mono; + +@RunWith(JUnit4.class) +public class R2dbcMysqlMCPIntegrationTests { + + private static final ImmutableList requiredEnvVars = + ImmutableList.of("MYSQL_USER", "MYSQL_MCP_PASS", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); + + private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); + private static final String DB_NAME = System.getenv("MYSQL_DB"); + private static final String DB_USER = System.getenv("MYSQL_USER"); + private static final String DB_PASSWORD = System.getenv("MYSQL_MCP_PASS"); + private static final String IP_TYPE = + System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); + + @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); + + private ConnectionPool connectionPool; + + @Before + public void setUpPool() { + // Check that required env vars are set + requiredEnvVars.forEach( + (varName) -> + assertWithMessage( + String.format( + "Environment variable '%s' must be set to perform these tests.", varName)) + .that(System.getenv(varName)) + .isNotEmpty()); + + // Set up URL parameters + String r2dbcURL = + String.format( + "r2dbc:gcp:mysql://%s:%s@%s/%s?ipTypes=%s", + DB_USER, DB_PASSWORD, CONNECTION_NAME, DB_NAME, IP_TYPE); + + // Initialize connection pool + ConnectionFactory connectionFactory = ConnectionFactories.get(r2dbcURL); + ConnectionPoolConfiguration configuration = + ConnectionPoolConfiguration.builder(connectionFactory).build(); + + this.connectionPool = new ConnectionPool(configuration); + } + + @Test + public void pooledConnectionTest() { + List rows = + Mono.from(this.connectionPool.create()) + .flatMapMany(connection -> connection.createStatement("SELECT NOW() as TS").execute()) + .flatMap(result -> result.map((r, meta) -> r.get("TS", Instant.class))) + .collectList() + .block(); + + assertThat(rows.size()).isEqualTo(1); + } +} From 5c4b3586bf5da492f3581b7a3aaaaa578f098713 Mon Sep 17 00:00:00 2001 From: kgala2 Date: Tue, 29 Apr 2025 16:10:12 -0700 Subject: [PATCH 5/9] chore: remove R2DBC tests --- .../R2dbcMysqlMCPIamAuthIntegrationTests.java | 107 ------------------ .../core/R2dbcMysqlMCPIntegrationTests.java | 91 --------------- 2 files changed, 198 deletions(-) delete mode 100644 r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIamAuthIntegrationTests.java delete mode 100644 r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIntegrationTests.java diff --git a/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIamAuthIntegrationTests.java b/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIamAuthIntegrationTests.java deleted file mode 100644 index ead29aa2d..000000000 --- a/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIamAuthIntegrationTests.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.sql.core; - -import static com.google.cloud.sql.core.GcpConnectionFactoryProvider.ENABLE_IAM_AUTH; -import static com.google.cloud.sql.core.GcpConnectionFactoryProvider.IP_TYPES; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; -import static io.r2dbc.spi.ConnectionFactoryOptions.DATABASE; -import static io.r2dbc.spi.ConnectionFactoryOptions.DRIVER; -import static io.r2dbc.spi.ConnectionFactoryOptions.HOST; -import static io.r2dbc.spi.ConnectionFactoryOptions.PROTOCOL; -import static io.r2dbc.spi.ConnectionFactoryOptions.USER; - -import com.google.common.collect.ImmutableList; -import io.r2dbc.pool.ConnectionPool; -import io.r2dbc.pool.ConnectionPoolConfiguration; -import io.r2dbc.spi.ConnectionFactories; -import io.r2dbc.spi.ConnectionFactory; -import io.r2dbc.spi.ConnectionFactoryOptions; -import java.time.Instant; -import java.util.List; -import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.Timeout; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import reactor.core.publisher.Mono; - -@RunWith(JUnit4.class) -public class R2dbcMysqlMCPIamAuthIntegrationTests { - - private static final ImmutableList requiredEnvVars = - ImmutableList.of("MYSQL_IAM_USER", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); - - private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); - private static final String DB_NAME = System.getenv("MYSQL_DB"); - private static final String DB_USER = System.getenv("MYSQL_IAM_USER"); - private static final String IP_TYPE = - System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); - - @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); - - private ConnectionPool connectionPool; - - @Before - public void setUpPool() { - // Check that required env vars are set - requiredEnvVars.forEach( - (varName) -> - assertWithMessage( - String.format( - "Environment variable '%s' must be set to perform these tests.", varName)) - .that(System.getenv(varName)) - .isNotEmpty()); - - // [START cloud_sql_connector_mysql_r2dbc_iam_auth] - // Set up ConnectionFactoryOptions - ConnectionFactoryOptions options = - ConnectionFactoryOptions.builder() - .option(DRIVER, "gcp") - .option(PROTOCOL, "mysql") - .option(USER, DB_USER) - .option(DATABASE, DB_NAME) - .option(HOST, CONNECTION_NAME) - .option(IP_TYPES, IP_TYPE) - .option(ENABLE_IAM_AUTH, true) - .build(); - - // Initialize connection pool - ConnectionFactory connectionFactory = ConnectionFactories.get(options); - ConnectionPoolConfiguration configuration = - ConnectionPoolConfiguration.builder(connectionFactory).build(); - - this.connectionPool = new ConnectionPool(configuration); - // [END cloud_sql_connector_mysql_r2dbc_iam_auth] - - } - - @Test - public void pooledConnectionTest() { - List rows = - Mono.from(this.connectionPool.create()) - .flatMapMany(connection -> connection.createStatement("SELECT NOW() as TS").execute()) - .flatMap(result -> result.map((r, meta) -> r.get("TS", Instant.class))) - .collectList() - .block(); - - assertThat(rows.size()).isEqualTo(1); - } -} diff --git a/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIntegrationTests.java b/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIntegrationTests.java deleted file mode 100644 index 9868714cd..000000000 --- a/r2dbc/mysql/src/test/java/com/google/cloud/sql/core/R2dbcMysqlMCPIntegrationTests.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.sql.core; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; - -import com.google.common.collect.ImmutableList; -import io.r2dbc.pool.ConnectionPool; -import io.r2dbc.pool.ConnectionPoolConfiguration; -import io.r2dbc.spi.ConnectionFactories; -import io.r2dbc.spi.ConnectionFactory; -import java.time.Instant; -import java.util.List; -import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.Timeout; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import reactor.core.publisher.Mono; - -@RunWith(JUnit4.class) -public class R2dbcMysqlMCPIntegrationTests { - - private static final ImmutableList requiredEnvVars = - ImmutableList.of("MYSQL_USER", "MYSQL_MCP_PASS", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); - - private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); - private static final String DB_NAME = System.getenv("MYSQL_DB"); - private static final String DB_USER = System.getenv("MYSQL_USER"); - private static final String DB_PASSWORD = System.getenv("MYSQL_MCP_PASS"); - private static final String IP_TYPE = - System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); - - @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); - - private ConnectionPool connectionPool; - - @Before - public void setUpPool() { - // Check that required env vars are set - requiredEnvVars.forEach( - (varName) -> - assertWithMessage( - String.format( - "Environment variable '%s' must be set to perform these tests.", varName)) - .that(System.getenv(varName)) - .isNotEmpty()); - - // Set up URL parameters - String r2dbcURL = - String.format( - "r2dbc:gcp:mysql://%s:%s@%s/%s?ipTypes=%s", - DB_USER, DB_PASSWORD, CONNECTION_NAME, DB_NAME, IP_TYPE); - - // Initialize connection pool - ConnectionFactory connectionFactory = ConnectionFactories.get(r2dbcURL); - ConnectionPoolConfiguration configuration = - ConnectionPoolConfiguration.builder(connectionFactory).build(); - - this.connectionPool = new ConnectionPool(configuration); - } - - @Test - public void pooledConnectionTest() { - List rows = - Mono.from(this.connectionPool.create()) - .flatMapMany(connection -> connection.createStatement("SELECT NOW() as TS").execute()) - .flatMap(result -> result.map((r, meta) -> r.get("TS", Instant.class))) - .collectList() - .block(); - - assertThat(rows.size()).isEqualTo(1); - } -} From 3709d38d42e9d91164651cbf3e69c78ec6aead53 Mon Sep 17 00:00:00 2001 From: kgala2 Date: Wed, 30 Apr 2025 09:48:01 -0700 Subject: [PATCH 6/9] chore: rename Java class --- .../cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java | 2 +- .../google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java index 5de1d2695..a0c119fbd 100644 --- a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java +++ b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java @@ -36,7 +36,7 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) -public class JdbcMysqlJ8MCPIamAuthIntegrationTests { +public class JdbcMysqlJ8McpIamAuthIntegrationTests { private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); private static final String DB_NAME = System.getenv("MYSQL_DB"); diff --git a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java index 64acac39c..3b6b00481 100644 --- a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java +++ b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java @@ -36,7 +36,7 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) -public class JdbcMysqlJ8MCPIntegrationTests { +public class JdbcMysqlJ8McpIntegrationTests { private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); private static final String DB_NAME = System.getenv("MYSQL_DB"); From 471ff184620a544cdc0fbe971f7c48add12363c2 Mon Sep 17 00:00:00 2001 From: kgala2 Date: Wed, 30 Apr 2025 09:56:41 -0700 Subject: [PATCH 7/9] chore: udpate ignorecase config to change MCP to Mcp --- ...JdbcMysqlJ8McpIamAuthIntegrationTests.java | 99 +++++++++++++++++++ .../mysql/JdbcMysqlJ8McpIntegrationTests.java | 98 ++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8McpIamAuthIntegrationTests.java create mode 100644 jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8McpIntegrationTests.java diff --git a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8McpIamAuthIntegrationTests.java b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8McpIamAuthIntegrationTests.java new file mode 100644 index 000000000..a0c119fbd --- /dev/null +++ b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8McpIamAuthIntegrationTests.java @@ -0,0 +1,99 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.sql.mysql; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.common.collect.ImmutableList; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class JdbcMysqlJ8McpIamAuthIntegrationTests { + + private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); + private static final String DB_NAME = System.getenv("MYSQL_DB"); + private static final String DB_USER = System.getenv("MYSQL_IAM_USER"); + private static final String IP_TYPE = + System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); + + private static final ImmutableList requiredEnvVars = + ImmutableList.of("MYSQL_IAM_USER", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); + @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); + private HikariDataSource connectionPool; + + @BeforeClass + public static void checkEnvVars() { + // Check that required env vars are set + requiredEnvVars.forEach( + (varName) -> + assertWithMessage( + String.format( + "Environment variable '%s' must be set to perform these tests.", varName)) + .that(System.getenv(varName)) + .isNotEmpty()); + } + + @Before + public void setUpPool() throws SQLException { + // Set up URL parameters + String jdbcURL = String.format("jdbc:mysql:///%s", DB_NAME); + Properties connProps = new Properties(); + connProps.setProperty("user", DB_USER); + connProps.setProperty("sslmode", "disable"); + connProps.setProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory"); + connProps.setProperty("cloudSqlInstance", CONNECTION_NAME); + connProps.setProperty("ipTypes", IP_TYPE); + connProps.setProperty("enableIamAuth", "true"); + + // Initialize connection pool + HikariConfig config = new HikariConfig(); + config.setJdbcUrl(jdbcURL); + config.setDataSourceProperties(connProps); + config.setConnectionTimeout(10000); // 10s + + this.connectionPool = new HikariDataSource(config); + } + + @Test + public void pooledConnectionTest() throws SQLException { + + List rows = new ArrayList<>(); + try (Connection conn = connectionPool.getConnection()) { + try (PreparedStatement selectStmt = conn.prepareStatement("SELECT NOW() as TS")) { + ResultSet rs = selectStmt.executeQuery(); + while (rs.next()) { + rows.add(rs.getTimestamp("TS")); + } + } + } + assertThat(rows.size()).isEqualTo(1); + } +} diff --git a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8McpIntegrationTests.java b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8McpIntegrationTests.java new file mode 100644 index 000000000..3b6b00481 --- /dev/null +++ b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8McpIntegrationTests.java @@ -0,0 +1,98 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.sql.mysql; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.common.collect.ImmutableList; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class JdbcMysqlJ8McpIntegrationTests { + + private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); + private static final String DB_NAME = System.getenv("MYSQL_DB"); + private static final String DB_USER = System.getenv("MYSQL_USER"); + private static final String DB_PASSWORD = System.getenv("MYSQL_MCP_PASS"); + private static final String IP_TYPE = + System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); + private static final ImmutableList requiredEnvVars = + ImmutableList.of("MYSQL_USER", "MYSQL_MCP_PASS", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); + @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); + private HikariDataSource connectionPool; + + @BeforeClass + public static void checkEnvVars() { + // Check that required env vars are set + requiredEnvVars.forEach( + (varName) -> + assertWithMessage( + String.format( + "Environment variable '%s' must be set to perform these tests.", varName)) + .that(System.getenv(varName)) + .isNotEmpty()); + } + + @Before + public void setUpPool() throws SQLException { + // Set up URL parameters + String jdbcURL = String.format("jdbc:mysql://db.example.com/%s", DB_NAME); + Properties connProps = new Properties(); + connProps.setProperty("user", DB_USER); + connProps.setProperty("password", DB_PASSWORD); + connProps.setProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory"); + connProps.setProperty("ipTypes", IP_TYPE); + connProps.setProperty("cloudSqlInstance", CONNECTION_NAME); + + // Initialize connection pool + HikariConfig config = new HikariConfig(); + config.setJdbcUrl(jdbcURL); + config.setDataSourceProperties(connProps); + config.setConnectionTimeout(10000); // 10s + + this.connectionPool = new HikariDataSource(config); + } + + @Test + public void pooledConnectionTest() throws SQLException { + + List rows = new ArrayList<>(); + try (Connection conn = connectionPool.getConnection()) { + try (PreparedStatement selectStmt = conn.prepareStatement("SELECT NOW() as TS")) { + ResultSet rs = selectStmt.executeQuery(); + while (rs.next()) { + rows.add(rs.getTimestamp("TS")); + } + } + } + assertThat(rows.size()).isEqualTo(1); + } +} From b263f5d6d8d9b04918d5c12dbeec4677e7f7dbdc Mon Sep 17 00:00:00 2001 From: kgala2 Date: Wed, 30 Apr 2025 09:59:51 -0700 Subject: [PATCH 8/9] Delete jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java --- ...JdbcMysqlJ8MCPIamAuthIntegrationTests.java | 99 ------------------- 1 file changed, 99 deletions(-) delete mode 100644 jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java diff --git a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java deleted file mode 100644 index a0c119fbd..000000000 --- a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIamAuthIntegrationTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.sql.mysql; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; - -import com.google.common.collect.ImmutableList; -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import java.sql.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.Timeout; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class JdbcMysqlJ8McpIamAuthIntegrationTests { - - private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); - private static final String DB_NAME = System.getenv("MYSQL_DB"); - private static final String DB_USER = System.getenv("MYSQL_IAM_USER"); - private static final String IP_TYPE = - System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); - - private static final ImmutableList requiredEnvVars = - ImmutableList.of("MYSQL_IAM_USER", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); - @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); - private HikariDataSource connectionPool; - - @BeforeClass - public static void checkEnvVars() { - // Check that required env vars are set - requiredEnvVars.forEach( - (varName) -> - assertWithMessage( - String.format( - "Environment variable '%s' must be set to perform these tests.", varName)) - .that(System.getenv(varName)) - .isNotEmpty()); - } - - @Before - public void setUpPool() throws SQLException { - // Set up URL parameters - String jdbcURL = String.format("jdbc:mysql:///%s", DB_NAME); - Properties connProps = new Properties(); - connProps.setProperty("user", DB_USER); - connProps.setProperty("sslmode", "disable"); - connProps.setProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory"); - connProps.setProperty("cloudSqlInstance", CONNECTION_NAME); - connProps.setProperty("ipTypes", IP_TYPE); - connProps.setProperty("enableIamAuth", "true"); - - // Initialize connection pool - HikariConfig config = new HikariConfig(); - config.setJdbcUrl(jdbcURL); - config.setDataSourceProperties(connProps); - config.setConnectionTimeout(10000); // 10s - - this.connectionPool = new HikariDataSource(config); - } - - @Test - public void pooledConnectionTest() throws SQLException { - - List rows = new ArrayList<>(); - try (Connection conn = connectionPool.getConnection()) { - try (PreparedStatement selectStmt = conn.prepareStatement("SELECT NOW() as TS")) { - ResultSet rs = selectStmt.executeQuery(); - while (rs.next()) { - rows.add(rs.getTimestamp("TS")); - } - } - } - assertThat(rows.size()).isEqualTo(1); - } -} From 53b3ee9ade755c4a4b698b083e2a0e2dc16bcdcf Mon Sep 17 00:00:00 2001 From: kgala2 Date: Wed, 30 Apr 2025 10:00:06 -0700 Subject: [PATCH 9/9] Delete jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java --- .../mysql/JdbcMysqlJ8MCPIntegrationTests.java | 98 ------------------- 1 file changed, 98 deletions(-) delete mode 100644 jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java diff --git a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java b/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java deleted file mode 100644 index 3b6b00481..000000000 --- a/jdbc/mysql-j-8/src/test/java/com/google/cloud/sql/mysql/JdbcMysqlJ8MCPIntegrationTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.cloud.sql.mysql; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; - -import com.google.common.collect.ImmutableList; -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import java.sql.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.Timeout; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class JdbcMysqlJ8McpIntegrationTests { - - private static final String CONNECTION_NAME = System.getenv("MYSQL_MCP_CONNECTION_NAME"); - private static final String DB_NAME = System.getenv("MYSQL_DB"); - private static final String DB_USER = System.getenv("MYSQL_USER"); - private static final String DB_PASSWORD = System.getenv("MYSQL_MCP_PASS"); - private static final String IP_TYPE = - System.getenv("IP_TYPE") == null ? "PUBLIC" : System.getenv("IP_TYPE"); - private static final ImmutableList requiredEnvVars = - ImmutableList.of("MYSQL_USER", "MYSQL_MCP_PASS", "MYSQL_DB", "MYSQL_MCP_CONNECTION_NAME"); - @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS); - private HikariDataSource connectionPool; - - @BeforeClass - public static void checkEnvVars() { - // Check that required env vars are set - requiredEnvVars.forEach( - (varName) -> - assertWithMessage( - String.format( - "Environment variable '%s' must be set to perform these tests.", varName)) - .that(System.getenv(varName)) - .isNotEmpty()); - } - - @Before - public void setUpPool() throws SQLException { - // Set up URL parameters - String jdbcURL = String.format("jdbc:mysql://db.example.com/%s", DB_NAME); - Properties connProps = new Properties(); - connProps.setProperty("user", DB_USER); - connProps.setProperty("password", DB_PASSWORD); - connProps.setProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory"); - connProps.setProperty("ipTypes", IP_TYPE); - connProps.setProperty("cloudSqlInstance", CONNECTION_NAME); - - // Initialize connection pool - HikariConfig config = new HikariConfig(); - config.setJdbcUrl(jdbcURL); - config.setDataSourceProperties(connProps); - config.setConnectionTimeout(10000); // 10s - - this.connectionPool = new HikariDataSource(config); - } - - @Test - public void pooledConnectionTest() throws SQLException { - - List rows = new ArrayList<>(); - try (Connection conn = connectionPool.getConnection()) { - try (PreparedStatement selectStmt = conn.prepareStatement("SELECT NOW() as TS")) { - ResultSet rs = selectStmt.executeQuery(); - while (rs.next()) { - rows.add(rs.getTimestamp("TS")); - } - } - } - assertThat(rows.size()).isEqualTo(1); - } -}