|
16 | 16 | import contextlib
|
17 | 17 | import copy
|
18 | 18 | import json
|
| 19 | +import os |
| 20 | +import pathlib |
19 | 21 | import re
|
20 | 22 | import sys
|
| 23 | +import tempfile |
21 | 24 | from unittest import mock
|
22 | 25 | import warnings
|
23 | 26 |
|
|
59 | 62 | except ImportError:
|
60 | 63 | gpd = None
|
61 | 64 |
|
| 65 | +Path = pathlib.Path |
| 66 | + |
62 | 67 |
|
63 | 68 | def make_connection(*args):
|
64 | 69 | # TODO(tswast): Remove this in favor of a mock google.cloud.bigquery.Client
|
@@ -929,6 +934,180 @@ def test_bigquery_magic_default_connection_user_agent():
|
929 | 934 | )
|
930 | 935 |
|
931 | 936 |
|
| 937 | +def test_bigquery_magic_default_connection_user_agent_vscode(): |
| 938 | + globalipapp.start_ipython() |
| 939 | + ip = globalipapp.get_ipython() |
| 940 | + ip.extension_manager.load_extension("bigquery_magics") |
| 941 | + bigquery_magics.context._connection = None |
| 942 | + |
| 943 | + credentials_mock = mock.create_autospec( |
| 944 | + google.auth.credentials.Credentials, instance=True |
| 945 | + ) |
| 946 | + default_patch = mock.patch( |
| 947 | + "google.auth.default", return_value=(credentials_mock, "general-project") |
| 948 | + ) |
| 949 | + run_query_patch = mock.patch("bigquery_magics.bigquery._run_query", autospec=True) |
| 950 | + conn_patch = mock.patch("google.cloud.bigquery.client.Connection", autospec=True) |
| 951 | + env_patch = mock.patch.dict(os.environ, {"VSCODE_PID": "1234"}, clear=True) |
| 952 | + |
| 953 | + with conn_patch as conn, run_query_patch, default_patch, env_patch: |
| 954 | + ip.run_cell_magic("bigquery", "", "SELECT 17 as num") |
| 955 | + |
| 956 | + client_info_arg = conn.call_args[1].get("client_info") |
| 957 | + assert client_info_arg is not None |
| 958 | + assert ( |
| 959 | + client_info_arg.user_agent |
| 960 | + == f"ipython-{IPython.__version__} bigquery-magics/{bigquery_magics.__version__} vscode" |
| 961 | + ) |
| 962 | + |
| 963 | + |
| 964 | +@pytest.mark.parametrize( |
| 965 | + ( |
| 966 | + "install_dir_exists", |
| 967 | + "manifest_exists", |
| 968 | + "manifest_valid", |
| 969 | + "expect_extension_user_agent", |
| 970 | + ), |
| 971 | + [ |
| 972 | + pytest.param(False, False, False, False, id="no-install"), |
| 973 | + pytest.param(True, False, False, False, id="no-manifest"), |
| 974 | + pytest.param(True, True, False, False, id="invalid-manifest"), |
| 975 | + pytest.param(True, True, True, True, id="good-install"), |
| 976 | + ], |
| 977 | +) |
| 978 | +def test_bigquery_magic_default_connection_user_agent_vscode_extension( |
| 979 | + install_dir_exists, manifest_exists, manifest_valid, expect_extension_user_agent |
| 980 | +): |
| 981 | + globalipapp.start_ipython() |
| 982 | + ip = globalipapp.get_ipython() |
| 983 | + ip.extension_manager.load_extension("bigquery_magics") |
| 984 | + bigquery_magics.context._connection = None |
| 985 | + |
| 986 | + credentials_mock = mock.create_autospec( |
| 987 | + google.auth.credentials.Credentials, instance=True |
| 988 | + ) |
| 989 | + default_patch = mock.patch( |
| 990 | + "google.auth.default", return_value=(credentials_mock, "general-project") |
| 991 | + ) |
| 992 | + run_query_patch = mock.patch("bigquery_magics.bigquery._run_query", autospec=True) |
| 993 | + conn_patch = mock.patch("google.cloud.bigquery.client.Connection", autospec=True) |
| 994 | + env_patch = mock.patch.dict(os.environ, {"VSCODE_PID": "1234"}, clear=True) |
| 995 | + |
| 996 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 997 | + user_home = Path(tmpdir) |
| 998 | + extension_dir = ( |
| 999 | + user_home / ".vscode" / "extensions" / "googlecloudtools.cloudcode-0.12" |
| 1000 | + ) |
| 1001 | + extension_config = extension_dir / "package.json" |
| 1002 | + |
| 1003 | + # originally extension config does not exist |
| 1004 | + assert not extension_config.exists() |
| 1005 | + |
| 1006 | + # simulate extension installation by creating extension config on disk |
| 1007 | + if install_dir_exists: |
| 1008 | + extension_dir.mkdir(parents=True) |
| 1009 | + |
| 1010 | + if manifest_exists: |
| 1011 | + if manifest_valid: |
| 1012 | + with open(extension_config, "w") as f: |
| 1013 | + f.write("{}") |
| 1014 | + else: |
| 1015 | + extension_config.touch() |
| 1016 | + |
| 1017 | + home_dir_patch = mock.patch("pathlib.Path.home", return_value=user_home) |
| 1018 | + |
| 1019 | + with conn_patch as conn, ( |
| 1020 | + run_query_patch |
| 1021 | + ), default_patch, env_patch, home_dir_patch: |
| 1022 | + ip.run_cell_magic("bigquery", "", "SELECT 17 as num") |
| 1023 | + |
| 1024 | + expected_user_agents = [ |
| 1025 | + f"ipython-{IPython.__version__}", |
| 1026 | + f"bigquery-magics/{bigquery_magics.__version__}", |
| 1027 | + "vscode", |
| 1028 | + ] |
| 1029 | + if expect_extension_user_agent: |
| 1030 | + expected_user_agents.append("googlecloudtools.cloudcode") |
| 1031 | + expected_user_agent = " ".join(expected_user_agents) |
| 1032 | + |
| 1033 | + client_info_arg = conn.call_args[1].get("client_info") |
| 1034 | + assert client_info_arg is not None |
| 1035 | + assert client_info_arg.user_agent == expected_user_agent |
| 1036 | + |
| 1037 | + |
| 1038 | +def test_bigquery_magic_default_connection_user_agent_jupyter(): |
| 1039 | + globalipapp.start_ipython() |
| 1040 | + ip = globalipapp.get_ipython() |
| 1041 | + ip.extension_manager.load_extension("bigquery_magics") |
| 1042 | + bigquery_magics.context._connection = None |
| 1043 | + |
| 1044 | + credentials_mock = mock.create_autospec( |
| 1045 | + google.auth.credentials.Credentials, instance=True |
| 1046 | + ) |
| 1047 | + default_patch = mock.patch( |
| 1048 | + "google.auth.default", return_value=(credentials_mock, "general-project") |
| 1049 | + ) |
| 1050 | + run_query_patch = mock.patch("bigquery_magics.bigquery._run_query", autospec=True) |
| 1051 | + conn_patch = mock.patch("google.cloud.bigquery.client.Connection", autospec=True) |
| 1052 | + env_patch = mock.patch.dict(os.environ, {"JPY_PARENT_PID": "1234"}, clear=True) |
| 1053 | + |
| 1054 | + with conn_patch as conn, run_query_patch, default_patch, env_patch: |
| 1055 | + ip.run_cell_magic("bigquery", "", "SELECT 17 as num") |
| 1056 | + |
| 1057 | + client_info_arg = conn.call_args[1].get("client_info") |
| 1058 | + assert client_info_arg is not None |
| 1059 | + assert ( |
| 1060 | + client_info_arg.user_agent |
| 1061 | + == f"ipython-{IPython.__version__} bigquery-magics/{bigquery_magics.__version__} jupyter" |
| 1062 | + ) |
| 1063 | + |
| 1064 | + |
| 1065 | +def test_bigquery_magic_default_connection_user_agent_jupyter_plugin(): |
| 1066 | + globalipapp.start_ipython() |
| 1067 | + ip = globalipapp.get_ipython() |
| 1068 | + ip.extension_manager.load_extension("bigquery_magics") |
| 1069 | + bigquery_magics.context._connection = None |
| 1070 | + |
| 1071 | + credentials_mock = mock.create_autospec( |
| 1072 | + google.auth.credentials.Credentials, instance=True |
| 1073 | + ) |
| 1074 | + default_patch = mock.patch( |
| 1075 | + "google.auth.default", return_value=(credentials_mock, "general-project") |
| 1076 | + ) |
| 1077 | + run_query_patch = mock.patch("bigquery_magics.bigquery._run_query", autospec=True) |
| 1078 | + conn_patch = mock.patch("google.cloud.bigquery.client.Connection", autospec=True) |
| 1079 | + env_patch = mock.patch.dict(os.environ, {"JPY_PARENT_PID": "1234"}, clear=True) |
| 1080 | + |
| 1081 | + def custom_import_module_side_effect(name, package=None): |
| 1082 | + if name == "bigquery_jupyter_plugin": |
| 1083 | + return mock.MagicMock() |
| 1084 | + else: |
| 1085 | + import importlib |
| 1086 | + |
| 1087 | + return importlib.import_module(name, package) |
| 1088 | + |
| 1089 | + assert isinstance( |
| 1090 | + custom_import_module_side_effect("bigquery_jupyter_plugin"), mock.MagicMock |
| 1091 | + ) |
| 1092 | + assert custom_import_module_side_effect("bigquery_magics") is bigquery_magics |
| 1093 | + |
| 1094 | + extension_import_patch = mock.patch( |
| 1095 | + "importlib.import_module", side_effect=custom_import_module_side_effect |
| 1096 | + ) |
| 1097 | + |
| 1098 | + with conn_patch as conn, ( |
| 1099 | + run_query_patch |
| 1100 | + ), default_patch, env_patch, extension_import_patch: |
| 1101 | + ip.run_cell_magic("bigquery", "", "SELECT 17 as num") |
| 1102 | + |
| 1103 | + client_info_arg = conn.call_args[1].get("client_info") |
| 1104 | + assert client_info_arg is not None |
| 1105 | + assert ( |
| 1106 | + client_info_arg.user_agent |
| 1107 | + == f"ipython-{IPython.__version__} bigquery-magics/{bigquery_magics.__version__} jupyter bigquery_jupyter_plugin" |
| 1108 | + ) |
| 1109 | + |
| 1110 | + |
932 | 1111 | def test_bigquery_magic_with_legacy_sql():
|
933 | 1112 | globalipapp.start_ipython()
|
934 | 1113 | ip = globalipapp.get_ipython()
|
|
0 commit comments