forked from GoogleCloudPlatform/cloud-sql-python-connector
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_refresh_utils.py
More file actions
239 lines (204 loc) · 7.08 KB
/
Copy pathtest_refresh_utils.py
File metadata and controls
239 lines (204 loc) · 7.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
""""
Copyright 2021 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.
"""
from typing import Any, no_type_check
import aiohttp
from google.auth.credentials import Credentials
import json
import pytest # noqa F401 Needed to run the tests
from mock import AsyncMock, Mock, patch
import asyncio
from google.cloud.sql.connector.refresh_utils import (
_get_ephemeral,
_get_metadata,
_is_valid,
)
from google.cloud.sql.connector.utils import generate_keys
from tests.unit.test_instance import ( # type: ignore
_get_metadata_success,
_get_metadata_expired,
)
class FakeClientSessionGet:
"""Helper class to return mock data for get request."""
async def text(self) -> str:
response = {
"kind": "sql#connectSettings",
"serverCaCert": {
"kind": "sql#sslCert",
"certSerialNumber": "0",
"cert": "-----BEGIN CERTIFICATE-----\nabc123\n-----END CERTIFICATE-----",
"commonName": "Google",
"sha1Fingerprint": "abc",
"instance": "my-instance",
"createTime": "2021-10-18T18:48:03.785Z",
"expirationTime": "2031-10-16T18:49:03.785Z",
},
"ipAddresses": [
{"type": "PRIMARY", "ipAddress": "0.0.0.0"},
{"type": "PRIVATE", "ipAddress": "1.0.0.0"},
],
"region": "my-region",
"databaseVersion": "MYSQL_8_0",
"backendType": "SECOND_GEN",
}
return json.dumps(response)
class FakeClientSessionPost:
"""Helper class to return mock data for post request."""
async def text(self) -> str:
response = {
"ephemeralCert": {
"kind": "sql#sslCert",
"certSerialNumber": "",
"cert": "-----BEGIN CERTIFICATE-----\nabc123\n-----END CERTIFICATE-----",
}
}
return json.dumps(response)
@pytest.fixture
def credentials() -> Credentials:
credentials = Mock(spec=Credentials)
credentials.valid = True
credentials.token = "12345"
return credentials
@pytest.mark.asyncio
@patch("aiohttp.ClientSession.post", new_callable=AsyncMock)
async def test_get_ephemeral(mock_post: AsyncMock, credentials: Credentials) -> None:
"""
Test to check whether _get_ephemeral runs without problems given valid
parameters.
"""
mock_post.return_value = FakeClientSessionPost()
project = "my-project"
instance = "my-instance"
_, pub_key = await generate_keys()
async with aiohttp.ClientSession() as client_session:
result: Any = await _get_ephemeral(
client_session, credentials, project, instance, pub_key
)
result = result.split("\n")
assert (
result[0] == "-----BEGIN CERTIFICATE-----"
and result[len(result) - 1] == "-----END CERTIFICATE-----"
)
@pytest.mark.asyncio
@no_type_check
async def test_get_ephemeral_TypeError(credentials: Credentials) -> None:
"""
Test to check whether _get_ephemeral throws proper TypeError
when given incorrect input arg types.
"""
client_session = Mock(aiohttp.ClientSession)
project = "my-project"
instance = "my-instance"
pub_key = "key"
# incorrect credentials type
with pytest.raises(TypeError):
await _get_ephemeral(
client_session=client_session,
credentials="bad-credentials",
project=project,
instance=instance,
pub_key=pub_key,
)
# incorrect project type
with pytest.raises(TypeError):
await _get_ephemeral(
client_session=client_session,
credentials=credentials,
project=12345,
instance=instance,
pub_key=pub_key,
)
# incorrect instance type
with pytest.raises(TypeError):
await _get_ephemeral(
client_session=client_session,
credentials=credentials,
project=project,
instance=12345,
pub_key=pub_key,
)
# incorrect pub_key type
with pytest.raises(TypeError):
await _get_ephemeral(
client_session=client_session,
credentials=credentials,
project=project,
instance=instance,
pub_key=12345,
)
@pytest.mark.asyncio
@patch("aiohttp.ClientSession.get", new_callable=AsyncMock)
async def test_get_metadata(mock_get: AsyncMock, credentials: Credentials) -> None:
"""
Test to check whether _get_metadata runs without problems given valid
parameters.
"""
mock_get.return_value = FakeClientSessionGet()
project = "my-project"
instance = "my-instance"
async with aiohttp.ClientSession() as client_session:
result = await _get_metadata(client_session, credentials, project, instance)
assert result["ip_addresses"] is not None and isinstance(
result["server_ca_cert"], str
)
@pytest.mark.asyncio
@no_type_check
async def test_get_metadata_TypeError(credentials: Credentials) -> None:
"""
Test to check whether _get_metadata throws proper TypeError
when given incorrect input arg types.
"""
client_session = Mock(aiohttp.ClientSession)
project = "my-project"
instance = "my-instance"
# incorrect credentials type
with pytest.raises(TypeError):
await _get_metadata(
client_session=client_session,
credentials="bad-credentials",
project=project,
instance=instance,
)
# incorrect project type
with pytest.raises(TypeError):
await _get_metadata(
client_session=client_session,
credentials=credentials,
project=12345,
instance=instance,
)
# incorrect instance type
with pytest.raises(TypeError):
await _get_metadata(
client_session=client_session,
credentials=credentials,
project=project,
instance=12345,
)
@pytest.mark.asyncio
@no_type_check
async def test_is_valid_with_valid_metadata() -> None:
"""
Test to check that valid metadata with expiration in future returns True.
"""
# task that returns class with expiration 10 mins in future
task = asyncio.create_task(_get_metadata_success())
assert await _is_valid(task)
@pytest.mark.asyncio
@no_type_check
async def test_is_valid_with_expired_metadata() -> None:
"""
Test to check that invalid metadata with expiration in past returns False.
"""
# task that returns class with expiration 10 mins in past
task = asyncio.create_task(_get_metadata_expired())
assert not await _is_valid(task)