feat: add asyncio based auth flow (#612)
* feat: asyncio http request logic and asynchronous credentials logic (#572)
Co-authored-by: Anirudh Baddepudi <43104821+anibadde@users.noreply.github.com>
diff --git a/system_tests/noxfile.py b/system_tests/noxfile.py
index 14cd3db..a039228 100644
--- a/system_tests/noxfile.py
+++ b/system_tests/noxfile.py
@@ -1,4 +1,4 @@
-# Copyright 2016 Google LLC
+# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -29,7 +29,6 @@
import nox
import py.path
-
HERE = os.path.abspath(os.path.dirname(__file__))
LIBRARY_DIR = os.path.join(HERE, "..")
DATA_DIR = os.path.join(HERE, "data")
@@ -169,92 +168,79 @@
# Test sesssions
-TEST_DEPENDENCIES = ["pytest", "requests"]
-PYTHON_VERSIONS = ["2.7", "3.7"]
+TEST_DEPENDENCIES_ASYNC = ["aiohttp", "pytest-asyncio", "nest-asyncio"]
+TEST_DEPENDENCIES_SYNC = ["pytest", "requests"]
+PYTHON_VERSIONS_ASYNC = ["3.7"]
+PYTHON_VERSIONS_SYNC = ["2.7", "3.7"]
-@nox.session(python=PYTHON_VERSIONS)
-def service_account(session):
- session.install(*TEST_DEPENDENCIES)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
+def service_account_sync(session):
+ session.install(*TEST_DEPENDENCIES_SYNC)
session.install(LIBRARY_DIR)
- session.run("pytest", "test_service_account.py")
+ session.run("pytest", "system_tests_sync/test_service_account.py")
-@nox.session(python=PYTHON_VERSIONS)
-def oauth2_credentials(session):
- session.install(*TEST_DEPENDENCIES)
- session.install(LIBRARY_DIR)
- session.run("pytest", "test_oauth2_credentials.py")
-
-
-@nox.session(python=PYTHON_VERSIONS)
-def impersonated_credentials(session):
- session.install(*TEST_DEPENDENCIES)
- session.install(LIBRARY_DIR)
- session.run("pytest", "test_impersonated_credentials.py")
-
-
-@nox.session(python=PYTHON_VERSIONS)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
def default_explicit_service_account(session):
session.env[EXPLICIT_CREDENTIALS_ENV] = SERVICE_ACCOUNT_FILE
session.env[EXPECT_PROJECT_ENV] = "1"
- session.install(*TEST_DEPENDENCIES)
+ session.install(*TEST_DEPENDENCIES_SYNC)
session.install(LIBRARY_DIR)
- session.run("pytest", "test_default.py", "test_id_token.py")
+ session.run("pytest", "system_tests_sync/test_default.py", "system_tests_sync/test_id_token.py")
-@nox.session(python=PYTHON_VERSIONS)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
def default_explicit_authorized_user(session):
session.env[EXPLICIT_CREDENTIALS_ENV] = AUTHORIZED_USER_FILE
- session.install(*TEST_DEPENDENCIES)
+ session.install(*TEST_DEPENDENCIES_SYNC)
session.install(LIBRARY_DIR)
- session.run("pytest", "test_default.py")
+ session.run("pytest", "system_tests_sync/test_default.py")
-@nox.session(python=PYTHON_VERSIONS)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
def default_explicit_authorized_user_explicit_project(session):
session.env[EXPLICIT_CREDENTIALS_ENV] = AUTHORIZED_USER_FILE
session.env[EXPLICIT_PROJECT_ENV] = "example-project"
session.env[EXPECT_PROJECT_ENV] = "1"
- session.install(*TEST_DEPENDENCIES)
+ session.install(*TEST_DEPENDENCIES_SYNC)
session.install(LIBRARY_DIR)
- session.run("pytest", "test_default.py")
+ session.run("pytest", "system_tests_sync/test_default.py")
-@nox.session(python=PYTHON_VERSIONS)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
def default_cloud_sdk_service_account(session):
configure_cloud_sdk(session, SERVICE_ACCOUNT_FILE)
session.env[EXPECT_PROJECT_ENV] = "1"
- session.install(*TEST_DEPENDENCIES)
+ session.install(*TEST_DEPENDENCIES_SYNC)
session.install(LIBRARY_DIR)
- session.run("pytest", "test_default.py")
+ session.run("pytest", "system_tests_sync/test_default.py")
-@nox.session(python=PYTHON_VERSIONS)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
def default_cloud_sdk_authorized_user(session):
configure_cloud_sdk(session, AUTHORIZED_USER_FILE)
- session.install(*TEST_DEPENDENCIES)
+ session.install(*TEST_DEPENDENCIES_SYNC)
session.install(LIBRARY_DIR)
- session.run("pytest", "test_default.py")
+ session.run("pytest", "system_tests_sync/test_default.py")
-@nox.session(python=PYTHON_VERSIONS)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
def default_cloud_sdk_authorized_user_configured_project(session):
configure_cloud_sdk(session, AUTHORIZED_USER_FILE, project=True)
session.env[EXPECT_PROJECT_ENV] = "1"
- session.install(*TEST_DEPENDENCIES)
+ session.install(*TEST_DEPENDENCIES_SYNC)
session.install(LIBRARY_DIR)
- session.run("pytest", "test_default.py")
+ session.run("pytest", "system_tests_sync/test_default.py")
-
-@nox.session(python=PYTHON_VERSIONS)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
def compute_engine(session):
- session.install(*TEST_DEPENDENCIES)
+ session.install(*TEST_DEPENDENCIES_SYNC)
# unset Application Default Credentials so
# credentials are detected from environment
del session.virtualenv.env["GOOGLE_APPLICATION_CREDENTIALS"]
session.install(LIBRARY_DIR)
- session.run("pytest", "test_compute_engine.py")
+ session.run("pytest", "system_tests_sync/test_compute_engine.py")
@nox.session(python=["2.7"])
@@ -283,8 +269,8 @@
application_url = GAE_APP_URL_TMPL.format(GAE_TEST_APP_SERVICE, project_id)
# Vendor in the test application's dependencies
- session.chdir(os.path.join(HERE, "app_engine_test_app"))
- session.install(*TEST_DEPENDENCIES)
+ session.chdir(os.path.join(HERE, "../app_engine_test_app"))
+ session.install(*TEST_DEPENDENCIES_SYNC)
session.install(LIBRARY_DIR)
session.run(
"pip", "install", "--target", "lib", "-r", "requirements.txt", silent=True
@@ -296,20 +282,82 @@
# Run the tests
session.env["TEST_APP_URL"] = application_url
session.chdir(HERE)
- session.run("pytest", "test_app_engine.py")
+ session.run("pytest", "system_tests_sync/test_app_engine.py")
-@nox.session(python=PYTHON_VERSIONS)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
def grpc(session):
session.install(LIBRARY_DIR)
- session.install(*TEST_DEPENDENCIES, "google-cloud-pubsub==1.0.0")
+ session.install(*TEST_DEPENDENCIES_SYNC, "google-cloud-pubsub==1.0.0")
session.env[EXPLICIT_CREDENTIALS_ENV] = SERVICE_ACCOUNT_FILE
- session.run("pytest", "test_grpc.py")
+ session.run("pytest", "system_tests_sync/test_grpc.py")
-@nox.session(python=PYTHON_VERSIONS)
+@nox.session(python=PYTHON_VERSIONS_SYNC)
def mtls_http(session):
session.install(LIBRARY_DIR)
- session.install(*TEST_DEPENDENCIES, "pyopenssl")
+ session.install(*TEST_DEPENDENCIES_SYNC, "pyopenssl")
session.env[EXPLICIT_CREDENTIALS_ENV] = SERVICE_ACCOUNT_FILE
- session.run("pytest", "test_mtls_http.py")
+ session.run("pytest", "system_tests_sync/test_mtls_http.py")
+
+#ASYNC SYSTEM TESTS
+
+@nox.session(python=PYTHON_VERSIONS_ASYNC)
+def service_account_async(session):
+ session.install(*(TEST_DEPENDENCIES_SYNC+TEST_DEPENDENCIES_ASYNC))
+ session.install(LIBRARY_DIR)
+ session.run("pytest", "system_tests_async/test_service_account.py")
+
+
+@nox.session(python=PYTHON_VERSIONS_ASYNC)
+def default_explicit_service_account_async(session):
+ session.env[EXPLICIT_CREDENTIALS_ENV] = SERVICE_ACCOUNT_FILE
+ session.env[EXPECT_PROJECT_ENV] = "1"
+ session.install(*(TEST_DEPENDENCIES_SYNC + TEST_DEPENDENCIES_ASYNC))
+ session.install(LIBRARY_DIR)
+ session.run("pytest", "system_tests_async/test_default.py",
+ "system_tests_async/test_id_token.py")
+
+
+@nox.session(python=PYTHON_VERSIONS_ASYNC)
+def default_explicit_authorized_user_async(session):
+ session.env[EXPLICIT_CREDENTIALS_ENV] = AUTHORIZED_USER_FILE
+ session.install(*(TEST_DEPENDENCIES_SYNC + TEST_DEPENDENCIES_ASYNC))
+ session.install(LIBRARY_DIR)
+ session.run("pytest", "system_tests_async/test_default.py")
+
+
+@nox.session(python=PYTHON_VERSIONS_ASYNC)
+def default_explicit_authorized_user_explicit_project_async(session):
+ session.env[EXPLICIT_CREDENTIALS_ENV] = AUTHORIZED_USER_FILE
+ session.env[EXPLICIT_PROJECT_ENV] = "example-project"
+ session.env[EXPECT_PROJECT_ENV] = "1"
+ session.install(*(TEST_DEPENDENCIES_SYNC + TEST_DEPENDENCIES_ASYNC))
+ session.install(LIBRARY_DIR)
+ session.run("pytest", "system_tests_async/test_default.py")
+
+
+@nox.session(python=PYTHON_VERSIONS_ASYNC)
+def default_cloud_sdk_service_account_async(session):
+ configure_cloud_sdk(session, SERVICE_ACCOUNT_FILE)
+ session.env[EXPECT_PROJECT_ENV] = "1"
+ session.install(*(TEST_DEPENDENCIES_SYNC + TEST_DEPENDENCIES_ASYNC))
+ session.install(LIBRARY_DIR)
+ session.run("pytest", "system_tests_async/test_default.py")
+
+
+@nox.session(python=PYTHON_VERSIONS_ASYNC)
+def default_cloud_sdk_authorized_user_async(session):
+ configure_cloud_sdk(session, AUTHORIZED_USER_FILE)
+ session.install(*(TEST_DEPENDENCIES_SYNC + TEST_DEPENDENCIES_ASYNC))
+ session.install(LIBRARY_DIR)
+ session.run("pytest", "system_tests_async/test_default.py")
+
+
+@nox.session(python=PYTHON_VERSIONS_ASYNC)
+def default_cloud_sdk_authorized_user_configured_project_async(session):
+ configure_cloud_sdk(session, AUTHORIZED_USER_FILE, project=True)
+ session.env[EXPECT_PROJECT_ENV] = "1"
+ session.install(*(TEST_DEPENDENCIES_SYNC + TEST_DEPENDENCIES_ASYNC))
+ session.install(LIBRARY_DIR)
+ session.run("pytest", "system_tests_async/test_default.py")
diff --git a/system_tests/conftest.py b/system_tests/system_tests_async/conftest.py
similarity index 63%
copy from system_tests/conftest.py
copy to system_tests/system_tests_async/conftest.py
index 02de846..ecff74c 100644
--- a/system_tests/conftest.py
+++ b/system_tests/system_tests_async/conftest.py
@@ -1,4 +1,4 @@
-# Copyright 2016 Google LLC
+# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -22,52 +22,43 @@
import requests
import urllib3
+import aiohttp
+from google.auth.transport import _aiohttp_requests as aiohttp_requests
+from system_tests.system_tests_sync import conftest as sync_conftest
-HERE = os.path.dirname(__file__)
-DATA_DIR = os.path.join(HERE, "data")
-IMPERSONATED_SERVICE_ACCOUNT_FILE = os.path.join(
- DATA_DIR, "impersonated_service_account.json"
-)
-SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, "service_account.json")
-AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json")
-URLLIB3_HTTP = urllib3.PoolManager(retries=False)
-REQUESTS_SESSION = requests.Session()
-REQUESTS_SESSION.verify = False
+ASYNC_REQUESTS_SESSION = aiohttp.ClientSession()
+
+ASYNC_REQUESTS_SESSION.verify = False
TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo"
@pytest.fixture
def service_account_file():
"""The full path to a valid service account key file."""
- yield SERVICE_ACCOUNT_FILE
+ yield sync_conftest.SERVICE_ACCOUNT_FILE
@pytest.fixture
def impersonated_service_account_file():
"""The full path to a valid service account key file."""
- yield IMPERSONATED_SERVICE_ACCOUNT_FILE
+ yield sync_conftest.IMPERSONATED_SERVICE_ACCOUNT_FILE
@pytest.fixture
def authorized_user_file():
"""The full path to a valid authorized user file."""
- yield AUTHORIZED_USER_FILE
+ yield sync_conftest.AUTHORIZED_USER_FILE
-
-@pytest.fixture(params=["urllib3", "requests"])
-def http_request(request):
+@pytest.fixture(params=["aiohttp"])
+async def http_request(request):
"""A transport.request object."""
- if request.param == "urllib3":
- yield google.auth.transport.urllib3.Request(URLLIB3_HTTP)
- elif request.param == "requests":
- yield google.auth.transport.requests.Request(REQUESTS_SESSION)
-
+ yield aiohttp_requests.Request(ASYNC_REQUESTS_SESSION)
@pytest.fixture
-def token_info(http_request):
+async def token_info(http_request):
"""Returns a function that obtains OAuth2 token info."""
- def _token_info(access_token=None, id_token=None):
+ async def _token_info(access_token=None, id_token=None):
query_params = {}
if access_token is not None:
@@ -77,24 +68,25 @@
else:
raise ValueError("No token specified.")
- url = _helpers.update_query(TOKEN_INFO_URL, query_params)
+ url = _helpers.update_query(sync_conftest.TOKEN_INFO_URL, query_params)
- response = http_request(url=url, method="GET")
+ response = await http_request(url=url, method="GET")
+ data = await response.data.read()
- return json.loads(response.data.decode("utf-8"))
+ return json.loads(data.decode("utf-8"))
yield _token_info
@pytest.fixture
-def verify_refresh(http_request):
+async def verify_refresh(http_request):
"""Returns a function that verifies that credentials can be refreshed."""
- def _verify_refresh(credentials):
+ async def _verify_refresh(credentials):
if credentials.requires_scopes:
credentials = credentials.with_scopes(["email", "profile"])
- credentials.refresh(http_request)
+ await credentials.refresh(http_request)
assert credentials.token
assert credentials.valid
@@ -104,7 +96,7 @@
def verify_environment():
"""Checks to make sure that requisite data files are available."""
- if not os.path.isdir(DATA_DIR):
+ if not os.path.isdir(sync_conftest.DATA_DIR):
raise EnvironmentError(
"In order to run system tests, test data must exist in "
"system_tests/data. See CONTRIBUTING.rst for details."
diff --git a/system_tests/system_tests_async/test_default.py b/system_tests/system_tests_async/test_default.py
new file mode 100644
index 0000000..383cbff
--- /dev/null
+++ b/system_tests/system_tests_async/test_default.py
@@ -0,0 +1,30 @@
+# Copyright 2020 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
+#
+# http://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.
+
+import os
+import pytest
+
+import google.auth
+
+EXPECT_PROJECT_ID = os.environ.get("EXPECT_PROJECT_ID")
+
+@pytest.mark.asyncio
+async def test_application_default_credentials(verify_refresh):
+ credentials, project_id = google.auth.default_async()
+ #breakpoint()
+
+ if EXPECT_PROJECT_ID is not None:
+ assert project_id is not None
+
+ await verify_refresh(credentials)
diff --git a/system_tests/system_tests_async/test_id_token.py b/system_tests/system_tests_async/test_id_token.py
new file mode 100644
index 0000000..a21b137
--- /dev/null
+++ b/system_tests/system_tests_async/test_id_token.py
@@ -0,0 +1,25 @@
+# Copyright 2020 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
+#
+# http://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.
+import pytest
+
+from google.auth import jwt
+import google.oauth2._id_token_async
+
+@pytest.mark.asyncio
+async def test_fetch_id_token(http_request):
+ audience = "https://pubsub.googleapis.com"
+ token = await google.oauth2._id_token_async.fetch_id_token(http_request, audience)
+
+ _, payload, _, _ = jwt._unverified_decode(token)
+ assert payload["aud"] == audience
diff --git a/system_tests/system_tests_async/test_service_account.py b/system_tests/system_tests_async/test_service_account.py
new file mode 100644
index 0000000..c1c16cc
--- /dev/null
+++ b/system_tests/system_tests_async/test_service_account.py
@@ -0,0 +1,53 @@
+# Copyright 2020 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
+#
+# http://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.
+
+import pytest
+
+from google.auth import _helpers
+from google.auth import exceptions
+from google.auth import iam
+from google.oauth2 import _service_account_async
+
+
+@pytest.fixture
+def credentials(service_account_file):
+ yield _service_account_async.Credentials.from_service_account_file(service_account_file)
+
+
+@pytest.mark.asyncio
+async def test_refresh_no_scopes(http_request, credentials):
+ """
+ We expect the http request to refresh credentials
+ without scopes provided to throw an error.
+ """
+ with pytest.raises(exceptions.RefreshError):
+ await credentials.refresh(http_request)
+
+@pytest.mark.asyncio
+async def test_refresh_success(http_request, credentials, token_info):
+ credentials = credentials.with_scopes(["email", "profile"])
+ await credentials.refresh(http_request)
+
+ assert credentials.token
+
+ info = await token_info(credentials.token)
+
+ assert info["email"] == credentials.service_account_email
+ info_scopes = _helpers.string_to_scopes(info["scope"])
+ assert set(info_scopes) == set(
+ [
+ "https://www.googleapis.com/auth/userinfo.email",
+ "https://www.googleapis.com/auth/userinfo.profile",
+ ]
+ )
diff --git a/system_tests/.gitignore b/system_tests/system_tests_sync/.gitignore
similarity index 100%
rename from system_tests/.gitignore
rename to system_tests/system_tests_sync/.gitignore
diff --git a/system_tests/__init__.py b/system_tests/system_tests_sync/__init__.py
similarity index 100%
rename from system_tests/__init__.py
rename to system_tests/system_tests_sync/__init__.py
diff --git a/system_tests/app_engine_test_app/.gitignore b/system_tests/system_tests_sync/app_engine_test_app/.gitignore
similarity index 100%
rename from system_tests/app_engine_test_app/.gitignore
rename to system_tests/system_tests_sync/app_engine_test_app/.gitignore
diff --git a/system_tests/app_engine_test_app/app.yaml b/system_tests/system_tests_sync/app_engine_test_app/app.yaml
similarity index 100%
rename from system_tests/app_engine_test_app/app.yaml
rename to system_tests/system_tests_sync/app_engine_test_app/app.yaml
diff --git a/system_tests/app_engine_test_app/appengine_config.py b/system_tests/system_tests_sync/app_engine_test_app/appengine_config.py
similarity index 100%
rename from system_tests/app_engine_test_app/appengine_config.py
rename to system_tests/system_tests_sync/app_engine_test_app/appengine_config.py
diff --git a/system_tests/app_engine_test_app/main.py b/system_tests/system_tests_sync/app_engine_test_app/main.py
similarity index 100%
rename from system_tests/app_engine_test_app/main.py
rename to system_tests/system_tests_sync/app_engine_test_app/main.py
diff --git a/system_tests/app_engine_test_app/requirements.txt b/system_tests/system_tests_sync/app_engine_test_app/requirements.txt
similarity index 100%
rename from system_tests/app_engine_test_app/requirements.txt
rename to system_tests/system_tests_sync/app_engine_test_app/requirements.txt
diff --git a/system_tests/conftest.py b/system_tests/system_tests_sync/conftest.py
similarity index 96%
rename from system_tests/conftest.py
rename to system_tests/system_tests_sync/conftest.py
index 02de846..37a6fd3 100644
--- a/system_tests/conftest.py
+++ b/system_tests/system_tests_sync/conftest.py
@@ -24,12 +24,11 @@
HERE = os.path.dirname(__file__)
-DATA_DIR = os.path.join(HERE, "data")
+DATA_DIR = os.path.join(HERE, "../data")
IMPERSONATED_SERVICE_ACCOUNT_FILE = os.path.join(
DATA_DIR, "impersonated_service_account.json"
)
SERVICE_ACCOUNT_FILE = os.path.join(DATA_DIR, "service_account.json")
-AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json")
URLLIB3_HTTP = urllib3.PoolManager(retries=False)
REQUESTS_SESSION = requests.Session()
REQUESTS_SESSION.verify = False
diff --git a/system_tests/secrets.tar.enc b/system_tests/system_tests_sync/secrets.tar.enc
similarity index 100%
rename from system_tests/secrets.tar.enc
rename to system_tests/system_tests_sync/secrets.tar.enc
Binary files differ
diff --git a/system_tests/test_app_engine.py b/system_tests/system_tests_sync/test_app_engine.py
similarity index 100%
rename from system_tests/test_app_engine.py
rename to system_tests/system_tests_sync/test_app_engine.py
diff --git a/system_tests/test_compute_engine.py b/system_tests/system_tests_sync/test_compute_engine.py
similarity index 100%
rename from system_tests/test_compute_engine.py
rename to system_tests/system_tests_sync/test_compute_engine.py
diff --git a/system_tests/test_default.py b/system_tests/system_tests_sync/test_default.py
similarity index 100%
rename from system_tests/test_default.py
rename to system_tests/system_tests_sync/test_default.py
diff --git a/system_tests/test_grpc.py b/system_tests/system_tests_sync/test_grpc.py
similarity index 100%
rename from system_tests/test_grpc.py
rename to system_tests/system_tests_sync/test_grpc.py
diff --git a/system_tests/test_id_token.py b/system_tests/system_tests_sync/test_id_token.py
similarity index 100%
rename from system_tests/test_id_token.py
rename to system_tests/system_tests_sync/test_id_token.py
diff --git a/system_tests/test_impersonated_credentials.py b/system_tests/system_tests_sync/test_impersonated_credentials.py
similarity index 100%
rename from system_tests/test_impersonated_credentials.py
rename to system_tests/system_tests_sync/test_impersonated_credentials.py
diff --git a/system_tests/test_mtls_http.py b/system_tests/system_tests_sync/test_mtls_http.py
similarity index 100%
rename from system_tests/test_mtls_http.py
rename to system_tests/system_tests_sync/test_mtls_http.py
diff --git a/system_tests/test_oauth2_credentials.py b/system_tests/system_tests_sync/test_oauth2_credentials.py
similarity index 100%
rename from system_tests/test_oauth2_credentials.py
rename to system_tests/system_tests_sync/test_oauth2_credentials.py
diff --git a/system_tests/test_service_account.py b/system_tests/system_tests_sync/test_service_account.py
similarity index 100%
rename from system_tests/test_service_account.py
rename to system_tests/system_tests_sync/test_service_account.py