|
15 | 15 | """
|
16 | 16 |
|
17 | 17 | import asyncio
|
18 |
| -from mock import patch |
| 18 | +import pytest # noqa F401 Needed to run the tests |
19 | 19 | import datetime
|
20 | 20 | from google.cloud.sql.connector.rate_limiter import AsyncRateLimiter
|
21 |
| -import pytest # noqa F401 Needed to run the tests |
22 | 21 | from google.auth.credentials import Credentials
|
23 | 22 | from google.cloud.sql.connector.instance import (
|
24 | 23 | IPTypes,
|
|
28 | 27 | InstanceMetadata,
|
29 | 28 | )
|
30 | 29 | from google.cloud.sql.connector.utils import generate_keys
|
| 30 | +from mock import patch |
| 31 | +from aioresponses import aioresponses |
| 32 | +from aiohttp import ClientResponseError, RequestInfo |
31 | 33 |
|
32 | 34 | # import mocks
|
33 | 35 | import mocks
|
@@ -344,3 +346,53 @@ async def test_get_preferred_ip_CloudSQLIPTypeError(instance: Instance) -> None:
|
344 | 346 | instance_metadata.ip_addrs = {"PRIMARY": "0.0.0.0"}
|
345 | 347 | with pytest.raises(CloudSQLIPTypeError):
|
346 | 348 | instance_metadata.get_preferred_ip(IPTypes.PRIVATE)
|
| 349 | + |
| 350 | + |
| 351 | +@pytest.mark.asyncio |
| 352 | +async def test_ClientResponseError( |
| 353 | + fake_credentials: Credentials, event_loop: asyncio.AbstractEventLoop |
| 354 | +) -> None: |
| 355 | + """ |
| 356 | + Test that detailed error message is applied to ClientResponseError. |
| 357 | + """ |
| 358 | + # mock Cloud SQL Admin API calls with exceptions |
| 359 | + keys = asyncio.run_coroutine_threadsafe(generate_keys(), event_loop) |
| 360 | + get_url = "https://sqladmin.googleapis.com/sql/v1beta4/projects/my-project/instances/my-instance/connectSettings" |
| 361 | + post_url = "https://sqladmin.googleapis.com/sql/v1beta4/projects/my-project/instances/my-instance:generateEphemeralCert" |
| 362 | + with aioresponses() as mocked: |
| 363 | + mocked.get( |
| 364 | + get_url, |
| 365 | + status=403, |
| 366 | + exception=ClientResponseError( |
| 367 | + RequestInfo(get_url, "GET", headers=[]), history=[], status=403 # type: ignore |
| 368 | + ), |
| 369 | + repeat=True, |
| 370 | + ) |
| 371 | + mocked.post( |
| 372 | + post_url, |
| 373 | + status=403, |
| 374 | + exception=ClientResponseError( |
| 375 | + RequestInfo(post_url, "POST", headers=[]), history=[], status=403 # type: ignore |
| 376 | + ), |
| 377 | + repeat=True, |
| 378 | + ) |
| 379 | + # verify that error is raised with detailed error message |
| 380 | + try: |
| 381 | + instance = Instance( |
| 382 | + "my-project:my-region:my-instance", |
| 383 | + "pymysql", |
| 384 | + keys, |
| 385 | + event_loop, |
| 386 | + credentials=fake_credentials, |
| 387 | + ) |
| 388 | + await instance._current |
| 389 | + except ClientResponseError as e: |
| 390 | + assert e.status == 403 |
| 391 | + assert ( |
| 392 | + e.message == "Forbidden: Authenticated IAM principal does not " |
| 393 | + "seeem authorized to make API request. Verify " |
| 394 | + "'Cloud SQL Admin API' is enabled within your GCP project and " |
| 395 | + "'Cloud SQL Client' role has been granted to IAM principal." |
| 396 | + ) |
| 397 | + finally: |
| 398 | + await instance.close() |
0 commit comments