Repository: googleapis/python-bigquery

Issue:
Remove test_utils directory
Now that test utils are available in a GitHub repo, a local `test_utils` copy is not needed anymore and should be removed.


Discussion:

Resolving patch:
diff --git a/noxfile.py b/noxfile.py
--- a/noxfile.py
+++ b/noxfile.py
@@ -34,7 +34,7 @@ def default(session):
     # Install all test dependencies, then install local packages in-place.
     session.install("mock", "pytest", "pytest-cov", "freezegun")
     session.install("grpcio")
-    session.install("-e", "test_utils")
+    session.install("git+https://github.com/googleapis/python-test-utils")
 
     # fastparquet is not included in .[all] because, in general, it's redundant
     # with pyarrow. We still want to run some unit tests with fastparquet
@@ -83,7 +83,7 @@ def system(session):
     session.install("mock", "pytest", "psutil")
     session.install("google-cloud-storage")
     session.install("fastavro")
-    session.install("-e", "test_utils")
+    session.install("git+https://github.com/googleapis/python-test-utils")
     session.install("-e", ".[all]")
 
     # IPython does not support Python 2 after version 5.x
@@ -110,7 +110,7 @@ def snippets(session):
     session.install("mock", "pytest")
     session.install("google-cloud-storage")
     session.install("grpcio")
-    session.install("-e", "test_utils")
+    session.install("git+https://github.com/googleapis/python-test-utils")
     session.install("-e", ".[all]")
 
     # Run py.test against the snippets tests.


