[ci] Remove deployment of PRs to wptpr.live (#28055)

diff --git a/.github/workflows/pull_request_previews.yml b/.github/workflows/pull_request_previews.yml
deleted file mode 100644
index 676aff3..0000000
--- a/.github/workflows/pull_request_previews.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-# Create previews for pull requests on https://wptpr.live
-#
-# Mirroring pull requests to wptpr.live requires write access to the WPT GitHub
-# repository. This means that we cannot run any code from the pull request in
-# doing so, to defend against attacks from malicious pull requests. As such,
-# this workflow uses the 'pull_request_target' event which runs in the context
-# of the base repository and thus doesn't run code from the pull request. Any
-# code run in this workflow should NOT checkout or trust code from the pull
-# request.
-#
-# Note that in pull_request_target the GITHUB token is read/write.
-name: create-pr-preview
-on:
-  pull_request_target:
-    types: [opened, synchronize, reopened, closed, labeled, unlabeled]
-jobs:
-  update-pr-preview:
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@v1
-      with:
-        fetch-depth: 1
-    - name: Install dependency
-      run: pip install requests
-    - name: Deploy PR
-      # Use a conditional step instead of a conditional job to work around #20700.
-      if: github.repository == 'web-platform-tests/wpt'
-      run:
-        ./tools/ci/pr_preview.py
-          --host https://api.github.com
-          --github-project web-platform-tests/wpt
-          --target https://wptpr.live
-          --timeout 600
-      env:
-        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/tools/ci/pr_preview.py b/tools/ci/pr_preview.py
deleted file mode 100755
index c6932da..0000000
--- a/tools/ci/pr_preview.py
+++ /dev/null
@@ -1,378 +0,0 @@
-#!/usr/bin/env python
-
-# The service provided by this script is not critical, but it shares a GitHub
-# API request quota with critical services. For this reason, all requests to
-# the GitHub API are preceded by a "guard" which verifies that the subsequent
-# request will not deplete the shared quota.
-#
-# In effect, this script will fail rather than interfere with the operation of
-# critical services.
-
-import argparse
-import json
-import logging
-import os
-import time
-
-import requests
-
-# The ratio of "requests remaining" to "total request quota" below which this
-# script should refuse to interact with the GitHub.com API
-API_RATE_LIMIT_THRESHOLD = 0.2
-# The GitHub Pull Request label which indicates that a Pull Request is expected
-# to be actively mirrored by the preview server
-LABEL = 'safe for preview'
-# The number of seconds to wait between attempts to verify that a submission
-# preview is available on the Pull Request preview server
-POLLING_PERIOD = 15
-# Pull Requests from authors with the following associations to the project
-# should automatically receive previews
-#
-# https://developer.github.com/v4/enum/commentauthorassociation/ (equivalent
-# documentation for the REST API was not available at the time of writing)
-TRUSTED_AUTHOR_ASSOCIATIONS = ('COLLABORATOR', 'MEMBER', 'OWNER')
-# These GitHub accounts are not associated with individuals, and the Pull
-# Requests they submit rarely require a preview.
-AUTOMATION_GITHUB_USERS = (
-    'autofoolip', 'chromium-wpt-export-bot', 'moz-wptsync-bot',
-    'servo-wpt-sync'
-)
-DEPLOYMENT_PREFIX = 'wpt-preview-'
-
-logging.basicConfig(level=logging.INFO)
-logger = logging.getLogger(__name__)
-
-def gh_request(method_name, url, body=None, media_type=None):
-    github_token = os.environ['GITHUB_TOKEN']
-
-    kwargs = {
-        'headers': {
-            'Authorization': 'token {}'.format(github_token),
-            'Accept': media_type or 'application/vnd.github.v3+json'
-        }
-    }
-    method = getattr(requests, method_name.lower())
-
-    if body is not None:
-        kwargs['json'] = body
-
-    logger.info('Issuing request: %s %s', method_name.upper(), url)
-
-    resp = method(url, **kwargs)
-
-    logger.info('Response status code: %s', resp.status_code)
-
-    # If GitHub thinks the fields are invalid, it will send a 422 back and
-    # include debugging information in the body. See
-    # https://developer.github.com/v3/#client-errors
-    if resp.status_code == 422:
-        logger.error(resp.json())
-
-    resp.raise_for_status()
-
-    if resp.status_code == 204:
-        return None
-    return resp.json()
-
-class GitHubRateLimitException(Exception):
-    pass
-
-def guard(resource):
-    '''Decorate a `Project` instance method which interacts with the GitHub
-    API, ensuring that the subsequent request will not deplete the relevant
-    allowance. This verification does not itself influence rate limiting:
-
-    > Accessing this endpoint does not count against your REST API rate limit.
-
-    https://developer.github.com/v3/rate_limit/
-    '''
-    def guard_decorator(func):
-        def wrapped(self, *args, **kwargs):
-            limits = gh_request('GET', '{}/rate_limit'.format(self._host))
-
-            values = limits['resources'].get(resource)
-
-            remaining = values['remaining']
-            limit = values['limit']
-
-            logger.info(
-                'Limit for "%s" resource: %s/%s', resource, remaining, limit
-            )
-
-            if limit and float(remaining) / limit < API_RATE_LIMIT_THRESHOLD:
-                raise GitHubRateLimitException(
-                    'Exiting to avoid GitHub.com API request throttling.'
-                )
-
-            return func(self, *args, **kwargs)
-        return wrapped
-    return guard_decorator
-
-class Project(object):
-    def __init__(self, host, github_project):
-        self._host = host
-        self._github_project = github_project
-
-    @guard('core')
-    def create_ref(self, refspec, revision):
-        url = '{}/repos/{}/git/refs'.format(self._host, self._github_project)
-
-        logger.info('Creating ref "%s" (%s)', refspec, revision)
-
-        gh_request('POST', url, {
-            'ref': 'refs/{}'.format(refspec),
-            'sha': revision
-        })
-
-    @guard('core')
-    def get_ref_revision(self, refspec):
-        url = '{}/repos/{}/git/refs/{}'.format(
-            self._host, self._github_project, refspec
-        )
-
-        logger.info('Fetching ref "%s"', refspec)
-
-        try:
-            body = gh_request('GET', url)
-            logger.info('Ref data: %s', json.dumps(body, indent=2))
-            return body['object']['sha']
-        except requests.exceptions.HTTPError as e:
-            if e.response.status_code == 404:
-                return None
-            raise e
-
-    @guard('core')
-    def update_ref(self, refspec, revision):
-        url = '{}/repos/{}/git/refs/{}'.format(
-            self._host, self._github_project, refspec
-        )
-
-        logger.info('Updating ref "%s" (%s)', refspec, revision)
-
-        gh_request('PATCH', url, {'sha': revision})
-
-    @guard('core')
-    def delete_ref(self, refspec):
-        url = '{}/repos/{}/git/refs/{}'.format(
-            self._host, self._github_project, refspec
-        )
-
-        logger.info('Deleting ref "%s"', refspec)
-
-        gh_request('DELETE', url)
-
-    @guard('core')
-    def create_deployment(self, pull_request, revision):
-        url = '{}/repos/{}/deployments'.format(
-            self._host, self._github_project
-        )
-        # The Pull Request preview system only exposes one Deployment for a
-        # given Pull Request. Identifying the Deployment by the Pull Request
-        # number ensures that GitHub.com automatically responds to new
-        # Deployments by designating prior Deployments as "inactive"
-        environment = DEPLOYMENT_PREFIX + str(pull_request['number'])
-
-        logger.info('Creating Deployment "%s" for "%s"', environment, revision)
-
-        return gh_request('POST', url, {
-            'ref': revision,
-            'environment': environment,
-            'auto_merge': False,
-            # Pull Request previews are created regardless of GitHub Commit
-            # Status Checks, so Status Checks should be ignored when creating
-            # GitHub Deployments.
-            'required_contexts': []
-        }, 'application/vnd.github.ant-man-preview+json')
-
-    @guard('core')
-    def get_deployment(self, revision):
-        url = '{}/repos/{}/deployments?sha={}'.format(
-            self._host, self._github_project, revision
-        )
-
-        deployments = gh_request('GET', url)
-
-        return deployments.pop() if len(deployments) else None
-
-    @guard('core')
-    def add_deployment_status(self, target, deployment, state, description=''):
-        if state in ('pending', 'success'):
-            pr_number = deployment['environment'][len(DEPLOYMENT_PREFIX):]
-            environment_url = '{}/{}'.format(target, pr_number)
-        else:
-            environment_url = None
-        url = '{}/repos/{}/deployments/{}/statuses'.format(
-            self._host, self._github_project, deployment['id']
-        )
-
-        gh_request('POST', url, {
-            'state': state,
-            'description': description,
-            'environment_url': environment_url
-        }, 'application/vnd.github.ant-man-preview+json')
-
-def is_open(pull_request):
-    return not pull_request['closed_at']
-
-def has_mirroring_label(pull_request):
-    for label in pull_request['labels']:
-        if label['name'] == LABEL:
-            return True
-
-    return False
-
-def should_be_mirrored(project, pull_request):
-    return (
-        is_open(pull_request) and (
-            has_mirroring_label(pull_request) or (
-                pull_request['user']['login'] not in AUTOMATION_GITHUB_USERS and
-                pull_request['author_association'] in TRUSTED_AUTHOR_ASSOCIATIONS
-            )
-        )
-    )
-
-def is_deployed(host, deployment):
-    worktree_name = deployment['environment'][len(DEPLOYMENT_PREFIX):]
-    url = '{}/.git/worktrees/{}/HEAD'.format(host, worktree_name)
-    logger.info('Issuing request: GET %s', url)
-    response = requests.get(url)
-
-    logger.info('Response status code: %s', response.status_code)
-    if response.status_code != 200:
-        return False
-
-    logger.info('Response text: %s', response.text.strip())
-    return response.text.strip() == deployment['sha']
-
-def update_mirror_refs(project, pull_request):
-    '''Update the WPT refs that control mirroring of this pull request.
-
-    Two sets of refs are used to control wptpr.live's mirroring of pull
-    requests:
-
-        1. refs/prs-trusted-for-preview/{number}
-        2. refs/prs-open/{number}
-
-    wptpr.live will only mirror a pull request if both exist for the given pull
-    request number; otherwise the pull request is either not open or is not
-    trustworthy (e.g. came from someone who doesn't have push access anyway.)
-
-    This method returns the revision that is being mirrored, or None if the
-    pull request should not be mirrored.
-    '''
-
-    refspec_trusted = 'prs-trusted-for-preview/{number}'.format(
-        **pull_request
-    )
-    refspec_open = 'prs-open/{number}'.format(**pull_request)
-
-    revision_latest = pull_request['head']['sha']
-    revision_trusted = project.get_ref_revision(refspec_trusted)
-    revision_open = project.get_ref_revision(refspec_open)
-
-    if should_be_mirrored(project, pull_request):
-        logger.info('Pull Request should be mirrored')
-
-        if revision_trusted is None:
-            project.create_ref(refspec_trusted, revision_latest)
-        elif revision_trusted != revision_latest:
-            project.update_ref(refspec_trusted, revision_latest)
-
-        if revision_open is None:
-            project.create_ref(refspec_open, revision_latest)
-        elif revision_open != revision_latest:
-            project.update_ref(refspec_open, revision_latest)
-
-        return revision_latest
-
-    logger.info('Pull Request should not be mirrored')
-
-    if not has_mirroring_label(pull_request) and revision_trusted is not None:
-        project.delete_ref(refspec_trusted)
-
-    if revision_open is not None and not is_open(pull_request):
-        project.delete_ref(refspec_open)
-
-    # No revision to be deployed to wptpr.live
-    return None
-
-class DeploymentFailedException(Exception):
-    pass
-
-def deploy(project, target, pull_request, revision, timeout):
-    '''Create a GitHub deployment for the given pull request and revision.
-
-    This method creates a pending GitHub deployment, waits for the
-    corresponding revision to be available on wptpr.live and marks the
-    deployment as successful. If the revision does not appear in the given
-    timeout, the deployment is marked as errored instead.'''
-    if project.get_deployment(revision) is not None:
-        return
-
-    deployment = project.create_deployment(pull_request, revision)
-
-    message = 'Waiting up to {} seconds for Deployment {} to be available on {}'.format(
-        timeout, deployment['environment'], target
-    )
-    logger.info(message)
-    project.add_deployment_status(target, deployment, 'pending', message)
-
-    start = time.time()
-    while not is_deployed(target, deployment):
-        if time.time() - start > timeout:
-            message = 'Deployment did not become available after {} seconds'.format(timeout)
-            project.add_deployment_status(target, deployment, 'error', message)
-            raise DeploymentFailedException(message)
-
-        time.sleep(POLLING_PERIOD)
-
-    result = project.add_deployment_status(target, deployment, 'success')
-    logger.info(json.dumps(result, indent=2))
-
-def main(host, github_project, target, timeout):
-    project = Project(host, github_project)
-
-    with open(os.environ['GITHUB_EVENT_PATH']) as handle:
-        data = json.load(handle)
-
-    logger.info('Event data: %s', json.dumps(data, indent=2))
-
-    pull_request = data['pull_request']
-
-    logger.info('Processing Pull Request #%(number)d', pull_request)
-
-    revision_to_mirror = update_mirror_refs(project, pull_request)
-    if revision_to_mirror:
-        deploy(project, target, pull_request, revision_to_mirror, timeout)
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(
-        description='''Mirror a pull request to an externally-hosted preview
-            system, and create a GitHub Deployment associated with the pull
-            request pointing at the preview.'''
-    )
-    parser.add_argument(
-        '--host', required=True, help='the location of the GitHub API server'
-    )
-    parser.add_argument(
-        '--github-project',
-        required=True,
-        help='''the GitHub organization and GitHub project name, separated by
-            a forward slash (e.g. "web-platform-tests/wpt")'''
-    )
-    parser.add_argument(
-        '--target',
-        required=True,
-        help='''the URL of the website to which submission previews are
-            expected to become available'''
-    )
-    parser.add_argument(
-        '--timeout',
-        type=int,
-        required=True,
-        help='''the number of seconds to wait for a submission preview to
-            become available before reporting a GitHub Deployment failure'''
-    )
-
-    values = dict(vars(parser.parse_args()))
-    main(**values)
diff --git a/tools/ci/tests/test_pr_preview.py b/tools/ci/tests/test_pr_preview.py
deleted file mode 100644
index a268383..0000000
--- a/tools/ci/tests/test_pr_preview.py
+++ /dev/null
@@ -1,683 +0,0 @@
-try:
-    from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
-except ImportError:
-    # Python 3 case
-    from http.server import BaseHTTPRequestHandler, HTTPServer
-import contextlib
-import errno
-import json
-import os
-import shutil
-import stat
-import subprocess
-import sys
-import tempfile
-import threading
-
-sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
-import pr_preview
-
-
-TEST_HOST = 'localhost'
-
-
-def same_members(a, b):
-    if len(a) != len(b):
-        return False
-    a_copy = list(a)
-    for elem in b:
-        try:
-            a_copy.remove(elem)
-        except ValueError:
-            return False
-
-    return len(a_copy) == 0
-
-
-# When these tests are executed in Windows, files in the temporary git
-# repositories may be marked as "read only" at the moment they are intended to
-# be deleted. The following handler for `shutil.rmtree` accounts for this by
-# making the files writable and attempting to delete them a second time.
-#
-# Source:
-# https://stackoverflow.com/questions/1213706/what-user-do-python-scripts-run-as-in-windows
-def handle_remove_readonly(func, path, exc):
-    excvalue = exc[1]
-    candidates = (os.rmdir, os.remove, os.unlink)
-    if func in candidates and excvalue.errno == errno.EACCES:
-        os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)  # 0777
-        func(path)
-    else:
-        raise
-
-
-class MockHandler(BaseHTTPRequestHandler, object):
-    def do_all(self):
-        path = self.path.split('?')[0]
-        request_body = None
-
-        if 'Content-Length' in self.headers:
-            request_body = self.rfile.read(
-                int(self.headers['Content-Length'])
-            ).decode('utf-8')
-
-            if self.headers.get('Content-Type') == 'application/json':
-                request_body = json.loads(request_body)
-
-        for request, response in self.server.expected_traffic:
-            if request[0] != self.command:
-                continue
-            if request[1] != path:
-                continue
-            body_matches = True
-            for key in request[2]:
-                body_matches &= request[2][key] == request_body.get(key)
-            if not body_matches:
-                continue
-            break
-        else:
-            request = (self.command, path, request_body)
-            response = (400, {})
-
-        self.server.actual_traffic.append((request, response))
-        self.send_response(response[0])
-        self.end_headers()
-        if self.server.reponse_body_is_json:
-            self.wfile.write(json.dumps(response[1]).encode('utf-8'))
-        else:
-            self.wfile.write(response[1].encode('utf-8'))
-
-    def do_DELETE(self):
-        return self.do_all()
-
-    def do_GET(self):
-        return self.do_all()
-
-    def do_PATCH(self):
-        return self.do_all()
-
-    def do_POST(self):
-        return self.do_all()
-
-
-class MockServer(HTTPServer, object):
-    '''HTTP server that responds to all requests with status code 200 and body
-    '{}' unless an alternative status code and body are specified for the given
-    method and path in the `responses` parameter.'''
-    def __init__(self, address, expected_traffic, reponse_body_is_json=True):
-        super(MockServer, self).__init__(address, MockHandler)
-        self.expected_traffic = expected_traffic
-        self.actual_traffic = []
-        self.reponse_body_is_json = reponse_body_is_json
-
-    def __enter__(self):
-        threading.Thread(target=lambda: self.serve_forever()).start()
-        return self
-
-    def __exit__(self, *args):
-        self.shutdown()
-
-
-class Requests(object):
-    get_rate = ('GET', '/rate_limit', {})
-    ref_create_open = (
-        'POST', '/repos/test-org/test-repo/git/refs', {'ref':'refs/prs-open/45'}
-    )
-    ref_create_trusted = (
-        'POST',
-        '/repos/test-org/test-repo/git/refs',
-        {'ref':'refs/prs-trusted-for-preview/45'}
-    )
-    ref_get_open = (
-        'GET', '/repos/test-org/test-repo/git/refs/prs-open/45', {}
-    )
-    ref_get_trusted = (
-        'GET', '/repos/test-org/test-repo/git/refs/prs-trusted-for-preview/45', {}
-    )
-    ref_update_open = (
-        'PATCH', '/repos/test-org/test-repo/git/refs/prs-open/45', {}
-    )
-    ref_update_trusted = (
-        'PATCH', '/repos/test-org/test-repo/git/refs/prs-trusted-for-preview/45', {}
-    )
-    ref_delete_open = (
-        'DELETE', '/repos/test-org/test-repo/git/refs/prs-open/45', {}
-    )
-    ref_delete_trusted = (
-        'DELETE', '/repos/test-org/test-repo/git/refs/prs-trusted-for-preview/45', {}
-    )
-    deployment_get = ('GET', '/repos/test-org/test-repo/deployments', {})
-    deployment_create = ('POST', '/repos/test-org/test-repo/deployments', {})
-    deployment_status_create_pending = (
-        'POST',
-        '/repos/test-org/test-repo/deployments/24601/statuses',
-        {'state':'pending'}
-    )
-    deployment_status_create_error = (
-        'POST',
-        '/repos/test-org/test-repo/deployments/24601/statuses',
-        {'state':'error'}
-    )
-    deployment_status_create_success = (
-        'POST',
-        '/repos/test-org/test-repo/deployments/24601/statuses',
-        {'state':'success'}
-    )
-    preview = ('GET', '/.git/worktrees/45/HEAD', {})
-
-
-class Responses(object):
-    no_limit = (200, {
-        'resources': {
-            'search': {
-                'remaining': 100,
-                'limit': 100
-            },
-            'core': {
-                'remaining': 100,
-                'limit': 100
-            }
-        }
-    })
-
-
-@contextlib.contextmanager
-def temp_repo():
-    original_dir = os.getcwd()
-    directory = tempfile.mkdtemp()
-    os.chdir(directory)
-
-    try:
-        subprocess.check_call(['git', 'init'], cwd=directory)
-        # Explicitly create the default branch.
-        subprocess.check_call(
-            ['git', 'checkout', '-b', 'master'],
-            cwd=directory
-        )
-        subprocess.check_call(
-            ['git', 'config', 'user.name', 'example'],
-            cwd=directory
-        )
-        subprocess.check_call(
-            ['git', 'config', 'user.email', 'example@example.com'],
-            cwd=directory
-        )
-        subprocess.check_call(
-            ['git', 'commit', '--allow-empty', '-m', 'first'],
-            cwd=directory
-        )
-
-        yield directory
-    finally:
-        os.chdir(original_dir)
-        shutil.rmtree(
-            directory, ignore_errors=False, onerror=handle_remove_readonly
-        )
-
-def update_mirror_refs(pull_request, expected_traffic):
-    os.environ['GITHUB_TOKEN'] = 'c0ffee'
-
-    github_server = MockServer((TEST_HOST, 0), expected_traffic)
-    github_port = github_server.server_address[1]
-
-    method_threw = False
-    with temp_repo(), github_server:
-        project = pr_preview.Project(
-            'http://{}:{}'.format(TEST_HOST, github_port),
-            'test-org/test-repo',
-        )
-        try:
-            pr_preview.update_mirror_refs(project, pull_request)
-        except pr_preview.GitHubRateLimitException:
-            method_threw = True
-
-    return (
-        method_threw,
-        github_server.actual_traffic,
-    )
-
-
-def deploy(pr_num, revision, expected_github_traffic, expected_preview_traffic):
-    os.environ['GITHUB_TOKEN'] = 'c0ffee'
-
-    github_server = MockServer((TEST_HOST, 0), expected_github_traffic)
-    github_port = github_server.server_address[1]
-    preview_server = MockServer((TEST_HOST, 0), expected_preview_traffic, reponse_body_is_json=False)
-    preview_port = preview_server.server_address[1]
-
-    method_threw = False
-    with github_server, preview_server:
-        project = pr_preview.Project(
-            'http://{}:{}'.format(TEST_HOST, github_port),
-            'test-org/test-repo',
-        )
-        target = 'http://{}:{}'.format(TEST_HOST, preview_port)
-        pull_request = {'number': pr_num}
-        timeout = 1
-        try:
-            pr_preview.deploy(project, target, pull_request, revision, timeout)
-        except (pr_preview.GitHubRateLimitException, pr_preview.DeploymentFailedException):
-            method_threw = True
-
-    return (
-        method_threw,
-        github_server.actual_traffic,
-        preview_server.actual_traffic
-    )
-
-def test_update_mirror_refs_fail_rate_limited():
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        'labels': [],
-        'user': {'login': 'stephenmcgruer'},
-        'author_association': 'COLLABORATOR',
-        'closed_at': None,
-    }
-    expected_traffic = [
-        (Requests.get_rate, (
-            200,
-            {
-                'resources': {
-                    'core': {
-                        'remaining': 1,
-                        'limit': 10
-                    }
-                }
-            }
-        ))
-    ]
-
-    method_threw, actual_traffic = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_synchronize_ignore_closed():
-    # No existing refs, but a closed PR event comes in. Nothing should happen.
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        'labels': [],
-        'user': {'login': 'stephenmcgruer'},
-        'author_association': 'COLLABORATOR',
-        'closed_at': '2019-10-28',
-    }
-    expected_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_trusted, (404, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_open, (404, {})),
-    ]
-
-    method_threw, actual_traffic = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert not method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_update_mirror_refs_collaborator():
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        'labels': [],
-        'user': {'login': 'stephenmcgruer'},
-        'author_association': 'COLLABORATOR',
-        'closed_at': None,
-    }
-    expected_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_trusted, (404, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_open, (404, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_create_open, (200, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_create_trusted, (200, {})),
-    ]
-
-    method_threw, actual_traffic, = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert not method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_update_mirror_refs_ignore_collaborator_bot():
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        'labels': [],
-        'user': {'login': 'chromium-wpt-export-bot'},
-        'author_association': 'COLLABORATOR',
-        'closed_at': None,
-    }
-    expected_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_trusted, (404, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_open, (404, {})),
-    ]
-
-    method_threw, actual_traffic = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert not method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_update_mirror_refs_ignore_untrusted_contributor():
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        'labels': [],
-        'user': {'login': 'stephenmcgruer'},
-        'author_association': 'CONTRIBUTOR',
-        'closed_at': None,
-    }
-    expected_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_trusted, (404, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_open, (404, {})),
-    ]
-
-    method_threw, actual_traffic = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert not method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_update_mirror_refs_trusted_contributor():
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        # user here is a contributor (untrusted), but the issue
-        # has been labelled as safe.
-        'labels': [{'name': 'safe for preview'}],
-        'user': {'login': 'Hexcles'},
-        'author_association': 'CONTRIBUTOR',
-        'closed_at': None,
-    }
-    expected_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_trusted, (404, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_open, (404, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_create_open, (200, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_create_trusted, (200, {})),
-    ]
-
-    method_threw, actual_traffic = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert not method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_synchronize_sync_bot_with_label():
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        # user here is a bot which is normally not mirrored,
-        # but the issue has been labelled as safe.
-        'labels': [{'name': 'safe for preview'}],
-        'user': {'login': 'chromium-wpt-export-bot'},
-        'author_association': 'COLLABORATOR',
-        'closed_at': None,
-    }
-    expected_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_trusted, (404, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_open, (404, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_create_open, (200, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_create_trusted, (200, {})),
-    ]
-
-    method_threw, actual_traffic = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert not method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_update_mirror_refs_update_collaborator():
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        'labels': [],
-        'user': {'login': 'stephenmcgruer'},
-        'author_association': 'COLLABORATOR',
-        'closed_at': None,
-    }
-    expected_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_trusted, (
-            200,
-            {
-                'object': {'sha': 'def234'},
-            }
-        )),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_open, (
-            200,
-            {
-                'object': {'sha': 'def234'},
-            }
-        )),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_update_open, (200, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_update_trusted, (200, {})),
-    ]
-
-    method_threw, actual_traffic = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert not method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_synchronize_update_member():
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        'labels': [],
-        'user': {'login': 'jgraham'},
-        'author_association': 'MEMBER',
-        'closed_at': None,
-    }
-    expected_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_trusted, (
-            200,
-            {
-                'object': {'sha': 'def234'},
-            }
-        )),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_open, (
-            200,
-            {
-                'object': {'sha': 'def234'},
-            }
-        )),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_update_open, (200, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_update_trusted, (200, {}))
-    ]
-
-    method_threw, actual_traffic = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert not method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_update_mirror_refs_delete_collaborator():
-    pull_request = {
-        'number': 45,
-        'head': {'sha': 'abc123'},
-        'labels': [],
-        'user': {'login': 'stephenmcgruer'},
-        'author_association': 'COLLABORATOR',
-        'closed_at': 2019-10-30,
-    }
-    expected_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_trusted, (
-            200,
-            {
-                'object': {'sha': 'def234'},
-            }
-        )),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_get_open, (
-            200,
-            {
-                'object': {'sha': 'def234'},
-            }
-        )),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_delete_trusted, (204, None)),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.ref_delete_open, (204, None)),
-    ]
-
-    method_threw, actual_traffic = update_mirror_refs(
-        pull_request, expected_traffic
-    )
-
-    assert not method_threw
-    assert same_members(expected_traffic, actual_traffic)
-
-def test_deploy_fail_rate_limited():
-    expected_github_traffic = [
-        (Requests.get_rate, (
-            200,
-            {
-                'resources': {
-                    'core': {
-                        'remaining': 1,
-                        'limit': 10
-                    }
-                }
-            }
-        ))
-    ]
-    expected_preview_traffic = []
-
-    pr_num = 45
-    revision = "abcdef123"
-    method_threw, actual_github_traffic, actual_preview_traffic = deploy(
-        pr_num, revision, expected_github_traffic, expected_preview_traffic
-    )
-
-    assert method_threw
-    assert actual_github_traffic == expected_github_traffic
-    assert actual_preview_traffic == expected_preview_traffic
-
-def test_deploy_success():
-    pr_num = 45
-    revision = 'abcdef123'
-
-    expected_github_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_get, (200, [])),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_create, (200, {
-            'id': 24601,
-            'sha': revision,
-            'environment': 'wpt-preview-45',
-        })),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_status_create_pending, (200, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_status_create_success, (200, {}))
-    ]
-    expected_preview_traffic = [
-        (Requests.preview, (200, revision))
-    ]
-
-    method_threw, actual_github_traffic, actual_preview_traffic = deploy(
-        pr_num, revision, expected_github_traffic, expected_preview_traffic
-    )
-
-    assert not method_threw
-    assert actual_github_traffic == expected_github_traffic
-    assert actual_preview_traffic == expected_preview_traffic
-
-def test_deploy_timeout_missing():
-    pr_num = 45
-    revision = 'abcdef123'
-
-    expected_github_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_get, (200, [])),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_create, (200, {
-            'id': 24601,
-            'sha': revision,
-            'environment': 'wpt-preview-45',
-        })),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_status_create_pending, (200, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_status_create_error, (200, {}))
-    ]
-    expected_preview_traffic = [
-        (Requests.preview, (404, ""))
-    ]
-
-    method_threw, actual_github_traffic, actual_preview_traffic = deploy(
-        pr_num, revision, expected_github_traffic, expected_preview_traffic
-    )
-
-    assert method_threw
-    assert expected_github_traffic == actual_github_traffic
-    ping_count = len(actual_preview_traffic)
-    assert ping_count > 0
-    assert actual_preview_traffic == expected_preview_traffic * ping_count
-
-def test_deploy_timeout_wrong_revision():
-    pr_num = 45
-    revision = 'abcdef123'
-
-    expected_github_traffic = [
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_get, (200, [])),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_create, (200, {
-            'id': 24601,
-            'sha': revision,
-            'environment': 'wpt-preview-45',
-        })),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_status_create_pending, (200, {})),
-        (Requests.get_rate, Responses.no_limit),
-        (Requests.deployment_status_create_error, (200, {}))
-    ]
-    expected_preview_traffic = [
-        # wptpr.live has the wrong revision deployed
-        (Requests.preview, (200, 'ghijkl456'))
-    ]
-
-    method_threw, actual_github_traffic, actual_preview_traffic = deploy(
-        pr_num, revision, expected_github_traffic, expected_preview_traffic
-    )
-
-    assert method_threw
-    assert expected_github_traffic == actual_github_traffic
-    ping_count = len(actual_preview_traffic)
-    assert ping_count > 0
-    assert actual_preview_traffic == expected_preview_traffic * ping_count