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")