Test patch:
diff --git a/test_utils/credentials.json.enc b/test_utils/credentials.json.enc
deleted file mode 100644
--- a/test_utils/credentials.json.enc
+++ /dev/null
@@ -1,49 +0,0 @@
-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
diff --git a/test_utils/scripts/circleci/get_tagged_package.py b/test_utils/scripts/circleci/get_tagged_package.py
deleted file mode 100644
--- a/test_utils/scripts/circleci/get_tagged_package.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2016 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.
-
-"""Helper to determine package from tag.
-Get the current package directory corresponding to the Circle Tag.
-"""
-
-from __future__ import print_function
-
-import os
-import re
-import sys
-
-
-TAG_RE = re.compile(r"""
-    ^
-    (?P<pkg>
-        (([a-z]+)[_-])*)  # pkg-name-with-hyphens-or-underscores (empty allowed)
-    ([0-9]+)\.([0-9]+)\.([0-9]+)  # Version x.y.z (x, y, z all ints)
-    $
-""", re.VERBOSE)
-TAG_ENV = 'CIRCLE_TAG'
-ERROR_MSG = '%s env. var. not set' % (TAG_ENV,)
-BAD_TAG_MSG = 'Invalid tag name: %s. Expected pkg-name-x.y.z'
-CIRCLE_CI_SCRIPTS_DIR = os.path.dirname(__file__)
-ROOT_DIR = os.path.realpath(
-    os.path.join(CIRCLE_CI_SCRIPTS_DIR, '..', '..', '..'))
-
-
-def main():
-    """Get the current package directory.
-    Prints the package directory out so callers can consume it.
-    """
-    if TAG_ENV not in os.environ:
-        print(ERROR_MSG, file=sys.stderr)
-        sys.exit(1)
-
-    tag_name = os.environ[TAG_ENV]
-    match = TAG_RE.match(tag_name)
-    if match is None:
-        print(BAD_TAG_MSG % (tag_name,), file=sys.stderr)
-        sys.exit(1)
-
-    pkg_name = match.group('pkg')
-    if pkg_name is None:
-        print(ROOT_DIR)
-    else:
-        pkg_dir = pkg_name.rstrip('-').replace('-', '_')
-        print(os.path.join(ROOT_DIR, pkg_dir))
-
-
-if __name__ == '__main__':
-    main()
diff --git a/test_utils/scripts/circleci/twine_upload.sh b/test_utils/scripts/circleci/twine_upload.sh
deleted file mode 100755
--- a/test_utils/scripts/circleci/twine_upload.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-
-# Copyright 2016 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.
-
-set -ev
-
-# If this is not a CircleCI tag, no-op.
-if [[ -z "$CIRCLE_TAG" ]]; then
-  echo "This is not a release tag. Doing nothing."
-  exit 0
-fi
-
-# H/T: http://stackoverflow.com/a/246128/1068170
-SCRIPT="$(dirname "${BASH_SOURCE[0]}")/get_tagged_package.py"
-# Determine the package directory being deploying on this tag.
-PKG_DIR="$(python ${SCRIPT})"
-
-# Ensure that we have the latest versions of Twine, Wheel, and Setuptools.
-python3 -m pip install --upgrade twine wheel setuptools
-
-# Move into the package, build the distribution and upload.
-cd ${PKG_DIR}
-python3 setup.py sdist bdist_wheel
-twine upload dist/*
diff --git a/test_utils/scripts/get_target_packages.py b/test_utils/scripts/get_target_packages.py
deleted file mode 100644
--- a/test_utils/scripts/get_target_packages.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# Copyright 2017 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.
-
-"""Print a list of packages which require testing."""
-
-import os
-import re
-import subprocess
-import warnings
-
-
-CURRENT_DIR = os.path.realpath(os.path.dirname(__file__))
-BASE_DIR = os.path.realpath(os.path.join(CURRENT_DIR, '..', '..'))
-GITHUB_REPO = os.environ.get('GITHUB_REPO', 'google-cloud-python')
-CI = os.environ.get('CI', '')
-CI_BRANCH = os.environ.get('CIRCLE_BRANCH')
-CI_PR = os.environ.get('CIRCLE_PR_NUMBER')
-CIRCLE_TAG = os.environ.get('CIRCLE_TAG')
-head_hash, head_name = subprocess.check_output(['git', 'show-ref', 'HEAD']
-).strip().decode('ascii').split()
-rev_parse = subprocess.check_output(
-    ['git', 'rev-parse', '--abbrev-ref', 'HEAD']
-).strip().decode('ascii')
-MAJOR_DIV = '#' * 78
-MINOR_DIV = '#' + '-' * 77
-
-# NOTE: This reg-ex is copied from ``get_tagged_packages``.
-TAG_RE = re.compile(r"""
-    ^
-    (?P<pkg>
-        (([a-z]+)-)*)            # pkg-name-with-hyphens- (empty allowed)
-    ([0-9]+)\.([0-9]+)\.([0-9]+)  # Version x.y.z (x, y, z all ints)
-    $
-""", re.VERBOSE)
-
-# This is the current set of dependencies by package.
-# As of this writing, the only "real" dependency is that of error_reporting
-# (on logging), the rest are just system test dependencies.
-PKG_DEPENDENCIES = {
-    'logging': {'pubsub'},
-}
-
-
-def get_baseline():
-    """Return the baseline commit.
-
-    On a pull request, or on a branch, return the common parent revision
-    with the master branch.
-
-    Locally, return a value pulled from environment variables, or None if
-    the environment variables are not set.
-
-    On a push to master, return None. This will effectively cause everything
-    to be considered to be affected.
-    """
-
-    # If this is a pull request or branch, return the tip for master.
-    # We will test only packages which have changed since that point.
-    ci_non_master = (CI == 'true') and any([CI_BRANCH != 'master', CI_PR])
-
-    if ci_non_master:
-
-        repo_url = 'git@github.com:GoogleCloudPlatform/{}'.format(GITHUB_REPO)
-        subprocess.run(['git', 'remote', 'add', 'baseline', repo_url],
-                        stderr=subprocess.DEVNULL)
-        subprocess.run(['git', 'pull', 'baseline'], stderr=subprocess.DEVNULL)
-
-        if CI_PR is None and CI_BRANCH is not None:
-            output = subprocess.check_output([
-                'git', 'merge-base', '--fork-point',
-                'baseline/master', CI_BRANCH])
-            return output.strip().decode('ascii')
-
-        return 'baseline/master'
-
-    # If environment variables are set identifying what the master tip is,
-    # use that.
-    if os.environ.get('GOOGLE_CLOUD_TESTING_REMOTE', ''):
-        remote = os.environ['GOOGLE_CLOUD_TESTING_REMOTE']
-        branch = os.environ.get('GOOGLE_CLOUD_TESTING_BRANCH', 'master')
-        return '%s/%s' % (remote, branch)
-
-    # If we are not in CI and we got this far, issue a warning.
-    if not CI:
-        warnings.warn('No baseline could be determined; this means tests '
-                      'will run for every package. If this is local '
-                      'development, set the $GOOGLE_CLOUD_TESTING_REMOTE '
-                      'environment variable.')
-
-    # That is all we can do; return None.
-    return None
-
-
-def get_changed_files():
-    """Return a list of files that have been changed since the baseline.
-
-    If there is no base, return None.
-    """
-    # Get the baseline, and fail quickly if there is no baseline.
-    baseline = get_baseline()
-    print('# Baseline commit: {}'.format(baseline))
-    if not baseline:
-        return None
-
-    # Return a list of altered files.
-    try:
-        return subprocess.check_output([
-            'git', 'diff', '--name-only', '{}..HEAD'.format(baseline),
-        ], stderr=subprocess.DEVNULL).decode('utf8').strip().split('\n')
-    except subprocess.CalledProcessError:
-        warnings.warn('Unable to perform git diff; falling back to assuming '
-                      'all packages have changed.')
-        return None
-
-
-def reverse_map(dict_of_sets):
-    """Reverse a map of one-to-many.
-
-    So the map::
-
-      {
-        'A': {'B', 'C'},
-        'B': {'C'},
-      }
-
-    becomes
-
-      {
-        'B': {'A'},
-        'C': {'A', 'B'},
-      }
-
-    Args:
-        dict_of_sets (dict[set]): A dictionary of sets, mapping
-            one value to many.
-
-    Returns:
-        dict[set]: The reversed map.
-    """
-    result = {}
-    for key, values in dict_of_sets.items():
-        for value in values:
-            result.setdefault(value, set()).add(key)
-
-    return result
-
-def get_changed_packages(file_list):
-    """Return a list of changed packages based on the provided file list.
-
-    If the file list is None, then all packages should be considered to be
-    altered.
-    """
-    # Determine a complete list of packages.
-    all_packages = set()
-    for file_ in os.listdir(BASE_DIR):
-        abs_file = os.path.realpath(os.path.join(BASE_DIR, file_))
-        nox_file = os.path.join(abs_file, 'nox.py')
-        if os.path.isdir(abs_file) and os.path.isfile(nox_file):
-            all_packages.add(file_)
-
-    # If ther is no file list, send down the full package set.
-    if file_list is None:
-        return all_packages
-
-    # Create a set based on the list of changed files.
-    answer = set()
-    reverse_deps = reverse_map(PKG_DEPENDENCIES)
-    for file_ in file_list:
-        # Ignore root directory changes (setup.py, .gitignore, etc.).
-        if os.path.sep not in file_:
-            continue
-
-        # Ignore changes that are not in a package (usually this will be docs).
-        package = file_.split(os.path.sep, 1)[0]
-        if package not in all_packages:
-            continue
-
-        # If there is a change in core, short-circuit now and return
-        # everything.
-        if package in ('core',):
-            return all_packages
-
-        # Add the package, as well as any dependencies this package has.
-        # NOTE: For now, dependencies only go down one level.
-        answer.add(package)
-        answer = answer.union(reverse_deps.get(package, set()))
-
-    # We got this far without being short-circuited; return the final answer.
-    return answer
-
-
-def get_tagged_package():
-    """Return the package corresponding to the current tag.
-
-    If there is not tag, will return :data:`None`.
-    """
-    if CIRCLE_TAG is None:
-        return
-
-    match = TAG_RE.match(CIRCLE_TAG)
-    if match is None:
-        return
-
-    pkg_name = match.group('pkg')
-    if pkg_name == '':
-        # NOTE: This corresponds to the "umbrella" tag.
-        return
-
-    return pkg_name.rstrip('-').replace('-', '_')
-
-
-def get_target_packages():
-    """Return a list of target packages to be run in the current build.
-
-    If in a tag build, will run only the package(s) that are tagged, otherwise
-    will run the packages that have file changes in them (or packages that
-    depend on those).
-    """
-    tagged_package = get_tagged_package()
-    if tagged_package is None:
-        file_list = get_changed_files()
-        print(MAJOR_DIV)
-        print('# Changed files:')
-        print(MINOR_DIV)
-        for file_ in file_list or ():
-            print('#  {}'.format(file_))
-        for package in sorted(get_changed_packages(file_list)):
-            yield package
-    else:
-        yield tagged_package
-
-
-def main():
-    print(MAJOR_DIV)
-    print('# Environment')
-    print(MINOR_DIV)
-    print('# CircleCI:        {}'.format(CI))
-    print('# CircleCI branch: {}'.format(CI_BRANCH))
-    print('# CircleCI pr:     {}'.format(CI_PR))
-    print('# CircleCI tag:    {}'.format(CIRCLE_TAG))
-    print('# HEAD ref:        {}'.format(head_hash))
-    print('#                  {}'.format(head_name))
-    print('# Git branch:      {}'.format(rev_parse))
-    print(MAJOR_DIV)
-
-    packages = list(get_target_packages())
-
-    print(MAJOR_DIV)
-    print('# Target packages:')
-    print(MINOR_DIV)
-    for package in packages:
-       print(package)
-    print(MAJOR_DIV)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/test_utils/scripts/get_target_packages_kokoro.py b/test_utils/scripts/get_target_packages_kokoro.py
deleted file mode 100644
--- a/test_utils/scripts/get_target_packages_kokoro.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright 2017 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.
-
-"""Print a list of packages which require testing."""
-
-import pathlib
-import subprocess
-
-import ci_diff_helper
-import requests
-
-
-def print_environment(environment):
-    print("-> CI environment:")
-    print('Branch', environment.branch)
-    print('PR', environment.pr)
-    print('In PR', environment.in_pr)
-    print('Repo URL', environment.repo_url)
-    if environment.in_pr:
-        print('PR Base', environment.base)
-
-
-def get_base(environment):
-    if environment.in_pr:
-        return environment.base
-    else:
-        # If we're not in a PR, just calculate the changes between this commit
-        # and its parent.
-        return 'HEAD~1'
-
-
-def get_changed_files_from_base(base):
-    return subprocess.check_output([
-        'git', 'diff', '--name-only', f'{base}..HEAD',
-    ], stderr=subprocess.DEVNULL).decode('utf8').strip().split('\n')
-
-
-_URL_TEMPLATE = (
-    'https://api.github.com/repos/googleapis/google-cloud-python/pulls/'
-    '{}/files'
-)
-
-
-def get_changed_files_from_pr(pr):
-    url = _URL_TEMPLATE.format(pr)
-    while url is not None:
-        response = requests.get(url)
-        for info in response.json():
-            yield info['filename']
-        url = response.links.get('next', {}).get('url')
-
-
-def determine_changed_packages(changed_files):
-    packages = [
-        path.parent for path in pathlib.Path('.').glob('*/noxfile.py')
-    ]
-
-    changed_packages = set()
-    for file in changed_files:
-        file = pathlib.Path(file)
-        for package in packages:
-            if package in file.parents:
-                changed_packages.add(package)
-
-    return changed_packages
-
-
-def main():
-    environment = ci_diff_helper.get_config()
-    print_environment(environment)
-    base = get_base(environment)
-
-    if environment.in_pr:
-        changed_files = list(get_changed_files_from_pr(environment.pr))
-    else:
-        changed_files = get_changed_files_from_base(base)
-
-    packages = determine_changed_packages(changed_files)
-
-    print(f"Comparing against {base}.")
-    print("-> Changed packages:")
-
-    for package in packages:
-        print(package)
-
-
-main()
diff --git a/test_utils/scripts/run_emulator.py b/test_utils/scripts/run_emulator.py
deleted file mode 100644
--- a/test_utils/scripts/run_emulator.py
+++ /dev/null
@@ -1,199 +0,0 @@
-# Copyright 2016 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.
-
-"""Run system tests locally with the emulator.
-
-First makes system calls to spawn the emulator and get the local environment
-variable needed for it. Then calls the system tests.
-"""
-
-
-import argparse
-import os
-import subprocess
-
-import psutil
-
-from google.cloud.environment_vars import BIGTABLE_EMULATOR
-from google.cloud.environment_vars import GCD_DATASET
-from google.cloud.environment_vars import GCD_HOST
-from google.cloud.environment_vars import PUBSUB_EMULATOR
-from run_system_test import run_module_tests
-
-
-BIGTABLE = 'bigtable'
-DATASTORE = 'datastore'
-PUBSUB = 'pubsub'
-PACKAGE_INFO = {
-    BIGTABLE: (BIGTABLE_EMULATOR,),
-    DATASTORE: (GCD_DATASET, GCD_HOST),
-    PUBSUB: (PUBSUB_EMULATOR,),
-}
-EXTRA = {
-    DATASTORE: ('--no-legacy',),
-}
-_DS_READY_LINE = '[datastore] Dev App Server is now running.\n'
-_PS_READY_LINE_PREFIX = '[pubsub] INFO: Server started, listening on '
-_BT_READY_LINE_PREFIX = '[bigtable] Cloud Bigtable emulator running on '
-
-
-def get_parser():
-    """Get simple ``argparse`` parser to determine package.
-
-    :rtype: :class:`argparse.ArgumentParser`
-    :returns: The parser for this script.
-    """
-    parser = argparse.ArgumentParser(
-        description='Run google-cloud system tests against local emulator.')
-    parser.add_argument('--package', dest='package',
-                        choices=sorted(PACKAGE_INFO.keys()),
-                        default=DATASTORE, help='Package to be tested.')
-    return parser
-
-
-def get_start_command(package):
-    """Get command line arguments for starting emulator.
-
-    :type package: str
-    :param package: The package to start an emulator for.
-
-    :rtype: tuple
-    :returns: The arguments to be used, in a tuple.
-    """
-    result = ('gcloud', 'beta', 'emulators', package, 'start')
-    extra = EXTRA.get(package, ())
-    return result + extra
-
-
-def get_env_init_command(package):
-    """Get command line arguments for getting emulator env. info.
-
-    :type package: str
-    :param package: The package to get environment info for.
-
-    :rtype: tuple
-    :returns: The arguments to be used, in a tuple.
-    """
-    result = ('gcloud', 'beta', 'emulators', package, 'env-init')
-    extra = EXTRA.get(package, ())
-    return result + extra
-
-
-def datastore_wait_ready(popen):
-    """Wait until the datastore emulator is ready to use.
-
-    :type popen: :class:`subprocess.Popen`
-    :param popen: An open subprocess to interact with.
-    """
-    emulator_ready = False
-    while not emulator_ready:
-        emulator_ready = popen.stderr.readline() == _DS_READY_LINE
-
-
-def wait_ready_prefix(popen, prefix):
-    """Wait until the a process encounters a line with matching prefix.
-
-    :type popen: :class:`subprocess.Popen`
-    :param popen: An open subprocess to interact with.
-
-    :type prefix: str
-    :param prefix: The prefix to match
-    """
-    emulator_ready = False
-    while not emulator_ready:
-        emulator_ready = popen.stderr.readline().startswith(prefix)
-
-
-def wait_ready(package, popen):
-    """Wait until the emulator is ready to use.
-
-    :type package: str
-    :param package: The package to check if ready.
-
-    :type popen: :class:`subprocess.Popen`
-    :param popen: An open subprocess to interact with.
-
-    :raises: :class:`KeyError` if the ``package`` is not among
-             ``datastore``, ``pubsub`` or ``bigtable``.
-    """
-    if package == DATASTORE:
-        datastore_wait_ready(popen)
-    elif package == PUBSUB:
-        wait_ready_prefix(popen, _PS_READY_LINE_PREFIX)
-    elif package == BIGTABLE:
-        wait_ready_prefix(popen, _BT_READY_LINE_PREFIX)
-    else:
-        raise KeyError('Package not supported', package)
-
-
-def cleanup(pid):
-    """Cleanup a process (including all of its children).
-
-    :type pid: int
-    :param pid: Process ID.
-    """
-    proc = psutil.Process(pid)
-    for child_proc in proc.children(recursive=True):
-        try:
-            child_proc.kill()
-            child_proc.terminate()
-        except psutil.NoSuchProcess:
-            pass
-    proc.terminate()
-    proc.kill()
-
-
-def run_tests_in_emulator(package):
-    """Spawn an emulator instance and run the system tests.
-
-    :type package: str
-    :param package: The package to run system tests against.
-    """
-    # Make sure this package has environment vars to replace.
-    env_vars = PACKAGE_INFO[package]
-
-    start_command = get_start_command(package)
-    # Ignore stdin and stdout, don't pollute the user's output with them.
-    proc_start = subprocess.Popen(start_command, stdout=subprocess.PIPE,
-                                  stderr=subprocess.PIPE)
-    try:
-        wait_ready(package, proc_start)
-        env_init_command = get_env_init_command(package)
-        proc_env = subprocess.Popen(env_init_command, stdout=subprocess.PIPE,
-                                    stderr=subprocess.PIPE)
-        env_status = proc_env.wait()
-        if env_status != 0:
-            raise RuntimeError(env_status, proc_env.stderr.read())
-        env_lines = proc_env.stdout.read().strip().split('\n')
-        # Set environment variables before running the system tests.
-        for env_var in env_vars:
-            line_prefix = 'export ' + env_var + '='
-            value, = [line.split(line_prefix, 1)[1] for line in env_lines
-                      if line.startswith(line_prefix)]
-            os.environ[env_var] = value
-        run_module_tests(package,
-                         ignore_requirements=True)
-    finally:
-        cleanup(proc_start.pid)
-
-
-def main():
-    """Main method to run this script."""
-    parser = get_parser()
-    args = parser.parse_args()
-    run_tests_in_emulator(args.package)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/test_utils/scripts/update_docs.sh b/test_utils/scripts/update_docs.sh
deleted file mode 100755
--- a/test_utils/scripts/update_docs.sh
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/bin/bash
-
-# Copyright 2016 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.
-
-set -ev
-
-GH_OWNER='GoogleCloudPlatform'
-GH_PROJECT_NAME='google-cloud-python'
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-# Function to build the docs.
-function build_docs {
-    rm -rf docs/_build/
-    rm -f docs/bigquery/generated/*.rst
-    # -W -> warnings as errors
-    # -T -> show full traceback on exception
-    # -N -> no color
-    sphinx-build \
-        -W -T -N \
-        -b html \
-        -d docs/_build/doctrees \
-        docs/ \
-        docs/_build/html/
-    return $?
-}
-
-# Only update docs if we are on CircleCI.
-if [[ "${CIRCLE_BRANCH}" == "master" ]] && [[ -z "${CIRCLE_PR_NUMBER}" ]]; then
-    echo "Building new docs on a merged commit."
-elif [[ "$1" == "kokoro" ]]; then
-    echo "Building and publishing docs on Kokoro."
-elif [[ -n "${CIRCLE_TAG}" ]]; then
-    echo "Building new docs on a tag (but will not deploy)."
-    build_docs
-    exit $?
-else
-    echo "Not on master nor a release tag."
-    echo "Building new docs for testing purposes, but not deploying."
-    build_docs
-    exit $?
-fi
-
-# Adding GitHub pages branch. `git submodule add` checks it
-# out at HEAD.
-GH_PAGES_DIR='ghpages'
-git submodule add -q -b gh-pages \
-    "git@github.com:${GH_OWNER}/${GH_PROJECT_NAME}" ${GH_PAGES_DIR}
-
-# Determine if we are building a new tag or are building docs
-# for master. Then build new docs in docs/_build from master.
-if [[ -n "${CIRCLE_TAG}" ]]; then
-    # Sphinx will use the package version by default.
-    build_docs
-else
-    SPHINX_RELEASE=$(git log -1 --pretty=%h) build_docs
-fi
-
-# Update gh-pages with the created docs.
-cd ${GH_PAGES_DIR}
-git rm -fr latest/
-cp -R ../docs/_build/html/ latest/
-
-# Update the files push to gh-pages.
-git add .
-git status
-
-# If there are no changes, just exit cleanly.
-if [[ -z "$(git status --porcelain)" ]]; then
-    echo "Nothing to commit. Exiting without pushing changes."
-    exit
-fi
-
-# Commit to gh-pages branch to apply changes.
-git config --global user.email "dpebot@google.com"
-git config --global user.name "dpebot"
-git commit -m "Update docs after merge to master."
-
-# NOTE: This may fail if two docs updates (on merges to master)
-#       happen in close proximity.
-git push -q origin HEAD:gh-pages
diff --git a/test_utils/setup.py b/test_utils/setup.py
deleted file mode 100644
--- a/test_utils/setup.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2017 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
-
-from setuptools import find_packages
-from setuptools import setup
-
-
-PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__))
-
-
-# NOTE: This is duplicated throughout and we should try to
-#       consolidate.
-SETUP_BASE = {
-    'author': 'Google Cloud Platform',
-    'author_email': 'googleapis-publisher@google.com',
-    'scripts': [],
-    'url': 'https://github.com/GoogleCloudPlatform/google-cloud-python',
-    'license': 'Apache 2.0',
-    'platforms': 'Posix; MacOS X; Windows',
-    'include_package_data': True,
-    'zip_safe': False,
-    'classifiers': [
-        'Development Status :: 4 - Beta',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: Apache Software License',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.5',
-        'Programming Language :: Python :: 3.6',
-        'Programming Language :: Python :: 3.7',
-        'Topic :: Internet',
-    ],
-}
-
-
-REQUIREMENTS = [
-    'google-auth >= 0.4.0',
-    'six',
-]
-
-setup(
-    name='google-cloud-testutils',
-    version='0.24.0',
-    description='System test utilities for google-cloud-python',
-    packages=find_packages(),
-    install_requires=REQUIREMENTS,
-    python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*',
-    **SETUP_BASE
-)
diff --git a/test_utils/test_utils/__init__.py b/test_utils/test_utils/__init__.py
deleted file mode 100644
diff --git a/test_utils/test_utils/imports.py b/test_utils/test_utils/imports.py
deleted file mode 100644
--- a/test_utils/test_utils/imports.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2019 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 mock
-import six
-
-
-def maybe_fail_import(predicate):
-    """Create and return a patcher that conditionally makes an import fail.
-
-    Args:
-        predicate (Callable[[...], bool]): A callable that, if it returns `True`,
-            triggers an `ImportError`. It must accept the same arguments as the
-            built-in `__import__` function.
-            https://docs.python.org/3/library/functions.html#__import__
-
-    Returns:
-        A mock patcher object that can be used to enable patched import behavior.
-    """
-    orig_import = six.moves.builtins.__import__
-
-    def custom_import(name, globals=None, locals=None, fromlist=(), level=0):
-        if predicate(name, globals, locals, fromlist, level):
-            raise ImportError
-        return orig_import(name, globals, locals, fromlist, level)
-
-    return mock.patch.object(six.moves.builtins, "__import__", new=custom_import)
diff --git a/test_utils/test_utils/retry.py b/test_utils/test_utils/retry.py
deleted file mode 100644
--- a/test_utils/test_utils/retry.py
+++ /dev/null
@@ -1,207 +0,0 @@
-# Copyright 2016 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 time
-from functools import wraps
-
-import six
-
-MAX_TRIES = 4
-DELAY = 1
-BACKOFF = 2
-
-
-def _retry_all(_):
-    """Retry all caught exceptions."""
-    return True
-
-
-class BackoffFailed(Exception):
-    """Retry w/ backoffs did not complete successfully."""
-
-
-class RetryBase(object):
-    """Base for retrying calling a decorated function w/ exponential backoff.
-
-    :type max_tries: int
-    :param max_tries: Number of times to try (not retry) before giving up.
-
-    :type delay: int
-    :param delay: Initial delay between retries in seconds.
-
-    :type backoff: int
-    :param backoff: Backoff multiplier e.g. value of 2 will double the
-                    delay each retry.
-
-    :type logger: logging.Logger instance
-    :param logger: Logger to use. If None, print.
-    """
-    def __init__(self, max_tries=MAX_TRIES, delay=DELAY, backoff=BACKOFF,
-                 logger=None):
-        self.max_tries = max_tries
-        self.delay = delay
-        self.backoff = backoff
-        self.logger = logger.warning if logger else six.print_
-
-
-class RetryErrors(RetryBase):
-    """Decorator for retrying given exceptions in testing.
-
-    :type exception: Exception or tuple of Exceptions
-    :param exception: The exception to check or may be a tuple of
-                      exceptions to check.
-
-    :type error_predicate: function, takes caught exception, returns bool
-    :param error_predicate: Predicate evaluating whether to retry after a
-                            caught exception.
-
-    :type max_tries: int
-    :param max_tries: Number of times to try (not retry) before giving up.
-
-    :type delay: int
-    :param delay: Initial delay between retries in seconds.
-
-    :type backoff: int
-    :param backoff: Backoff multiplier e.g. value of 2 will double the
-                    delay each retry.
-
-    :type logger: logging.Logger instance
-    :param logger: Logger to use. If None, print.
-    """
-    def __init__(self, exception, error_predicate=_retry_all,
-                 max_tries=MAX_TRIES, delay=DELAY, backoff=BACKOFF,
-                 logger=None):
-        super(RetryErrors, self).__init__(max_tries, delay, backoff, logger)
-        self.exception = exception
-        self.error_predicate = error_predicate
-
-    def __call__(self, to_wrap):
-        @wraps(to_wrap)
-        def wrapped_function(*args, **kwargs):
-            tries = 0
-            while tries < self.max_tries:
-                try:
-                    return to_wrap(*args, **kwargs)
-                except self.exception as caught_exception:
-
-                    if not self.error_predicate(caught_exception):
-                        raise
-
-                    delay = self.delay * self.backoff**tries
-                    msg = ("%s, Trying again in %d seconds..." %
-                           (caught_exception, delay))
-                    self.logger(msg)
-
-                    time.sleep(delay)
-                    tries += 1
-            return to_wrap(*args, **kwargs)
-
-        return wrapped_function
-
-
-class RetryResult(RetryBase):
-    """Decorator for retrying based on non-error result.
-
-    :type result_predicate: function, takes result, returns bool
-    :param result_predicate: Predicate evaluating whether to retry after a
-                             result is returned.
-
-    :type max_tries: int
-    :param max_tries: Number of times to try (not retry) before giving up.
-
-    :type delay: int
-    :param delay: Initial delay between retries in seconds.
-
-    :type backoff: int
-    :param backoff: Backoff multiplier e.g. value of 2 will double the
-                    delay each retry.
-
-    :type logger: logging.Logger instance
-    :param logger: Logger to use. If None, print.
-    """
-    def __init__(self, result_predicate,
-                 max_tries=MAX_TRIES, delay=DELAY, backoff=BACKOFF,
-                 logger=None):
-        super(RetryResult, self).__init__(max_tries, delay, backoff, logger)
-        self.result_predicate = result_predicate
-
-    def __call__(self, to_wrap):
-        @wraps(to_wrap)
-        def wrapped_function(*args, **kwargs):
-            tries = 0
-            while tries < self.max_tries:
-                result = to_wrap(*args, **kwargs)
-                if self.result_predicate(result):
-                    return result
-
-                delay = self.delay * self.backoff**tries
-                msg = "%s. Trying again in %d seconds..." % (
-                    self.result_predicate.__name__, delay,)
-                self.logger(msg)
-
-                time.sleep(delay)
-                tries += 1
-            raise BackoffFailed()
-
-        return wrapped_function
-
-
-class RetryInstanceState(RetryBase):
-    """Decorator for retrying based on instance state.
-
-    :type instance_predicate: function, takes instance, returns bool
-    :param instance_predicate: Predicate evaluating whether to retry after an
-                               API-invoking method is called.
-
-    :type max_tries: int
-    :param max_tries: Number of times to try (not retry) before giving up.
-
-    :type delay: int
-    :param delay: Initial delay between retries in seconds.
-
-    :type backoff: int
-    :param backoff: Backoff multiplier e.g. value of 2 will double the
-                    delay each retry.
-
-    :type logger: logging.Logger instance
-    :param logger: Logger to use. If None, print.
-    """
-    def __init__(self, instance_predicate,
-                 max_tries=MAX_TRIES, delay=DELAY, backoff=BACKOFF,
-                 logger=None):
-        super(RetryInstanceState, self).__init__(
-            max_tries, delay, backoff, logger)
-        self.instance_predicate = instance_predicate
-
-    def __call__(self, to_wrap):
-        instance = to_wrap.__self__   # only instance methods allowed
-
-        @wraps(to_wrap)
-        def wrapped_function(*args, **kwargs):
-            tries = 0
-            while tries < self.max_tries:
-                result = to_wrap(*args, **kwargs)
-                if self.instance_predicate(instance):
-                    return result
-
-                delay = self.delay * self.backoff**tries
-                msg = "%s. Trying again in %d seconds..." % (
-                    self.instance_predicate.__name__, delay,)
-                self.logger(msg)
-
-                time.sleep(delay)
-                tries += 1
-            raise BackoffFailed()
-
-        return wrapped_function
diff --git a/test_utils/test_utils/system.py b/test_utils/test_utils/system.py
deleted file mode 100644
--- a/test_utils/test_utils/system.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright 2014 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.
-
-from __future__ import print_function
-import os
-import sys
-import time
-
-import google.auth.credentials
-from google.auth.environment_vars import CREDENTIALS as TEST_CREDENTIALS
-
-
-# From shell environ. May be None.
-CREDENTIALS = os.getenv(TEST_CREDENTIALS)
-
-ENVIRON_ERROR_MSG = """\
-To run the system tests, you need to set some environment variables.
-Please check the CONTRIBUTING guide for instructions.
-"""
-
-
-class EmulatorCreds(google.auth.credentials.Credentials):
-    """A mock credential object.
-
-    Used to avoid unnecessary token refreshing or reliance on the network
-    while an emulator is running.
-    """
-
-    def __init__(self):  # pylint: disable=super-init-not-called
-        self.token = b'seekrit'
-        self.expiry = None
-
-    @property
-    def valid(self):
-        """Would-be validity check of the credentials.
-
-        Always is :data:`True`.
-        """
-        return True
-
-    def refresh(self, unused_request):  # pylint: disable=unused-argument
-        """Off-limits implementation for abstract method."""
-        raise RuntimeError('Should never be refreshed.')
-
-
-def check_environ():
-    err_msg = None
-    if CREDENTIALS is None:
-        err_msg = '\nMissing variables: ' + TEST_CREDENTIALS
-    elif not os.path.isfile(CREDENTIALS):
-        err_msg = '\nThe %s path %r is not a file.' % (TEST_CREDENTIALS,
-                                                       CREDENTIALS)
-
-    if err_msg is not None:
-        msg = ENVIRON_ERROR_MSG + err_msg
-        print(msg, file=sys.stderr)
-        sys.exit(1)
-
-
-def unique_resource_id(delimiter='_'):
-    """A unique identifier for a resource.
-
-    Intended to help locate resources created in particular
-    testing environments and at particular times.
-    """
-    build_id = os.getenv('CIRCLE_BUILD_NUM', '')
-    if build_id == '':
-        return '%s%d' % (delimiter, 1000 * time.time())
-    else:
-        return '%s%s%s%d' % (delimiter, build_id, delimiter, time.time())
diff --git a/test_utils/test_utils/vpcsc_config.py b/test_utils/test_utils/vpcsc_config.py
deleted file mode 100644
--- a/test_utils/test_utils/vpcsc_config.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright 2019 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.
-
-import os
-
-import pytest
-
-
-INSIDE_VPCSC_ENVVAR = "GOOGLE_CLOUD_TESTS_IN_VPCSC"
-PROJECT_INSIDE_ENVVAR = "PROJECT_ID"
-PROJECT_OUTSIDE_ENVVAR = "GOOGLE_CLOUD_TESTS_VPCSC_OUTSIDE_PERIMETER_PROJECT"
-BUCKET_OUTSIDE_ENVVAR = "GOOGLE_CLOUD_TESTS_VPCSC_OUTSIDE_PERIMETER_BUCKET"
-
-
-class VPCSCTestConfig(object):
-    """System test utility for VPCSC detection.
-
-    See: https://cloud.google.com/vpc-service-controls/docs/
-    """
-
-    @property
-    def inside_vpcsc(self):
-        """Test whether the test environment is configured to run inside VPCSC.
-
-        Returns:
-            bool:
-                true if the environment is configured to run inside VPCSC,
-                else false.
-        """
-        return INSIDE_VPCSC_ENVVAR in os.environ
-
-    @property
-    def project_inside(self):
-        """Project ID for testing outside access.
-
-        Returns:
-            str: project ID used for testing outside access; None if undefined.
-        """
-        return os.environ.get(PROJECT_INSIDE_ENVVAR, None)
-
-    @property
-    def project_outside(self):
-        """Project ID for testing inside access.
-
-        Returns:
-            str: project ID used for testing inside access; None if undefined.
-        """
-        return os.environ.get(PROJECT_OUTSIDE_ENVVAR, None)
-
-    @property
-    def bucket_outside(self):
-        """GCS bucket for testing inside access.
-
-        Returns:
-            str: bucket ID used for testing inside access; None if undefined.
-        """
-        return os.environ.get(BUCKET_OUTSIDE_ENVVAR, None)
-
-    def skip_if_inside_vpcsc(self, testcase):
-        """Test decorator: skip if running inside VPCSC."""
-        reason = (
-            "Running inside VPCSC.  "
-            "Unset the {} environment variable to enable this test."
-        ).format(INSIDE_VPCSC_ENVVAR)
-        skip = pytest.mark.skipif(self.inside_vpcsc, reason=reason)
-        return skip(testcase)
-
-    def skip_unless_inside_vpcsc(self, testcase):
-        """Test decorator: skip if running outside VPCSC."""
-        reason = (
-            "Running outside VPCSC.  "
-            "Set the {} environment variable to enable this test."
-        ).format(INSIDE_VPCSC_ENVVAR)
-        skip = pytest.mark.skipif(not self.inside_vpcsc, reason=reason)
-        return skip(testcase)
-
-    def skip_unless_inside_project(self, testcase):
-        """Test decorator: skip if inside project env var not set."""
-        reason = (
-            "Project ID for running inside VPCSC not set.  "
-            "Set the {} environment variable to enable this test."
-        ).format(PROJECT_INSIDE_ENVVAR)
-        skip = pytest.mark.skipif(self.project_inside is None, reason=reason)
-        return skip(testcase)
-
-    def skip_unless_outside_project(self, testcase):
-        """Test decorator: skip if outside project env var not set."""
-        reason = (
-            "Project ID for running outside VPCSC not set. "
-            "Set the {} environment variable to enable this test."
-        ).format(PROJECT_OUTSIDE_ENVVAR)
-        skip = pytest.mark.skipif(self.project_outside is None, reason=reason)
-        return skip(testcase)
-
-    def skip_unless_outside_bucket(self, testcase):
-        """Test decorator: skip if outside bucket env var not set."""
-        reason = (
-            "Bucket ID for running outside VPCSC not set. "
-            "Set the {} environment variable to enable this test."
-        ).format(BUCKET_OUTSIDE_ENVVAR)
-        skip = pytest.mark.skipif(self.bucket_outside is None, reason=reason)
-        return skip(testcase)
-
-
-vpcsc_config = VPCSCTestConfig()