|
21 | 21 | import os
|
22 | 22 | import re
|
23 | 23 | from io import StringIO
|
| 24 | +from pathlib import Path |
24 | 25 | from unittest import mock
|
| 26 | +from unittest.mock import patch |
25 | 27 |
|
26 | 28 | import google.auth
|
27 | 29 | import pytest
|
|
34 | 36 | from airflow.exceptions import AirflowException
|
35 | 37 | from airflow.providers.google.cloud.utils.credentials_provider import _DEFAULT_SCOPES
|
36 | 38 | from airflow.providers.google.common.hooks import base_google as hook
|
| 39 | +from airflow.providers.google.common.hooks.base_google import GoogleBaseHook |
37 | 40 | from tests.providers.google.cloud.utils.base_gcp_mock import mock_base_gcp_hook_default_project_id
|
38 | 41 |
|
39 | 42 | default_creds_available = True
|
@@ -166,6 +169,37 @@ def assert_gcp_credential_file_in_env(_):
|
166 | 169 | ):
|
167 | 170 | assert_gcp_credential_file_in_env(self.instance)
|
168 | 171 |
|
| 172 | + def test_provide_gcp_credential_keyfile_dict_json(self): |
| 173 | + """ |
| 174 | + Historically, keyfile_dict had to be str in the conn extra. Now it |
| 175 | + can be dict and this is verified here. |
| 176 | + """ |
| 177 | + conn_dict = { |
| 178 | + "extra": { |
| 179 | + "keyfile_dict": {"foo": "bar", "private_key": "hi"}, # notice keyfile_dict is dict not str |
| 180 | + } |
| 181 | + } |
| 182 | + |
| 183 | + @GoogleBaseHook.provide_gcp_credential_file |
| 184 | + def assert_gcp_credential_file_in_env(instance): |
| 185 | + assert Path(os.environ[CREDENTIALS]).read_text() == json.dumps(conn_dict["extra"]["keyfile_dict"]) |
| 186 | + |
| 187 | + with patch.dict("os.environ", AIRFLOW_CONN_MY_GOOGLE=json.dumps(conn_dict)): |
| 188 | + # keyfile dict is handled in two different areas |
| 189 | + |
| 190 | + hook = GoogleBaseHook("my_google") |
| 191 | + |
| 192 | + # the first is in provide_gcp_credential_file |
| 193 | + assert_gcp_credential_file_in_env(hook) |
| 194 | + |
| 195 | + with patch("google.oauth2.service_account.Credentials.from_service_account_info") as m: |
| 196 | + # the second is in get_credentials_and_project_id |
| 197 | + hook.get_credentials_and_project_id() |
| 198 | + m.assert_called_once_with( |
| 199 | + conn_dict["extra"]["keyfile_dict"], |
| 200 | + scopes=("https://www.googleapis.com/auth/cloud-platform",), |
| 201 | + ) |
| 202 | + |
169 | 203 | def test_provide_gcp_credential_file_decorator_key_path(self):
|
170 | 204 | key_path = "/test/key-path"
|
171 | 205 | self.instance.extras = {"key_path": key_path}
|
|
0 commit comments