Skip to content

test(bigquery-jdbc): do not merge#13528

Open
Neenu1995 wants to merge 1 commit into
mainfrom
test-job-cacellation
Open

test(bigquery-jdbc): do not merge#13528
Neenu1995 wants to merge 1 commit into
mainfrom
test-job-cacellation

Conversation

@Neenu1995

Copy link
Copy Markdown
Contributor

No description provided.

@Neenu1995 Neenu1995 requested review from a team as code owners June 19, 2026 17:04

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new integration test, testCancelLocation, to verify query cancellation functionality in the BigQuery JDBC driver. The review feedback highlights that the Connection, Statement, and ExecutorService resources are not closed in an exception-safe manner, which could lead to resource leaks if assertions fail or exceptions are thrown. It is recommended to use try-with-resources and a finally block to ensure proper resource cleanup.

Comment on lines +414 to +455
public void testCancelLocation() throws Exception {
String connection_uri =
"jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;PROJECTID="
+ PROJECT_ID
+ ";OAUTHTYPE=3;LOCATION=EU";

Driver driver = BigQueryDriver.getRegisteredDriver();
Connection connection = driver.connect(connection_uri, new Properties());
Statement statement = connection.createStatement();

// Query a dataset in the EU with a heavy query so that we can cancel it while it runs.
String query =
"SELECT COUNT(*) FROM `bigquery-public-data.covid19_italy_eu.data_by_province` a "
+ "CROSS JOIN `bigquery-public-data.covid19_italy_eu.data_by_province` b "
+ "CROSS JOIN `bigquery-public-data.covid19_italy_eu.data_by_province` c";

// Run the query in a separate thread so we can cancel it from the main thread
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<SQLException> future = executor.submit(() -> {
try {
statement.executeQuery(query);
return null;
} catch (SQLException e) {
return e;
}
});

// Wait a short moment to let the query submit and start running
Thread.sleep(1500);

// Cancel the query execution
statement.cancel();

// Verify that the query threw a SQLException indicating it was cancelled
SQLException exception = future.get(15, TimeUnit.SECONDS);
assertNotNull(exception, "Expected SQLException to be thrown due to cancellation");
assertTrue(exception.getMessage().contains("cancelled") || exception.getMessage().contains("Job was cancelled") || exception.getMessage().contains("Query was cancelled"),
"Unexpected exception message: " + exception.getMessage());

connection.close();
executor.shutdown();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The Connection, Statement, and ExecutorService resources are not closed in an exception-safe manner. If an assertion fails or an exception is thrown (e.g., during future.get()), the connection.close() and executor.shutdown() calls will be bypassed, leading to resource leaks. Use try-with-resources for the JDBC resources and a finally block to ensure the executor is shut down.

  @Test
  public void testCancelLocation() throws Exception {
    String connection_uri =
        "jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;PROJECTID="
            + PROJECT_ID
            + ";OAUTHTYPE=3;LOCATION=EU";

    Driver driver = BigQueryDriver.getRegisteredDriver();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    try (Connection connection = driver.connect(connection_uri, new Properties());
        Statement statement = connection.createStatement()) {

      // Query a dataset in the EU with a heavy query so that we can cancel it while it runs.
      String query =
          "SELECT COUNT(*) FROM bigquery_public_data.covid19_italy_eu.data_by_province a "
              + "CROSS JOIN bigquery_public_data.covid19_italy_eu.data_by_province b "
              + "CROSS JOIN bigquery_public_data.covid19_italy_eu.data_by_province c";

      // Run the query in a separate thread so we can cancel it from the main thread
      Future<SQLException> future = executor.submit(() -> {
        try {
          statement.executeQuery(query);
          return null;
        } catch (SQLException e) {
          return e;
        }
      });

      // Wait a short moment to let the query submit and start running
      Thread.sleep(1500);

      // Cancel the query execution
      statement.cancel();

      // Verify that the query threw a SQLException indicating it was cancelled
      SQLException exception = future.get(15, TimeUnit.SECONDS);
      assertNotNull(exception, "Expected SQLException to be thrown due to cancellation");
      assertTrue(exception.getMessage().contains("cancelled") || exception.getMessage().contains("Job was cancelled") || exception.getMessage().contains("Query was cancelled"),
          "Unexpected exception message: " + exception.getMessage());
    } finally {
      executor.shutdown();
    }
  }
References
  1. When managing a collection of closeable resources, ensure they are closed in the reverse order of their creation (LIFO). The implementation must be exception-safe to prevent resource leaks, meaning all opened resources should be closed even if exceptions occur during their creation or closing.

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