diff --git a/testing/__init__.py b/testing/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/testing/__init__.py
@@ -0,0 +1 @@
+
diff --git a/testing/api_clients.cfg b/testing/api_clients.cfg
new file mode 100644
index 0000000..c9588df
--- /dev/null
+++ b/testing/api_clients.cfg
@@ -0,0 +1,43 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+# Defines fake monorail api clients for testing
+
+clients {
+  client_email: "123456789@developer.gserviceaccount.com"
+  client_id: "123456789.apps.googleusercontent.com"
+  allowed_origins: "chicken.test"
+  allowed_origins: "cow.test"
+  display_name: "johndoe@example.com"
+  description: "John Doe needs api access"
+  project_permissions {
+    project: "chromium"
+    role: contributor
+  }
+  contacts: "johndoe@example.com"
+  qpm_limit: 1
+}
+
+clients {
+  client_email: "bugdroid1@chromium.org"
+  client_id: "987654321.apps.googleusercontent.com"
+  description: "bugdroid"
+  project_permissions {
+    project: "chromium"
+    role: committer
+  }
+  contacts: "bugdroidowner@example.com"
+}
+
+clients {
+  client_id: "98723764876"
+  allowed_origins: "goat.test"
+  description: "test client_id alone is sufficient to access API."
+  project_permissions {
+    project: "chromium"
+    role: committer
+  }
+  contacts: "client_id_only@example.com"
+}
diff --git a/testing/fake.py b/testing/fake.py
new file mode 100644
index 0000000..33d5ed0
--- /dev/null
+++ b/testing/fake.py
@@ -0,0 +1,2901 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Fake object classes that are useful for unit tests."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import collections
+import itertools
+import logging
+import re
+import sys
+import time
+
+from six import string_types
+
+import settings
+from features import filterrules_helpers
+from framework import exceptions
+from framework import framework_bizobj
+from framework import framework_constants
+from framework import framework_helpers
+from framework import monorailrequest
+from framework import permissions
+from framework import profiler
+from framework import validate
+from proto import features_pb2
+from proto import project_pb2
+from proto import tracker_pb2
+from proto import user_pb2
+from proto import usergroup_pb2
+from services import caches
+from services import config_svc
+from services import features_svc
+from services import project_svc
+from tracker import tracker_bizobj
+from tracker import tracker_constants
+
+# Many fakes return partial or constant values, regardless of their arguments.
+# pylint: disable=unused-argument
+
+BOUNDARY = '-----thisisaboundary'
+OWNER_ROLE = 'OWNER_ROLE'
+COMMITTER_ROLE = 'COMMITTER_ROLE'
+CONTRIBUTOR_ROLE = 'CONTRIBUTOR_ROLE'
+EDITOR_ROLE = 'EDITOR_ROLE'
+FOLLOWER_ROLE = 'FOLLOWER_ROLE'
+
+def Hotlist(
+    hotlist_name, hotlist_id, hotlist_item_fields=None,
+    is_private=False, owner_ids=None, editor_ids=None, follower_ids=None,
+    default_col_spec=None, summary=None, description=None):
+  hotlist_id = hotlist_id or hash(hotlist_name)
+  return features_pb2.MakeHotlist(
+      hotlist_name, hotlist_item_fields=hotlist_item_fields,
+      hotlist_id=hotlist_id, is_private=is_private, owner_ids=owner_ids or [],
+      editor_ids=editor_ids or [], follower_ids=follower_ids or [],
+      default_col_spec=default_col_spec, summary=summary,
+      description=description)
+
+def HotlistItem(issue_id, rank=None, adder_id=None, date_added=None, note=None):
+  return features_pb2.MakeHotlistItem(issue_id=issue_id, rank=rank,
+                                      adder_id=adder_id, date_added=date_added,
+                                      note=None)
+
+def Project(
+    project_name='proj', project_id=None, state=project_pb2.ProjectState.LIVE,
+    access=project_pb2.ProjectAccess.ANYONE, moved_to=None,
+    cached_content_timestamp=None,
+    owner_ids=None, committer_ids=None, contributor_ids=None):
+  """Returns a project protocol buffer with the given attributes."""
+  project_id = project_id or hash(project_name)
+  return project_pb2.MakeProject(
+      project_name, project_id=project_id, state=state, access=access,
+      moved_to=moved_to, cached_content_timestamp=cached_content_timestamp,
+      owner_ids=owner_ids, committer_ids=committer_ids,
+      contributor_ids=contributor_ids)
+
+
+def MakeTestFieldDef(
+    field_id, project_id, field_type, field_name='', applic_type=None,
+    applic_pred=None, is_required=False, is_niche=False, is_multivalued=False,
+    min_value=None, max_value=None, regex=None, needs_member=False,
+    needs_perm=None, grants_perm=None, notify_on=None, date_action_str=None,
+    docstring=None, admin_ids=None, editor_ids=None, approval_id=None,
+    is_phase_field=False, is_restricted_field=False):
+  return  tracker_bizobj.MakeFieldDef(
+        field_id, project_id, field_name, field_type, applic_type, applic_pred,
+        is_required, is_niche, is_multivalued, min_value, max_value, regex,
+        needs_member, needs_perm, grants_perm, notify_on, date_action_str,
+        docstring, False,
+        approval_id=approval_id, is_phase_field=is_phase_field,
+        is_restricted_field=is_restricted_field, admin_ids=admin_ids,
+        editor_ids=editor_ids)
+
+def MakeTestApprovalDef(approval_id, approver_ids=None, survey=None):
+  return tracker_pb2.ApprovalDef(
+      approval_id=approval_id,
+      approver_ids = approver_ids,
+      survey = survey)
+
+def MakePhase(phase_id, name='', rank=0):
+  return tracker_pb2.Phase(phase_id=phase_id, name=name, rank=rank)
+
+
+def MakeApprovalValue(
+    approval_id,
+    status=tracker_pb2.ApprovalStatus.NOT_SET,
+    setter_id=None,
+    set_on=None,
+    approver_ids=None,
+    phase_id=None):
+  if approver_ids is None:
+    approver_ids = []
+  return tracker_pb2.ApprovalValue(
+      approval_id=approval_id,
+      status=status,
+      setter_id=setter_id,
+      set_on=set_on,
+      approver_ids=approver_ids,
+      phase_id=phase_id)
+
+
+def MakeFieldValue(
+    field_id,
+    int_value=None,
+    str_value=None,
+    user_id=None,
+    date_value=None,
+    url_value=None,
+    derived=None,
+    phase_id=None):
+  return tracker_pb2.FieldValue(
+      field_id=field_id,
+      int_value=int_value,
+      str_value=str_value,
+      user_id=user_id,
+      date_value=date_value,
+      url_value=url_value,
+      derived=derived,
+      phase_id=phase_id)
+
+
+def MakeTestIssue(
+    project_id, local_id, summary, status, owner_id, labels=None,
+    derived_labels=None, derived_status=None, merged_into=0, star_count=0,
+    derived_owner_id=0, issue_id=None, reporter_id=None, opened_timestamp=None,
+    closed_timestamp=None, modified_timestamp=None, is_spam=False,
+    component_ids=None, project_name=None, field_values=None, cc_ids=None,
+    derived_cc_ids=None, assume_stale=True, phases=None, approval_values=None,
+    merged_into_external=None, attachment_count=0, derived_component_ids=None):
+  """Easily make an Issue for testing."""
+  issue = tracker_pb2.Issue()
+  issue.project_id = project_id
+  issue.project_name = project_name
+  issue.local_id = local_id
+  issue.issue_id = issue_id if issue_id else 100000 + local_id
+  issue.reporter_id = reporter_id if reporter_id else owner_id
+  issue.summary = summary
+  issue.status = status
+  issue.owner_id = owner_id
+  issue.derived_owner_id = derived_owner_id
+  issue.star_count = star_count
+  issue.merged_into = merged_into
+  issue.merged_into_external = merged_into_external
+  issue.is_spam = is_spam
+  issue.attachment_count = attachment_count
+  if cc_ids:
+    issue.cc_ids = cc_ids
+  if derived_cc_ids:
+    issue.derived_cc_ids = derived_cc_ids
+  issue.assume_stale = assume_stale
+  if opened_timestamp:
+    issue.opened_timestamp = opened_timestamp
+    issue.owner_modified_timestamp = opened_timestamp
+    issue.status_modified_timestamp = opened_timestamp
+    issue.component_modified_timestamp = opened_timestamp
+  if modified_timestamp:
+    issue.modified_timestamp = modified_timestamp
+  if closed_timestamp:
+    issue.closed_timestamp = closed_timestamp
+  if labels is not None:
+    if isinstance(labels, string_types):
+      labels = labels.split()
+    issue.labels.extend(labels)
+  if derived_labels is not None:
+    if isinstance(derived_labels, string_types):
+      derived_labels = derived_labels.split()
+    issue.derived_labels.extend(derived_labels)
+  if derived_status is not None:
+    issue.derived_status = derived_status
+  if component_ids is not None:
+    issue.component_ids = component_ids
+  if derived_component_ids is not None:
+    issue.derived_component_ids = derived_component_ids
+  if field_values is not None:
+    issue.field_values = field_values
+  if phases is not None:
+    issue.phases = phases
+  if approval_values is not None:
+    issue.approval_values = approval_values
+  return issue
+
+
+def MakeTestComponentDef(project_id, comp_id, path='', cc_ids=None):
+  if cc_ids is None:
+    cc_ids = []
+  return tracker_bizobj.MakeComponentDef(
+      comp_id, project_id, path, '', False, [], cc_ids, None, None)
+
+
+def MakeTestConfig(project_id, labels, statuses):
+  """Convenient function to make a ProjectIssueConfig object."""
+  config = tracker_bizobj.MakeDefaultProjectIssueConfig(project_id)
+  if isinstance(labels, string_types):
+    labels = labels.split()
+  if isinstance(statuses, string_types):
+    statuses = statuses.split()
+  config.well_known_labels = [
+      tracker_pb2.LabelDef(label=lab) for lab in labels]
+  config.well_known_statuses = [
+      tracker_pb2.StatusDef(status=stat) for stat in statuses]
+  return config
+
+
+class MonorailConnection(object):
+  """Fake connection to databases for use in tests."""
+
+  def Commit(self):
+    pass
+
+  def Close(self):
+    pass
+
+
+class MonorailRequest(monorailrequest.MonorailRequest):
+  """Subclass of MonorailRequest suitable for testing."""
+
+  def __init__(self, services, user_info=None, project=None, perms=None,
+               hotlist=None, **kwargs):
+    """Construct a test MonorailRequest.
+
+    Typically, this is constructed via testing.helpers.GetRequestObjects,
+    which also causes url parsing and optionally initializes the user,
+    project, and permissions info.
+
+    Args:
+      services: connections to backends.
+      user_info: a dict of user attributes to set on a MonorailRequest object.
+        For example, "user_id: 5" causes self.auth.user_id=5.
+      project: the Project pb for this request.
+      perms: a PermissionSet for this request.
+    """
+    super(MonorailRequest, self).__init__(services, **kwargs)
+
+    if user_info is not None:
+      for key in user_info:
+        setattr(self.auth, key, user_info[key])
+      if 'user_id' in user_info:
+        self.auth.effective_ids = {user_info['user_id']}
+
+    self.perms = perms or permissions.ADMIN_PERMISSIONSET
+    self.profiler = profiler.Profiler()
+    self.project = project
+    self.hotlist = hotlist
+    if hotlist is not None:
+      self.hotlist_id = hotlist.hotlist_id
+
+class UserGroupService(object):
+  """Fake UserGroupService class for testing other code."""
+
+  def __init__(self):
+    # Test-only sequence of expunged users.
+    self.expunged_users_in_groups = []
+
+    self.group_settings = {}
+    self.group_members = {}
+    self.group_addrs = {}
+    self.role_dict = {}
+
+  def TestAddGroupSettings(
+      self,
+      group_id,
+      email,
+      who_can_view=None,
+      anyone_can_join=False,
+      who_can_add=None,
+      external_group_type=None,
+      last_sync_time=0,
+      friend_projects=None,
+      notify_members=True,
+      notify_group=False):
+    """Set up a fake group for testing.
+
+    Args:
+      group_id: int user ID of the new user group.
+      email: string email address to identify the user group.
+      who_can_view: string enum 'owners', 'members', or 'anyone'.
+      anyone_can_join: optional boolean to allow any users to join the group.
+      who_can_add: optional list of int user IDs of users who can add
+          more members to the group.
+      notify_members: optional boolean for if emails to this group should be
+          sent directly to members.
+      notify_group: optional boolean for if emails to this group should be
+          sent directly to the group email.
+    """
+    friend_projects = friend_projects or []
+    group_settings = usergroup_pb2.MakeSettings(
+        who_can_view or 'members', external_group_type, last_sync_time,
+        friend_projects, notify_members, notify_group)
+    self.group_settings[group_id] = group_settings
+    self.group_addrs[group_id] = email
+    # TODO(jrobbins): store the other settings.
+
+  def TestAddMembers(self, group_id, user_ids, role='member'):
+    self.group_members.setdefault(group_id, []).extend(user_ids)
+    for user_id in user_ids:
+      self.role_dict.setdefault(group_id, {})[user_id] = role
+
+  def LookupAllMemberships(self, _cnxn, user_ids, use_cache=True):
+    return {
+        user_id: self.LookupMemberships(_cnxn, user_id)
+        for user_id in user_ids
+    }
+
+  def LookupMemberships(self, _cnxn, user_id):
+    memberships = {
+        group_id for group_id, member_ids in self.group_members.items()
+        if user_id in member_ids}
+    return memberships
+
+  def DetermineWhichUserIDsAreGroups(self, _cnxn, user_ids):
+    return [uid for uid in user_ids
+            if uid in self.group_settings]
+
+  def GetAllUserGroupsInfo(self, cnxn):
+    infos = []
+    for group_id in self.group_settings:
+      infos.append(
+          (self.group_addrs[group_id],
+           len(self.group_members.get(group_id, [])),
+           self.group_settings[group_id], group_id))
+
+    return infos
+
+  def GetAllGroupSettings(self, _cnxn, group_ids):
+    return {gid: self.group_settings[gid]
+            for gid in group_ids
+            if gid in self.group_settings}
+
+  def GetGroupSettings(self, cnxn, group_id):
+    return self.GetAllGroupSettings(cnxn, [group_id]).get(group_id)
+
+  def CreateGroup(self, cnxn, services, email, who_can_view_members,
+                  ext_group_type=None, friend_projects=None):
+    friend_projects = friend_projects or []
+    group_id = services.user.LookupUserID(
+        cnxn, email, autocreate=True, allowgroups=True)
+    self.group_addrs[group_id] = email
+    group_settings = usergroup_pb2.MakeSettings(
+        who_can_view_members, ext_group_type, 0, friend_projects)
+    self.UpdateSettings(cnxn, group_id, group_settings)
+    return group_id
+
+  def DeleteGroups(self, cnxn, group_ids):
+    member_ids_dict, owner_ids_dict = self.LookupMembers(cnxn, group_ids)
+    citizens_id_dict = collections.defaultdict(list)
+    for g_id, user_ids in member_ids_dict.items():
+      citizens_id_dict[g_id].extend(user_ids)
+    for g_id, user_ids in owner_ids_dict.items():
+      citizens_id_dict[g_id].extend(user_ids)
+    for g_id, citizen_ids in citizens_id_dict.items():
+      # Remove group members, friend projects and settings
+      self.RemoveMembers(cnxn, g_id, citizen_ids)
+      self.group_settings.pop(g_id, None)
+
+  def LookupComputedMemberships(self, cnxn, domain, use_cache=True):
+    group_email = 'everyone@%s' % domain
+    group_id = self.LookupUserGroupID(cnxn, group_email, use_cache=use_cache)
+    if group_id:
+      return [group_id]
+
+    return []
+
+  def LookupUserGroupID(self, cnxn, group_email, use_cache=True):
+    for group_id in self.group_settings:
+      if group_email == self.group_addrs.get(group_id):
+        return group_id
+    return None
+
+  def LookupMembers(self, _cnxn, group_id_list):
+    members_dict = {}
+    owners_dict = {}
+    for gid in group_id_list:
+      members_dict[gid] = []
+      owners_dict[gid] = []
+      for mid in self.group_members.get(gid, []):
+        if self.role_dict.get(gid, {}).get(mid) == 'owner':
+          owners_dict[gid].append(mid)
+        elif self.role_dict.get(gid, {}).get(mid) == 'member':
+          members_dict[gid].append(mid)
+    return members_dict, owners_dict
+
+  def LookupAllMembers(self, _cnxn, group_id_list):
+    direct_members, direct_owners = self.LookupMembers(
+        _cnxn, group_id_list)
+    members_dict = {}
+    owners_dict = {}
+    for gid in group_id_list:
+      members = direct_members[gid]
+      owners = direct_owners[gid]
+      owners_dict[gid] = owners
+      members_dict[gid] = members
+      group_ids = set([uid for uid in members + owners
+                       if uid in self.group_settings])
+      while group_ids:
+        indirect_members, indirect_owners = self.LookupMembers(
+            _cnxn, group_ids)
+        child_members = set()
+        child_owners = set()
+        for _, children in indirect_members.items():
+          child_members.update(children)
+        for _, children in indirect_owners.items():
+          child_owners.update(children)
+        members_dict[gid].extend(list(child_members))
+        owners_dict[gid].extend(list(child_owners))
+        group_ids = set(self.DetermineWhichUserIDsAreGroups(
+            _cnxn, list(child_members) + list(child_owners)))
+      members_dict[gid] = list(set(members_dict[gid]))
+    return members_dict, owners_dict
+
+
+  def RemoveMembers(self, _cnxn, group_id, old_member_ids):
+    current_member_ids = self.group_members.get(group_id, [])
+    revised_member_ids = [mid for mid in current_member_ids
+                          if mid not in old_member_ids]
+    self.group_members[group_id] = revised_member_ids
+
+  def UpdateMembers(self, _cnxn, group_id, member_ids, new_role):
+    self.RemoveMembers(_cnxn, group_id, member_ids)
+    self.TestAddMembers(group_id, member_ids, new_role)
+
+  def UpdateSettings(self, _cnxn, group_id, group_settings):
+    self.group_settings[group_id] = group_settings
+
+  def ExpandAnyGroupEmailRecipients(self, cnxn, user_ids):
+    group_ids = set(self.DetermineWhichUserIDsAreGroups(cnxn, user_ids))
+    group_settings_dict = self.GetAllGroupSettings(cnxn, group_ids)
+    member_ids_dict, owner_ids_dict = self.LookupAllMembers(cnxn, group_ids)
+    indirect_ids = set()
+    direct_ids = {uid for uid in user_ids if uid not in group_ids}
+    for gid, group_settings in group_settings_dict.items():
+      if group_settings.notify_members:
+        indirect_ids.update(member_ids_dict.get(gid, set()))
+        indirect_ids.update(owner_ids_dict.get(gid, set()))
+      if group_settings.notify_group:
+        direct_ids.add(gid)
+
+    return list(direct_ids), list(indirect_ids)
+
+  def LookupVisibleMembers(
+      self, cnxn, group_id_list, perms, effective_ids, services):
+    settings_dict = self.GetAllGroupSettings(cnxn, group_id_list)
+    group_ids = list(settings_dict.keys())
+
+    direct_member_ids_dict, direct_owner_ids_dict = self.LookupMembers(
+        cnxn, group_ids)
+    all_member_ids_dict, all_owner_ids_dict = self.LookupAllMembers(
+        cnxn, group_ids)
+    visible_member_ids_dict = {}
+    visible_owner_ids_dict = {}
+    for gid in group_ids:
+      member_ids = all_member_ids_dict[gid]
+      owner_ids = all_owner_ids_dict[gid]
+      if permissions.CanViewGroupMembers(
+          perms, effective_ids, settings_dict[gid], member_ids, owner_ids, []):
+        visible_member_ids_dict[gid] = direct_member_ids_dict[gid]
+        visible_owner_ids_dict[gid] = direct_owner_ids_dict[gid]
+
+    return visible_member_ids_dict, visible_owner_ids_dict
+
+  def ValidateFriendProjects(self, cnxn, services, friend_projects):
+    project_names = list(filter(None, re.split('; |, | |;|,', friend_projects)))
+    id_dict = services.project.LookupProjectIDs(cnxn, project_names)
+    missed_projects = []
+    result = []
+    for p_name in project_names:
+      if p_name in id_dict:
+        result.append(id_dict[p_name])
+      else:
+        missed_projects.append(p_name)
+    error_msg = ''
+    if missed_projects:
+      error_msg = 'Project(s) %s do not exist' % ', '.join(missed_projects)
+      return None, error_msg
+    else:
+      return result, None
+
+  def ExpungeUsersInGroups(self, cnxn, ids):
+    self.expunged_users_in_groups.extend(ids)
+
+
+class CacheManager(object):
+
+  def __init__(self, invalidate_tbl=None):
+    self.last_call = None
+    self.cache_registry = collections.defaultdict(list)
+    self.processed_invalidations_up_to = 0
+
+  def RegisterCache(self, cache, kind):
+    """Register a cache to be notified of future invalidations."""
+    self.cache_registry[kind].append(cache)
+
+  def DoDistributedInvalidation(self, cnxn):
+    """Drop any cache entries that were invalidated by other jobs."""
+    self.last_call = 'DoDistributedInvalidation', cnxn
+
+  def StoreInvalidateRows(self, cnxn, kind, keys):
+    """Store database rows to let all frontends know to invalidate."""
+    self.last_call = 'StoreInvalidateRows', cnxn, kind, keys
+
+  def StoreInvalidateAll(self, cnxn, kind):
+    """Store a database row to let all frontends know to invalidate."""
+    self.last_call = 'StoreInvalidateAll', cnxn, kind
+
+
+
+class UserService(object):
+
+  def __init__(self):
+    """Creates a test-appropriate UserService object."""
+    self.users_by_email = {}  # {email: user_id, ...}
+    self.users_by_id = {}  # {user_id: email, ...}
+    self.test_users = {}  # {user_id: user_pb, ...}
+    self.visited_hotlists = {}  # user_id:[(hotlist_id, viewed), ...]
+    self.invite_rows = []  # (parent_id, child_id)
+    self.linked_account_rows = []  # (parent_id, child_id)
+    self.prefs_dict = {}  # {user_id: UserPrefs}
+
+  def TestAddUser(
+      self, email, user_id, add_user=True, banned=False, obscure_email=True):
+    """Add a user to the fake UserService instance.
+
+    Args:
+      email: Email of the user.
+      user_id: int user ID.
+      add_user: Flag whether user pb should be created, i.e. whether a
+          Monorail account should be created
+      banned: Boolean to set the user as banned
+      obscure_email: Boolean to determine whether to obscure the user's email.
+
+    Returns:
+      The User PB that was added, or None.
+    """
+    self.users_by_email[email] = user_id
+    self.users_by_id[user_id] = email
+
+    user = None
+    if add_user:
+      user = user_pb2.MakeUser(user_id)
+      user.is_site_admin = False
+      user.email = email
+      user.obscure_email = obscure_email
+      if banned:
+        user.banned = 'is banned'
+      self.test_users[user_id] = user
+
+    return user
+
+  def GetUser(self, cnxn, user_id):
+    return self.GetUsersByIDs(cnxn, [user_id])[user_id]
+
+  def _CreateUser(self, _cnxn, email):
+    if email in self.users_by_email:
+      return
+    user_id = framework_helpers.MurmurHash3_x86_32(email)
+    self.TestAddUser(email, user_id)
+
+  def _CreateUsers(self, cnxn, emails):
+    for email in emails:
+      self._CreateUser(cnxn, email)
+
+  def LookupUserID(self, cnxn, email, autocreate=False, allowgroups=False):
+    email_dict = self.LookupUserIDs(
+        cnxn, [email], autocreate=autocreate, allowgroups=allowgroups)
+    if email in email_dict:
+      return email_dict[email]
+    raise exceptions.NoSuchUserException('%r not found' % email)
+
+  def GetUsersByIDs(self, cnxn, user_ids, use_cache=True, skip_missed=False):
+    user_dict = {}
+    for user_id in user_ids:
+      if user_id and self.test_users.get(user_id):
+        user_dict[user_id] = self.test_users[user_id]
+      elif not skip_missed:
+        user_dict[user_id] = user_pb2.MakeUser(user_id)
+    return user_dict
+
+  def LookupExistingUserIDs(self, cnxn, emails):
+    email_dict = {
+        email: self.users_by_email[email]
+        for email in emails
+        if email in self.users_by_email}
+    return email_dict
+
+  def LookupUserIDs(self, cnxn, emails, autocreate=False,
+                    allowgroups=False):
+    email_dict = {}
+    needed_emails = [email.lower() for email in emails
+                     if email
+                     and not framework_constants.NO_VALUE_RE.match(email)]
+    for email in needed_emails:
+      user_id = self.users_by_email.get(email)
+      if not user_id:
+        if autocreate and validate.IsValidEmail(email):
+          self._CreateUser(cnxn, email)
+          user_id = self.users_by_email.get(email)
+        elif not autocreate:
+          raise exceptions.NoSuchUserException('%r' % email)
+      if user_id:
+        email_dict[email] = user_id
+    return email_dict
+
+  def LookupUserEmail(self, _cnxn, user_id):
+    email = self.users_by_id.get(user_id)
+    if not email:
+      raise exceptions.NoSuchUserException('No user has ID %r' % user_id)
+    return email
+
+  def LookupUserEmails(self, cnxn, user_ids, ignore_missed=False):
+    if ignore_missed:
+      user_dict = {}
+      for user_id in user_ids:
+        try:
+          user_dict[user_id] = self.LookupUserEmail(cnxn, user_id)
+        except exceptions.NoSuchUserException:
+          continue
+      return user_dict
+    user_dict = {
+        user_id: self.LookupUserEmail(cnxn, user_id)
+        for user_id in user_ids}
+    return user_dict
+
+  def UpdateUser(self, _cnxn, user_id, user):
+    """Updates the user pb."""
+    self.test_users[user_id] = user
+
+  def UpdateUserBan(self, _cnxn, user_id, user, is_banned=None,
+        banned_reason=None):
+    """Updates the user pb."""
+    self.test_users[user_id] = user
+    user.banned = banned_reason if is_banned else ''
+
+  def GetPendingLinkedInvites(self, cnxn, user_id):
+    invite_as_parent = [row[1] for row in self.invite_rows
+                        if row[0] == user_id]
+    invite_as_child = [row[0] for row in self.invite_rows
+                       if row[1] == user_id]
+    return invite_as_parent, invite_as_child
+
+  def InviteLinkedParent(self, cnxn, parent_id, child_id):
+    self.invite_rows.append((parent_id, child_id))
+
+  def AcceptLinkedChild(self, cnxn, parent_id, child_id):
+    if (parent_id, child_id) not in self.invite_rows:
+      raise exceptions.InputException('No such invite')
+    self.linked_account_rows.append((parent_id, child_id))
+    self.invite_rows = [
+        (p_id, c_id) for (p_id, c_id) in self.invite_rows
+        if p_id != parent_id and c_id != child_id]
+    self.GetUser(cnxn, parent_id).linked_child_ids.append(child_id)
+    self.GetUser(cnxn, child_id).linked_parent_id = parent_id
+
+  def UnlinkAccounts(self, _cnxn, parent_id, child_id):
+    """Delete a linked-account relationship."""
+    if not parent_id:
+      raise exceptions.InputException('Parent account is missing')
+    if not child_id:
+      raise exceptions.InputException('Child account is missing')
+    self.linked_account_rows = [(p, c) for (p, c) in self.linked_account_rows
+                                if (p, c) != (parent_id, child_id)]
+
+  def UpdateUserSettings(
+      self, cnxn, user_id, user, notify=None, notify_starred=None,
+      email_compact_subject=None, email_view_widget=None,
+      notify_starred_ping=None, obscure_email=None, after_issue_update=None,
+      is_site_admin=None, is_banned=None, banned_reason=None,
+      keep_people_perms_open=None, preview_on_hover=None,
+      vacation_message=None):
+    # notifications
+    if notify is not None:
+      user.notify_issue_change = notify
+    if notify_starred is not None:
+      user.notify_starred_issue_change = notify_starred
+    if notify_starred_ping is not None:
+      user.notify_starred_ping = notify_starred_ping
+    if email_compact_subject is not None:
+      user.email_compact_subject = email_compact_subject
+    if email_view_widget is not None:
+      user.email_view_widget = email_view_widget
+
+    # display options
+    if after_issue_update is not None:
+      user.after_issue_update = user_pb2.IssueUpdateNav(after_issue_update)
+    if preview_on_hover is not None:
+      user.preview_on_hover = preview_on_hover
+    if keep_people_perms_open is not None:
+      user.keep_people_perms_open = keep_people_perms_open
+
+    # misc
+    if obscure_email is not None:
+      user.obscure_email = obscure_email
+
+    # admin
+    if is_site_admin is not None:
+      user.is_site_admin = is_site_admin
+    if is_banned is not None:
+      if is_banned:
+        user.banned = banned_reason or 'No reason given'
+      else:
+        user.reset('banned')
+
+    # user availability
+    if vacation_message is not None:
+      user.vacation_message = vacation_message
+
+    return self.UpdateUser(cnxn, user_id, user)
+
+  def GetUsersPrefs(self, cnxn, user_ids, use_cache=True):
+    for user_id in user_ids:
+      if user_id not in self.prefs_dict:
+        self.prefs_dict[user_id] = user_pb2.UserPrefs(user_id=user_id)
+    return self.prefs_dict
+
+  def GetUserPrefs(self, cnxn, user_id, use_cache=True):
+    """Return a UserPrefs PB for the requested user ID."""
+    prefs_dict = self.GetUsersPrefs(cnxn, [user_id], use_cache=use_cache)
+    return prefs_dict[user_id]
+
+  def GetUserPrefsByEmail(self, cnxn, email, use_cache=True):
+    """Return a UserPrefs PB for the requested email, or an empty UserPrefs."""
+    try:
+      user_id = self.LookupUserID(cnxn, email)
+      user_prefs = self.GetUserPrefs(cnxn, user_id, use_cache=use_cache)
+    except exceptions.NoSuchUserException:
+      user_prefs = user_pb2.UserPrefs()
+    return user_prefs
+
+  def SetUserPrefs(self, cnxn, user_id, pref_values):
+    userprefs = self.GetUserPrefs(cnxn, user_id)
+    names_to_overwrite = {upv.name for upv in pref_values}
+    userprefs.prefs = [upv for upv in userprefs.prefs
+                       if upv.name not in names_to_overwrite]
+    userprefs.prefs.extend(pref_values)
+
+  def ExpungeUsers(self, cnxn, user_ids):
+    for user_id in user_ids:
+      self.test_users.pop(user_id, None)
+      self.prefs_dict.pop(user_id, None)
+      email = self.users_by_id.pop(user_id, None)
+      if email:
+        self.users_by_email.pop(email, None)
+
+    self.invite_rows = [row for row in self.invite_rows
+                        if row[0] not in user_ids and row[1] not in user_ids]
+    self.linked_account_rows = [
+        row for row in self.linked_account_rows
+        if row[0] not in user_ids and row[1] not in user_ids]
+
+  def TotalUsersCount(self, cnxn):
+    return len(self.users_by_id) - 1 if (
+        framework_constants.DELETED_USER_ID in self.users_by_id
+        ) else len(self.users_by_id)
+
+  def GetAllUserEmailsBatch(self, cnxn, limit=1000, offset=0):
+    sorted_user_ids = sorted(self.users_by_id.keys())
+    sorted_user_ids = [
+        user_id for user_id in sorted_user_ids
+        if user_id != framework_constants.DELETED_USER_ID]
+    emails = []
+    for i in range(offset, offset + limit):
+      try:
+        user_id = sorted_user_ids[i]
+        if user_id != framework_constants.DELETED_USER_ID:
+          emails.append(self.users_by_id[user_id])
+      except IndexError:
+        break
+    return emails
+
+  def GetRecentlyVisitedHotlists(self, _cnxn, user_id):
+    try:
+      return self.visited_hotlists[user_id]
+    except KeyError:
+      return []
+
+  def AddVisitedHotlist(self, _cnxn, user_id, hotlist_id, commit=True):
+    try:
+      user_visited_tuples = self.visited_hotlists[user_id]
+      self.visited_hotlists[user_id] = [
+          hid for hid in user_visited_tuples if hid != hotlist_id]
+    except KeyError:
+      self.visited_hotlists[user_id] = []
+    self.visited_hotlists[user_id].append(hotlist_id)
+
+  def ExpungeUsersHotlistsHistory(self, cnxn, user_ids, commit=True):
+    for user_id in user_ids:
+      self.visited_hotlists.pop(user_id, None)
+
+
+class AbstractStarService(object):
+  """Fake StarService."""
+
+  def __init__(self):
+    self.stars_by_item_id = {}
+    self.stars_by_starrer_id = {}
+    self.expunged_item_ids = []
+
+  def ExpungeStars(self, _cnxn, item_id, commit=True, limit=None):
+    self.expunged_item_ids.append(item_id)
+    old_starrers = self.stars_by_item_id.get(item_id, [])
+    self.stars_by_item_id[item_id] = []
+    for old_starrer in old_starrers:
+      if self.stars_by_starrer_id.get(old_starrer):
+        self.stars_by_starrer_id[old_starrer] = [
+            it for it in self.stars_by_starrer_id[old_starrer]
+            if it != item_id]
+
+  def ExpungeStarsByUsers(self, _cnxn, user_ids, limit=None):
+    for user_id in user_ids:
+      item_ids = self.stars_by_starrer_id.pop(user_id, [])
+      for item_id in item_ids:
+        starrers = self.stars_by_item_id.get(item_id, None)
+        if starrers:
+          self.stars_by_item_id[item_id] = [
+              starrer for starrer in starrers if starrer != user_id]
+
+  def LookupItemStarrers(self, _cnxn, item_id):
+    return self.stars_by_item_id.get(item_id, [])
+
+  def LookupItemsStarrers(self, cnxn, item_ids):
+    return {
+        item_id: self.LookupItemStarrers(cnxn, item_id) for item_id in item_ids}
+
+  def LookupStarredItemIDs(self, _cnxn, starrer_user_id):
+    return self.stars_by_starrer_id.get(starrer_user_id, [])
+
+  def IsItemStarredBy(self, cnxn, item_id, starrer_user_id):
+    return item_id in self.LookupStarredItemIDs(cnxn, starrer_user_id)
+
+  def CountItemStars(self, cnxn, item_id):
+    return len(self.LookupItemStarrers(cnxn, item_id))
+
+  def CountItemsStars(self, cnxn, item_ids):
+    return {item_id: self.CountItemStars(cnxn, item_id)
+            for item_id in item_ids}
+
+  def _SetStar(self, cnxn, item_id, starrer_user_id, starred):
+    if starred and not self.IsItemStarredBy(cnxn, item_id, starrer_user_id):
+      self.stars_by_item_id.setdefault(item_id, []).append(starrer_user_id)
+      self.stars_by_starrer_id.setdefault(starrer_user_id, []).append(item_id)
+
+    elif not starred and self.IsItemStarredBy(cnxn, item_id, starrer_user_id):
+      self.stars_by_item_id[item_id].remove(starrer_user_id)
+      self.stars_by_starrer_id[starrer_user_id].remove(item_id)
+
+  def SetStar(self, cnxn, item_id, starrer_user_id, starred):
+    self._SetStar(cnxn, item_id, starrer_user_id, starred)
+
+  def SetStarsBatch(
+      self, cnxn, item_id, starrer_user_ids, starred, commit=True):
+    for starrer_user_id in starrer_user_ids:
+      self._SetStar(cnxn, item_id, starrer_user_id, starred)
+
+
+class UserStarService(AbstractStarService):
+  pass
+
+
+class ProjectStarService(AbstractStarService):
+  pass
+
+
+class HotlistStarService(AbstractStarService):
+  pass
+
+
+class IssueStarService(AbstractStarService):
+
+  # pylint: disable=arguments-differ
+  def SetStar(
+      self, cnxn, services, _config, issue_id, starrer_user_id,
+      starred):
+    super(IssueStarService, self).SetStar(
+        cnxn, issue_id, starrer_user_id, starred)
+    try:
+      issue = services.issue.GetIssue(cnxn, issue_id)
+      issue.star_count += (1 if starred else -1)
+    except exceptions.NoSuchIssueException:
+      pass
+
+  # pylint: disable=arguments-differ
+  def SetStarsBatch(
+      self, cnxn, _service, _config, issue_id, starrer_user_ids,
+      starred):
+    super(IssueStarService, self).SetStarsBatch(
+        cnxn, issue_id, starrer_user_ids, starred)
+
+  def SetStarsBatch_SkipIssueUpdate(
+      self, cnxn, issue_id, starrer_user_ids, starred, commit=True):
+    super(IssueStarService, self).SetStarsBatch(
+        cnxn, issue_id, starrer_user_ids, starred)
+
+
+class ProjectService(object):
+  """Fake ProjectService object.
+
+  Provides methods for creating users and projects, which are accessible
+  through parts of the real ProjectService interface.
+  """
+
+  def __init__(self):
+    self.test_projects = {}  # project_name -> project_pb
+    self.projects_by_id = {}  # project_id -> project_pb
+    self.test_star_manager = None
+    self.indexed_projects = {}
+    self.unindexed_projects = set()
+    self.index_counter = 0
+    self.project_commitments = {}
+    self.ac_exclusion_ids = {}
+    self.no_expand_ids = {}
+
+  def TestAddProject(
+      self, name, summary='', state=project_pb2.ProjectState.LIVE,
+      owner_ids=None, committer_ids=None, contrib_ids=None,
+      issue_notify_address=None, state_reason='', description=None,
+      project_id=None, process_inbound_email=None, access=None,
+      extra_perms=None):
+    """Add a project to the fake ProjectService object.
+
+    Args:
+      name: The name of the project. Will replace any existing project under
+        the same name.
+      summary: The summary string of the project.
+      state: Initial state for the project from project_pb2.ProjectState.
+      owner_ids: List of user ids for project owners
+      committer_ids: List of user ids for project committers
+      contrib_ids: List of user ids for project contributors
+      issue_notify_address: email address to send issue change notifications
+      state_reason: string describing the reason the project is in its current
+        state.
+      description: The description string for this project
+      project_id: A unique integer identifier for the created project.
+      process_inbound_email: True to make this project accept inbound email.
+      access: One of the values of enum project_pb2.ProjectAccess.
+      extra_perms: List of ExtraPerms PBs for project members.
+
+    Returns:
+      A populated project PB.
+    """
+    proj_pb = project_pb2.Project()
+    proj_pb.project_id = project_id or hash(name) % 100000
+    proj_pb.project_name = name
+    proj_pb.summary = summary
+    proj_pb.state = state
+    proj_pb.state_reason = state_reason
+    proj_pb.extra_perms = extra_perms or []
+    if description is not None:
+      proj_pb.description = description
+
+    self.TestAddProjectMembers(owner_ids, proj_pb, OWNER_ROLE)
+    self.TestAddProjectMembers(committer_ids, proj_pb, COMMITTER_ROLE)
+    self.TestAddProjectMembers(contrib_ids, proj_pb, CONTRIBUTOR_ROLE)
+
+    if issue_notify_address is not None:
+      proj_pb.issue_notify_address = issue_notify_address
+    if process_inbound_email is not None:
+      proj_pb.process_inbound_email = process_inbound_email
+    if access is not None:
+      proj_pb.access = access
+
+    self.test_projects[name] = proj_pb
+    self.projects_by_id[proj_pb.project_id] = proj_pb
+    return proj_pb
+
+  def TestAddProjectMembers(self, user_id_list, proj_pb, role):
+    if user_id_list is not None:
+      for user_id in user_id_list:
+        if role == OWNER_ROLE:
+          proj_pb.owner_ids.append(user_id)
+        elif role == COMMITTER_ROLE:
+          proj_pb.committer_ids.append(user_id)
+        elif role == CONTRIBUTOR_ROLE:
+          proj_pb.contributor_ids.append(user_id)
+
+  def LookupProjectIDs(self, cnxn, project_names):
+    return {
+        project_name: self.test_projects[project_name].project_id
+        for project_name in project_names
+        if project_name in self.test_projects}
+
+  def LookupProjectNames(self, cnxn, project_ids):
+    projects_dict = self.GetProjects(cnxn, project_ids)
+    return {p.project_id: p.project_name
+            for p in projects_dict.values()}
+
+  def CreateProject(
+      self, _cnxn, project_name, owner_ids, committer_ids,
+      contributor_ids, summary, description,
+      state=project_pb2.ProjectState.LIVE, access=None,
+      read_only_reason=None,
+      home_page=None, docs_url=None, source_url=None,
+      logo_gcs_id=None, logo_file_name=None):
+    """Create and store a Project with the given attributes."""
+    if project_name in self.test_projects:
+      raise exceptions.ProjectAlreadyExists()
+    project = self.TestAddProject(
+        project_name, summary=summary, state=state,
+        owner_ids=owner_ids, committer_ids=committer_ids,
+        contrib_ids=contributor_ids, description=description,
+        access=access)
+    return project.project_id
+
+  def ExpungeProject(self, _cnxn, project_id):
+    project = self.projects_by_id.get(project_id)
+    if project:
+      self.test_projects.pop(project.project_name, None)
+
+  def GetProjectsByName(self, _cnxn, project_name_list, use_cache=True):
+    return {
+        pn: self.test_projects[pn] for pn in project_name_list
+        if pn in self.test_projects}
+
+  def GetProjectByName(self, _cnxn, name, use_cache=True):
+    return self.test_projects.get(name)
+
+  def GetProjectList(self, cnxn, project_id_list, use_cache=True):
+    project_dict = self.GetProjects(cnxn, project_id_list, use_cache=use_cache)
+    return [project_dict[pid] for pid in project_id_list
+            if pid in project_dict]
+
+  def GetVisibleLiveProjects(
+      self, _cnxn, logged_in_user, effective_ids, domain=None, use_cache=True):
+    project_ids = list(self.projects_by_id.keys())
+    visible_project_ids = []
+    for pid in project_ids:
+      can_view = permissions.UserCanViewProject(
+          logged_in_user, effective_ids, self.projects_by_id[pid])
+      different_domain = framework_helpers.GetNeededDomain(
+          self.projects_by_id[pid].project_name, domain)
+      if can_view and not different_domain:
+        visible_project_ids.append(pid)
+
+    return visible_project_ids
+
+  def GetProjects(self, _cnxn, project_ids, use_cache=True):
+    result = {}
+    for project_id in project_ids:
+      project = self.projects_by_id.get(project_id)
+      if project:
+        result[project_id] = project
+      else:
+        raise exceptions.NoSuchProjectException(project_id)
+    return result
+
+  def GetAllProjects(self, _cnxn, use_cache=True):
+    result = {}
+    for project_id in self.projects_by_id:
+      project = self.projects_by_id.get(project_id)
+      result[project_id] = project
+    return result
+
+
+  def GetProject(self, cnxn, project_id, use_cache=True):
+    """Load the specified project from the database."""
+    project_id_dict = self.GetProjects(cnxn, [project_id], use_cache=use_cache)
+    if project_id not in project_id_dict:
+      raise exceptions.NoSuchProjectException()
+    return project_id_dict[project_id]
+
+  def GetProjectCommitments(self, _cnxn, project_id):
+    if project_id in self.project_commitments:
+      return self.project_commitments[project_id]
+
+    project_commitments = project_pb2.ProjectCommitments()
+    project_commitments.project_id = project_id
+    return project_commitments
+
+  def TestStoreProjectCommitments(self, project_commitments):
+    key = project_commitments.project_id
+    self.project_commitments[key] = project_commitments
+
+  def GetProjectAutocompleteExclusion(self, cnxn, project_id):
+    return (self.ac_exclusion_ids.get(project_id, []),
+            self.no_expand_ids.get(project_id, []))
+
+  def UpdateProject(
+      self,
+      _cnxn,
+      project_id,
+      summary=None,
+      description=None,
+      state=None,
+      state_reason=None,
+      access=None,
+      issue_notify_address=None,
+      attachment_bytes_used=None,
+      attachment_quota=None,
+      moved_to=None,
+      process_inbound_email=None,
+      only_owners_remove_restrictions=None,
+      read_only_reason=None,
+      cached_content_timestamp=None,
+      only_owners_see_contributors=None,
+      delete_time=None,
+      recent_activity=None,
+      revision_url_format=None,
+      home_page=None,
+      docs_url=None,
+      source_url=None,
+      logo_gcs_id=None,
+      logo_file_name=None,
+      issue_notify_always_detailed=None,
+      commit=True):
+    project = self.projects_by_id.get(project_id)
+    if not project:
+      raise exceptions.NoSuchProjectException(
+          'Project "%s" not found!' % project_id)
+
+    # TODO(jrobbins): implement all passed arguments - probably as a utility
+    # method shared with the real persistence implementation.
+    if read_only_reason is not None:
+      project.read_only_reason = read_only_reason
+    if attachment_bytes_used is not None:
+      project.attachment_bytes_used = attachment_bytes_used
+
+  def UpdateProjectRoles(
+      self, _cnxn, project_id, owner_ids, committer_ids,
+      contributor_ids, now=None):
+    project = self.projects_by_id.get(project_id)
+    if not project:
+      raise exceptions.NoSuchProjectException(
+          'Project "%s" not found!' % project_id)
+
+    project.owner_ids = owner_ids
+    project.committer_ids = committer_ids
+    project.contributor_ids = contributor_ids
+
+  def MarkProjectDeletable(
+      self, _cnxn, project_id, _config_service):
+    project = self.projects_by_id[project_id]
+    project.project_name = 'DELETABLE_%d' % project_id
+    project.state = project_pb2.ProjectState.DELETABLE
+
+  def UpdateRecentActivity(self, _cnxn, _project_id, now=None):
+    pass
+
+  def GetUserRolesInAllProjects(self, _cnxn, effective_ids):
+    owned_project_ids = set()
+    membered_project_ids = set()
+    contrib_project_ids = set()
+
+    for project in self.projects_by_id.values():
+      if not effective_ids.isdisjoint(project.owner_ids):
+        owned_project_ids.add(project.project_id)
+      elif not effective_ids.isdisjoint(project.committer_ids):
+        membered_project_ids.add(project.project_id)
+      elif not effective_ids.isdisjoint(project.contributor_ids):
+        contrib_project_ids.add(project.project_id)
+
+    return owned_project_ids, membered_project_ids, contrib_project_ids
+
+  def GetProjectMemberships(self, _cnxn, effective_ids, use_cache=True):
+    # type: MonorailConnection, Collection[int], bool ->
+    #     Mapping[int, Collection[int]]
+    projects_by_user_id = collections.defaultdict(set)
+
+    for project in self.projects_by_id.values():
+      member_ids = set(
+          itertools.chain(
+              project.owner_ids, project.committer_ids,
+              project.contributor_ids))
+      for user_id in effective_ids:
+        if user_id in member_ids:
+          projects_by_user_id[user_id].add(project.project_id)
+    return projects_by_user_id
+
+  def ExpungeUsersInProjects(self, cnxn, user_ids, limit=None):
+    for project in self.projects_by_id.values():
+      project.owner_ids = [owner_id for owner_id in project.owner_ids
+                           if owner_id not in user_ids]
+      project.committer_ids = [com_id for com_id in project.committer_ids
+                              if com_id not in user_ids]
+      project.contributor_ids = [con_id for con_id in project.contributor_ids
+                                 if con_id not in user_ids]
+
+
+class ConfigService(object):
+  """Fake version of ConfigService that just works in-RAM."""
+
+  def __init__(self, user_id=None):
+    self.project_configs = {}
+    self.next_field_id = 123
+    self.next_component_id = 345
+    self.next_template_id = 23
+    self.expunged_configs = []
+    self.expunged_users_in_configs = []
+    self.component_ids_to_templates = {}
+    self.label_to_id = {}
+    self.id_to_label = {}
+    self.strict = False  # Set true to raise more exceptions like real class.
+
+  def TestAddLabelsDict(self, label_to_id):
+    self.label_to_id = label_to_id
+    self.id_to_label = {
+        label_id: label
+        for label, label_id in list(self.label_to_id.items())}
+
+  def TestAddFieldDef(self, fd):
+    self.project_configs[fd.project_id].field_defs.append(fd)
+
+  def TestAddApprovalDef(self, ad, project_id):
+    self.project_configs[project_id].approval_defs.append(ad)
+
+  def ExpungeConfig(self, _cnxn, project_id):
+    self.expunged_configs.append(project_id)
+
+  def ExpungeUsersInConfigs(self, _cnxn, user_ids, limit=None):
+    self.expunged_users_in_configs.extend(user_ids)
+
+  def GetLabelDefRows(self, cnxn, project_id, use_cache=True):
+    """This always returns empty results.  Mock it to test other cases."""
+    return []
+
+  def GetLabelDefRowsAnyProject(self, cnxn, where=None):
+    """This always returns empty results.  Mock it to test other cases."""
+    return []
+
+  def LookupLabel(self, cnxn, project_id, label_id):
+    if label_id in self.id_to_label:
+      return self.id_to_label[label_id]
+    if label_id == 999:
+      return None
+    return 'label_%d_%d' % (project_id, label_id)
+
+  def LookupLabelID(self, cnxn, project_id, label, autocreate=True):
+    if label in self.label_to_id:
+      return self.label_to_id[label]
+    return 1
+
+  def LookupLabelIDs(self, cnxn, project_id, labels, autocreate=False):
+    ids = []
+    next_label_id = 0
+    if self.id_to_label.keys():
+      existing_ids = self.id_to_label.keys()
+      existing_ids.sort()
+      next_label_id = existing_ids[-1] + 1
+    for label in labels:
+      if self.label_to_id.get(label) is not None:
+        ids.append(self.label_to_id[label])
+      elif autocreate:
+        self.label_to_id[label] = next_label_id
+        self.id_to_label[next_label_id] = label
+        ids.append(next_label_id)
+        next_label_id += 1
+    return ids
+
+  def LookupIDsOfLabelsMatching(self, cnxn, project_id, regex):
+    return [1, 2, 3]
+
+  def LookupStatus(self, cnxn, project_id, status_id):
+    return 'status_%d_%d' % (project_id, status_id)
+
+  def LookupStatusID(self, cnxn, project_id, status, autocreate=True):
+    if status:
+      return 1
+    else:
+      return 0
+
+  def LookupStatusIDs(self, cnxn, project_id, statuses):
+    return [idx for idx, _status in enumerate(statuses)]
+
+  def LookupClosedStatusIDs(self, cnxn, project_id):
+    return [7, 8, 9]
+
+  def StoreConfig(self, _cnxn, config):
+    self.project_configs[config.project_id] = config
+
+  def GetProjectConfig(self, _cnxn, project_id, use_cache=True):
+    if project_id in self.project_configs:
+      return self.project_configs[project_id]
+    elif self.strict:
+      raise exceptions.NoSuchProjectException()
+    else:
+      return tracker_bizobj.MakeDefaultProjectIssueConfig(project_id)
+
+  def GetProjectConfigs(self, _cnxn, project_ids, use_cache=True):
+    config_dict = {}
+    for project_id in project_ids:
+      if project_id in self.project_configs:
+        config_dict[project_id] = self.project_configs[project_id]
+      elif not self.strict:
+        config_dict[project_id] = tracker_bizobj.MakeDefaultProjectIssueConfig(
+            project_id)
+    return config_dict
+
+  def UpdateConfig(
+      self, cnxn, project, well_known_statuses=None,
+      statuses_offer_merge=None, well_known_labels=None,
+      excl_label_prefixes=None, default_template_for_developers=None,
+      default_template_for_users=None, list_prefs=None, restrict_to_known=None,
+      approval_defs=None):
+    project_id = project.project_id
+    project_config = self.GetProjectConfig(cnxn, project_id, use_cache=False)
+
+    if well_known_statuses is not None:
+      tracker_bizobj.SetConfigStatuses(project_config, well_known_statuses)
+
+    if statuses_offer_merge is not None:
+      project_config.statuses_offer_merge = statuses_offer_merge
+
+    if well_known_labels is not None:
+      tracker_bizobj.SetConfigLabels(project_config, well_known_labels)
+
+    if excl_label_prefixes is not None:
+      project_config.exclusive_label_prefixes = excl_label_prefixes
+
+    if approval_defs is not None:
+      tracker_bizobj.SetConfigApprovals(project_config, approval_defs)
+
+    if default_template_for_developers is not None:
+      project_config.default_template_for_developers = (
+          default_template_for_developers)
+    if default_template_for_users is not None:
+      project_config.default_template_for_users = default_template_for_users
+
+    if list_prefs:
+      default_col_spec, default_sort_spec, x_attr, y_attr, m_d_q = list_prefs
+      project_config.default_col_spec = default_col_spec
+      project_config.default_sort_spec = default_sort_spec
+      project_config.default_x_attr = x_attr
+      project_config.default_y_attr = y_attr
+      project_config.member_default_query = m_d_q
+
+    if restrict_to_known is not None:
+      project_config.restrict_to_known = restrict_to_known
+
+    self.StoreConfig(cnxn, project_config)
+    return project_config
+
+  def CreateFieldDef(
+      self,
+      cnxn,
+      project_id,
+      field_name,
+      field_type_str,
+      applic_type,
+      applic_pred,
+      is_required,
+      is_niche,
+      is_multivalued,
+      min_value,
+      max_value,
+      regex,
+      needs_member,
+      needs_perm,
+      grants_perm,
+      notify_on,
+      date_action_str,
+      docstring,
+      admin_ids,
+      editor_ids,
+      approval_id=None,
+      is_phase_field=False,
+      is_restricted_field=False):
+    config = self.GetProjectConfig(cnxn, project_id)
+    field_type = tracker_pb2.FieldTypes(field_type_str)
+    field_id = self.next_field_id
+    self.next_field_id += 1
+    fd = tracker_bizobj.MakeFieldDef(
+        field_id, project_id, field_name, field_type, applic_type, applic_pred,
+        is_required, is_niche, is_multivalued, min_value, max_value, regex,
+        needs_member, needs_perm, grants_perm, notify_on, date_action_str,
+        docstring, False, approval_id, is_phase_field, is_restricted_field,
+        admin_ids=admin_ids, editor_ids=editor_ids)
+    config.field_defs.append(fd)
+    self.StoreConfig(cnxn, config)
+    return field_id
+
+  def LookupFieldID(self, cnxn, project_id, field):
+    config = self.GetProjectConfig(cnxn, project_id)
+    for fd in config.field_defs:
+      if fd.field_name == field:
+        return fd.field_id
+
+    return None
+
+  def SoftDeleteFieldDefs(self, cnxn, project_id, field_ids):
+    config = self.GetProjectConfig(cnxn, project_id)
+    for fd in config.field_defs:
+      if fd.field_id in field_ids:
+        fd.is_deleted = True
+    self.StoreConfig(cnxn, config)
+
+  def UpdateFieldDef(
+      self,
+      cnxn,
+      project_id,
+      field_id,
+      field_name=None,
+      applicable_type=None,
+      applicable_predicate=None,
+      is_required=None,
+      is_niche=None,
+      is_multivalued=None,
+      min_value=None,
+      max_value=None,
+      regex=None,
+      needs_member=None,
+      needs_perm=None,
+      grants_perm=None,
+      notify_on=None,
+      date_action=None,
+      docstring=None,
+      admin_ids=None,
+      editor_ids=None,
+      is_restricted_field=None):
+    config = self.GetProjectConfig(cnxn, project_id)
+    fd = tracker_bizobj.FindFieldDefByID(field_id, config)
+    # pylint: disable=multiple-statements
+    if field_name is not None: fd.field_name = field_name
+    if applicable_type is not None: fd.applicable_type = applicable_type
+    if applicable_predicate is not None:
+      fd.applicable_predicate = applicable_predicate
+    if is_required is not None: fd.is_required = is_required
+    if is_niche is not None: fd.is_niche = is_niche
+    if is_multivalued is not None: fd.is_multivalued = is_multivalued
+    if min_value is not None: fd.min_value = min_value
+    if max_value is not None: fd.max_value = max_value
+    if regex is not None: fd.regex = regex
+    if date_action is not None:
+      fd.date_action = config_svc.DATE_ACTION_ENUM.index(date_action)
+    if docstring is not None: fd.docstring = docstring
+    if admin_ids is not None: fd.admin_ids = admin_ids
+    if editor_ids is not None:
+      fd.editor_ids = editor_ids
+    if is_restricted_field is not None:
+      fd.is_restricted_field = is_restricted_field
+    self.StoreConfig(cnxn, config)
+
+  def CreateComponentDef(
+      self, cnxn, project_id, path, docstring, deprecated, admin_ids, cc_ids,
+      created, creator_id, label_ids):
+    config = self.GetProjectConfig(cnxn, project_id)
+    cd = tracker_bizobj.MakeComponentDef(
+        self.next_component_id, project_id, path, docstring, deprecated,
+        admin_ids, cc_ids, created, creator_id, label_ids=label_ids)
+    config.component_defs.append(cd)
+    self.next_component_id += 1
+    self.StoreConfig(cnxn, config)
+    return self.next_component_id - 1
+
+  def UpdateComponentDef(
+      self, cnxn, project_id, component_id, path=None, docstring=None,
+      deprecated=None, admin_ids=None, cc_ids=None, created=None,
+      creator_id=None, modified=None, modifier_id=None, label_ids=None):
+    config = self.GetProjectConfig(cnxn, project_id)
+    cd = tracker_bizobj.FindComponentDefByID(component_id, config)
+    if path is not None:
+      assert path
+      cd.path = path
+    # pylint: disable=multiple-statements
+    if docstring is not None: cd.docstring = docstring
+    if deprecated is not None: cd.deprecated = deprecated
+    if admin_ids is not None: cd.admin_ids = admin_ids
+    if cc_ids is not None: cd.cc_ids = cc_ids
+    if created is not None: cd.created = created
+    if creator_id is not None: cd.creator_id = creator_id
+    if modified is not None: cd.modified = modified
+    if modifier_id is not None: cd.modifier_id = modifier_id
+    if label_ids is not None: cd.label_ids = label_ids
+    self.StoreConfig(cnxn, config)
+
+  def DeleteComponentDef(self, cnxn, project_id, component_id):
+    """Delete the specified component definition."""
+    config = self.GetProjectConfig(cnxn, project_id)
+    config.component_defs = [
+        cd for cd in config.component_defs
+        if cd.component_id != component_id]
+    self.StoreConfig(cnxn, config)
+
+  def InvalidateMemcache(self, issues, key_prefix=''):
+    pass
+
+  def InvalidateMemcacheForEntireProject(self, project_id):
+    pass
+
+
+class IssueService(object):
+  """Fake version of IssueService that just works in-RAM."""
+  # pylint: disable=unused-argument
+
+  def __init__(self, user_id=None):
+    self.user_id = user_id
+    # Dictionary {project_id: issue_pb_dict}
+    # where issue_pb_dict is a dictionary of the form
+    # {local_id: issue_pb}
+    self.issues_by_project = {}
+    self.issues_by_iid = {}
+    # Dictionary {project_id: comment_pb_dict}
+    # where comment_pb_dict is a dictionary of the form
+    # {local_id: comment_pb_list}
+    self.comments_by_project = {}
+    self.comments_by_iid = {}
+    self.comments_by_cid = {}
+    self.attachments_by_id = {}
+
+    # Set of issue IDs for issues that have been indexed by calling
+    # IndexIssues().
+    self.indexed_issue_iids = set()
+
+    # Set of issue IDs for issues that have been moved by calling MoveIssue().
+    self.moved_back_iids = set()
+
+    # Dict of issue IDs mapped to other issue IDs to represent moved issues.
+    self.moved_issues = {}
+
+    # Test-only indication that the indexer would have been called
+    # by the real DITPersist.
+    self.indexer_called = False
+
+    # Test-only sequence of updated and enqueued.
+    self.updated_issues = []
+    self.enqueued_issues = []  # issue_ids
+
+    # Test-only sequence of expunged issues and projects.
+    self.expunged_issues = []
+    self.expunged_former_locations = []
+    self.expunged_local_ids = []
+    self.expunged_users_in_issues = []
+
+    # Test-only indicators that methods were called.
+    self.get_all_issues_in_project_called = False
+    self.update_issues_called = False
+    self.enqueue_issues_called = False
+    self.get_issue_acitivity_called = False
+
+    # The next id to return if it is > 0.
+    self.next_id = -1
+
+  def UpdateIssues(
+      self, cnxn, issues, update_cols=None, just_derived=False,
+      commit=True, invalidate=True):
+    self.update_issues_called = True
+    assert all(issue.assume_stale == False for issue in issues)
+    self.updated_issues.extend(issues)
+
+  def GetIssueActivity(
+      self, cnxn, num=50, before=None, after=None,
+      project_ids=None, user_ids=None, ascending=False):
+    self.get_issue_acitivity_called = True
+    comments_dict = self.comments_by_cid
+    comments = []
+    for value in comments_dict.values():
+      if project_ids is not None:
+        if value.issue_id > 0 and value.issue_id in self.issues_by_iid:
+          issue = self.issues_by_iid[value.issue_id]
+          if issue.project_id in project_ids:
+            comments.append(value)
+      elif user_ids is not None:
+        if value.user_id in user_ids:
+          comments.append(value)
+      else:
+        comments.append(value)
+    return comments
+
+  def EnqueueIssuesForIndexing(self, _cnxn, issue_ids, commit=True):
+    self.enqueue_issues_called = True
+    for i in issue_ids:
+      if i not in self.enqueued_issues:
+        self.enqueued_issues.extend(issues)
+
+  def ExpungeIssues(self, _cnxn, issue_ids):
+    self.expunged_issues.extend(issue_ids)
+
+  def ExpungeFormerLocations(self, _cnxn, project_id):
+    self.expunged_former_locations.append(project_id)
+
+  def ExpungeLocalIDCounters(self, _cnxn, project_id):
+    self.expunged_local_ids.append(project_id)
+
+  def TestAddIssue(self, issue, importer_id=None):
+    project_id = issue.project_id
+    self.issues_by_project.setdefault(project_id, {})
+    self.issues_by_project[project_id][issue.local_id] = issue
+    self.issues_by_iid[issue.issue_id] = issue
+    if issue.issue_id not in self.enqueued_issues:
+      self.enqueued_issues.append(issue.issue_id)
+      self.enqueue_issues_called = True
+
+    # Adding a new issue should add the first comment to the issue
+    comment = tracker_pb2.IssueComment()
+    comment.project_id = issue.project_id
+    comment.issue_id = issue.issue_id
+    comment.content = issue.summary
+    comment.timestamp = issue.opened_timestamp
+    comment.is_description = True
+    if issue.reporter_id:
+      comment.user_id = issue.reporter_id
+    if importer_id:
+      comment.importer_id = importer_id
+    comment.sequence = 0
+    self.TestAddComment(comment, issue.local_id)
+
+  def TestAddMovedIssueRef(self, source_project_id, source_local_id,
+      target_project_id, target_local_id):
+    self.moved_issues[(source_project_id, source_local_id)] = (
+        target_project_id, target_local_id)
+
+  def TestAddComment(self, comment, local_id):
+    pid = comment.project_id
+    if not comment.id:
+      comment.id = len(self.comments_by_cid)
+
+    self.comments_by_project.setdefault(pid, {})
+    self.comments_by_project[pid].setdefault(local_id, []).append(comment)
+    self.comments_by_iid.setdefault(comment.issue_id, []).append(comment)
+    self.comments_by_cid[comment.id] = comment
+
+  def TestAddAttachment(self, attachment, comment_id, issue_id):
+    if not attachment.attachment_id:
+      attachment.attachment_id = len(self.attachments_by_id)
+
+    aid = attachment.attachment_id
+    self.attachments_by_id[aid] = attachment, comment_id, issue_id
+    comment = self.comments_by_cid[comment_id]
+    if attachment not in comment.attachments:
+      comment.attachments.extend([attachment])
+
+  def SoftDeleteAttachment(
+      self, _cnxn, _issue, comment, attach_id, _user_service, delete=True,
+      index_now=False):
+    attachment = None
+    for attach in comment.attachments:
+      if attach.attachment_id == attach_id:
+        attachment = attach
+    if not attachment:
+      return
+    attachment.deleted = delete
+
+  def GetAttachmentAndContext(self, _cnxn, attachment_id):
+    if attachment_id in self.attachments_by_id:
+      attach, comment_id, issue_id = self.attachments_by_id[attachment_id]
+      if not attach.deleted:
+        return attach, comment_id, issue_id
+
+    raise exceptions.NoSuchAttachmentException()
+
+  def GetComments(
+      self, _cnxn, where=None, order_by=None, content_only=False, **kwargs):
+    # This is a very limited subset of what the real GetComments() can do.
+    cid = kwargs.get('id')
+
+    comment = self.comments_by_cid.get(cid)
+    if comment:
+      return [comment]
+    else:
+      return []
+
+  def GetComment(self, cnxn, comment_id):
+    """Get the requested comment, or raise an exception."""
+    comments = self.GetComments(cnxn, id=comment_id)
+    if len(comments) == 1:
+      return comments[0]
+
+    raise exceptions.NoSuchCommentException()
+
+  def ResolveIssueRefs(self, cnxn, ref_projects, default_project_name, refs):
+    result = []
+    misses = []
+    for project_name, local_id in refs:
+      project = ref_projects.get(project_name or default_project_name)
+      if not project or project.state == project_pb2.ProjectState.DELETABLE:
+        continue  # ignore any refs to issues in deleted projects
+      try:
+        issue = self.GetIssueByLocalID(cnxn, project.project_id, local_id)
+        result.append(issue.issue_id)
+      except exceptions.NoSuchIssueException:
+        misses.append((project.project_id, local_id))
+
+    return result, misses
+
+  def LookupIssueRefs(self, cnxn, issue_ids):
+    issue_dict, _misses = self.GetIssuesDict(cnxn, issue_ids)
+    return {
+      issue_id: (issue.project_name, issue.local_id)
+      for issue_id, issue in issue_dict.items()}
+
+  def GetAllIssuesInProject(
+      self, _cnxn, project_id, min_local_id=None, use_cache=True):
+    self.get_all_issues_in_project_called = True
+    if project_id in self.issues_by_project:
+      return list(self.issues_by_project[project_id].values())
+    else:
+      return []
+
+  def GetIssuesByLocalIDs(
+      self, _cnxn, project_id, local_id_list, use_cache=True, shard_id=None):
+    results = []
+    for local_id in local_id_list:
+      if (project_id in self.issues_by_project
+          and local_id in self.issues_by_project[project_id]):
+        results.append(self.issues_by_project[project_id][local_id])
+
+    return results
+
+  def GetIssueByLocalID(self, _cnxn, project_id, local_id, use_cache=True):
+    try:
+      return self.issues_by_project[project_id][local_id]
+    except KeyError:
+      raise exceptions.NoSuchIssueException()
+
+  def GetAnyOnHandIssue(self, issue_ids, start=None, end=None):
+    return None  # Treat them all like misses.
+
+  def GetIssue(self, cnxn, issue_id, use_cache=True):
+    issues = self.GetIssues(cnxn, [issue_id], use_cache=use_cache)
+    try:
+      return issues[0]
+    except IndexError:
+      raise exceptions.NoSuchIssueException()
+
+  def GetCurrentLocationOfMovedIssue(self, cnxn, project_id, local_id):
+    key = (project_id, local_id)
+    if key in self.moved_issues:
+      ref = self.moved_issues[key]
+      return ref[0], ref[1]
+    return None, None
+
+  def GetPreviousLocations(self, cnxn, issue):
+    return []
+
+  def GetCommentsByUser(self, cnxn, user_id):
+    """Get all comments created by a user"""
+    comments = []
+    for cid in self.comments_by_cid:
+      comment = self.comments_by_cid[cid]
+      if comment.user_id == user_id and not comment.is_description:
+        comments.append(comment)
+    return comments
+
+  def GetCommentsByID(self, cnxn, comment_ids, _sequences, use_cache=True,
+      shard_id=None):
+    """Return all IssueComment PBs by comment ids."""
+    comments = [self.comments_by_cid[cid] for cid in comment_ids]
+    return comments
+
+  def GetIssueIDsReportedByUser(self, cnxn, user_id):
+    """Get all issues created by a user"""
+    ids = []
+    for iid in self.issues_by_iid:
+      issue = self.issues_by_iid[iid]
+      if issue.reporter_id == user_id:
+        ids.append(iid)
+    return ids
+
+  def LookupIssueIDs(self, _cnxn, project_local_id_pairs):
+    hits = []
+    misses = []
+    for (project_id, local_id) in project_local_id_pairs:
+      try:
+        issue = self.issues_by_project[project_id][local_id]
+        hits.append(issue.issue_id)
+      except KeyError:
+        misses.append((project_id, local_id))
+
+    return hits, misses
+
+  def LookupIssueIDsFollowMoves(self, _cnxn, project_local_id_pairs):
+    hits = []
+    misses = []
+    for pair in project_local_id_pairs:
+      project_id, local_id = self.moved_issues.get(pair, pair)
+      try:
+        issue = self.issues_by_project[project_id][local_id]
+        hits.append(issue.issue_id)
+      except KeyError:
+        misses.append((project_id, local_id))
+
+    return hits, misses
+
+  def LookupIssueID(self, _cnxn, project_id, local_id):
+    try:
+      issue = self.issues_by_project[project_id][local_id]
+    except KeyError:
+      raise exceptions.NoSuchIssueException()
+    return issue.issue_id
+
+  def GetCommentsForIssue(self, _cnxn, issue_id):
+    comments = self.comments_by_iid.get(issue_id, [])
+    for idx, c in enumerate(comments):
+      c.sequence = idx
+
+    return comments
+
+  def InsertIssue(self, cnxn, issue):
+    issue.issue_id = issue.project_id * 1000000 + issue.local_id
+    self.issues_by_project.setdefault(issue.project_id, {})
+    self.issues_by_project[issue.project_id][issue.local_id] = issue
+    self.issues_by_iid[issue.issue_id] = issue
+    return issue.issue_id
+
+  def CreateIssue(
+      self,
+      cnxn,
+      services,
+      issue,
+      marked_description,
+      attachments=None,
+      index_now=False,
+      importer_id=None):
+    project_id = issue.project_id
+
+    issue.local_id = self.AllocateNextLocalID(cnxn, project_id)
+    issue.issue_id = project_id * 1000000 + issue.local_id
+
+    self.TestAddIssue(issue, importer_id=importer_id)
+    comment = self.comments_by_iid[issue.issue_id][0]
+    comment.content = marked_description
+    return issue, comment
+
+  def GetIssueApproval(self, cnxn, issue_id, approval_id, use_cache=True):
+    issue = self.GetIssue(cnxn, issue_id, use_cache=use_cache)
+    approval = tracker_bizobj.FindApprovalValueByID(
+        approval_id, issue.approval_values)
+    if approval:
+      return issue, approval
+    raise exceptions.NoSuchIssueApprovalException()
+
+  def UpdateIssueApprovalStatus(
+      self, cnxn, issue_id, approval_id, status, setter_id, set_on,
+      commit=True):
+    issue = self.GetIssue(cnxn, issue_id)
+    for av in issue.approval_values:
+      if av.approval_id == approval_id:
+        av.status = status
+        av.setter_id = setter_id
+        av.set_on = set_on
+        return
+    return
+
+  def UpdateIssueApprovalApprovers(
+      self, cnxn, issue_id, approval_id, approver_ids, commit=True):
+    issue = self.GetIssue(cnxn, issue_id)
+    for av in issue.approval_values:
+      if av.approval_id == approval_id:
+        av.approver_ids = approver_ids
+        return
+    return
+
+  def UpdateIssueStructure(
+      self, cnxn, config, issue, template, reporter_id, comment_content,
+      commit=True, invalidate=True):
+    approval_defs_by_id = {ad.approval_id: ad for ad in config.approval_defs}
+    issue_avs_by_id = {av.approval_id: av for av in issue.approval_values}
+
+    new_issue_approvals = []
+
+    for template_av in template.approval_values:
+      existing_issue_av = issue_avs_by_id.get(template_av.approval_id)
+      # Keep approval values as-if fi it exists in issue and template
+      if existing_issue_av:
+        existing_issue_av.phase_id = template_av.phase_id
+        new_issue_approvals.append(existing_issue_av)
+      else:
+        new_issue_approvals.append(template_av)
+
+      # Update all approval surveys so latest ApprovalDef survey changes
+      # appear in the converted issue's approval values.
+      ad = approval_defs_by_id.get(template_av.approval_id)
+      if ad:
+        self.CreateIssueComment(
+            cnxn, issue, reporter_id, ad.survey,
+            is_description=True, approval_id=ad.approval_id, commit=False)
+      else:
+        logging.info('ApprovalDef not found for approval %r', template_av)
+
+    template_phase_by_name = {
+        phase.name.lower(): phase for phase in template.phases}
+    issue_phase_by_id = {phase.phase_id: phase for phase in issue.phases}
+    updated_fvs = []
+    # Trim issue FieldValues or update FieldValue phase_ids
+    for fv in issue.field_values:
+      # If a fv's phase has the same name as a template's phase, update
+      # the fv's phase_id to that of the template phase's. Otherwise,
+      # remove the fv.
+      if fv.phase_id:
+        issue_phase = issue_phase_by_id.get(fv.phase_id)
+        if issue_phase and issue_phase.name:
+          template_phase = template_phase_by_name.get(issue_phase.name.lower())
+          if template_phase:
+            fv.phase_id = template_phase.phase_id
+            updated_fvs.append(fv)
+      # keep all fvs that do not belong to phases.
+      else:
+        updated_fvs.append(fv)
+
+    fd_names_by_id = {fd.field_id: fd.field_name for fd in config.field_defs}
+    amendment = tracker_bizobj.MakeApprovalStructureAmendment(
+        [fd_names_by_id.get(av.approval_id) for av in new_issue_approvals],
+        [fd_names_by_id.get(av.approval_id) for av in issue.approval_values])
+
+    issue.approval_values = new_issue_approvals
+    issue.phases = template.phases
+    issue.field_values = updated_fvs
+
+    return self.CreateIssueComment(
+        cnxn, issue, reporter_id, comment_content,
+        amendments=[amendment], commit=False)
+
+  def SetUsedLocalID(self, cnxn, project_id):
+    self.next_id = self.GetHighestLocalID(cnxn, project_id) + 1
+
+  def AllocateNextLocalID(self, cnxn, project_id):
+    return self.GetHighestLocalID(cnxn, project_id) + 1
+
+  def GetHighestLocalID(self, _cnxn, project_id):
+    if self.next_id > 0:
+      return self.next_id - 1
+    else:
+      issue_dict = self.issues_by_project.get(project_id, {})
+      highest = max([0] + [issue.local_id for issue in issue_dict.values()])
+      return highest
+
+  def _MakeIssueComment(
+      self, project_id, user_id, content, inbound_message=None,
+      amendments=None, attachments=None, kept_attachments=None, timestamp=None,
+      is_spam=False, is_description=False, approval_id=None, importer_id=None):
+    comment = tracker_pb2.IssueComment()
+    comment.project_id = project_id
+    comment.user_id = user_id
+    comment.content = content or ''
+    comment.is_spam = is_spam
+    comment.is_description = is_description
+    if not timestamp:
+      timestamp = int(time.time())
+    comment.timestamp = int(timestamp)
+    if inbound_message:
+      comment.inbound_message = inbound_message
+    if amendments:
+      comment.amendments.extend(amendments)
+    if approval_id:
+      comment.approval_id = approval_id
+    if importer_id:
+      comment.importer_id = importer_id
+    return comment
+
+  def CopyIssues(self, cnxn, dest_project, issues, user_service, copier_id):
+    created_issues = []
+    for target_issue in issues:
+      new_issue = tracker_pb2.Issue()
+      new_issue.project_id = dest_project.project_id
+      new_issue.project_name = dest_project.project_name
+      new_issue.summary = target_issue.summary
+      new_issue.labels.extend(target_issue.labels)
+      new_issue.field_values.extend(target_issue.field_values)
+      new_issue.reporter_id = copier_id
+
+      timestamp = int(time.time())
+      new_issue.opened_timestamp = timestamp
+      new_issue.modified_timestamp = timestamp
+
+      target_comments = self.GetCommentsForIssue(cnxn, target_issue.issue_id)
+      initial_summary_comment = target_comments[0]
+
+      # Note that blocking and merge_into are not copied.
+      new_issue.blocked_on_iids = target_issue.blocked_on_iids
+      new_issue.blocked_on_ranks = target_issue.blocked_on_ranks
+
+      # Create the same summary comment as the target issue.
+      comment = self._MakeIssueComment(
+          dest_project.project_id, copier_id, initial_summary_comment.content,
+          is_description=True)
+
+      new_issue.local_id = self.AllocateNextLocalID(
+          cnxn, dest_project.project_id)
+      issue_id = self.InsertIssue(cnxn, new_issue)
+      comment.issue_id = issue_id
+      self.InsertComment(cnxn, comment)
+      created_issues.append(new_issue)
+
+    return created_issues
+
+  def MoveIssues(self, cnxn, dest_project, issues, user_service):
+    move_to = dest_project.project_id
+    self.issues_by_project.setdefault(move_to, {})
+    moved_back_iids = set()
+    for issue in issues:
+      if issue.issue_id in self.moved_back_iids:
+        moved_back_iids.add(issue.issue_id)
+      self.moved_back_iids.add(issue.issue_id)
+      project_id = issue.project_id
+      self.issues_by_project[project_id].pop(issue.local_id)
+      issue.local_id = self.AllocateNextLocalID(cnxn, move_to)
+      self.issues_by_project[move_to][issue.local_id] = issue
+      issue.project_id = move_to
+      issue.project_name = dest_project.project_name
+    return moved_back_iids
+
+  def GetCommentsForIssues(self, _cnxn, issue_ids, content_only=False):
+    comments_dict = {}
+    for issue_id in issue_ids:
+      comments_dict[issue_id] = self.comments_by_iid[issue_id]
+
+    return comments_dict
+
+  def InsertComment(self, cnxn, comment, commit=True):
+    issue = self.GetIssue(cnxn, comment.issue_id)
+    self.TestAddComment(comment, issue.local_id)
+
+  # pylint: disable=unused-argument
+  def DeltaUpdateIssue(
+      self, cnxn, services, reporter_id, project_id,
+      config, issue, delta, index_now=False, comment=None, attachments=None,
+      iids_to_invalidate=None, rules=None, predicate_asts=None,
+      is_description=False, timestamp=None, kept_attachments=None,
+      importer_id=None, inbound_message=None):
+    # Return a bogus amendments list if any of the fields changed
+    amendments, _ = tracker_bizobj.ApplyIssueDelta(
+        cnxn, self, issue, delta, config)
+
+    if not amendments and (not comment or not comment.strip()):
+      return [], None
+
+    comment_pb = self.CreateIssueComment(
+        cnxn, issue, reporter_id, comment, attachments=attachments,
+        amendments=amendments, is_description=is_description,
+        kept_attachments=kept_attachments, importer_id=importer_id,
+        inbound_message=inbound_message)
+
+    self.indexer_called = index_now
+    return amendments, comment_pb
+
+  def InvalidateIIDs(self, cnxn, iids_to_invalidate):
+    pass
+
+  # pylint: disable=unused-argument
+  def CreateIssueComment(
+      self, _cnxn, issue, user_id, content,
+      inbound_message=None, amendments=None, attachments=None,
+      kept_attachments=None, timestamp=None, is_spam=False,
+      is_description=False, approval_id=None, commit=True,
+      importer_id=None):
+    # Add a comment to an issue
+    comment = tracker_pb2.IssueComment()
+    comment.id = len(self.comments_by_cid)
+    comment.project_id = issue.project_id
+    comment.issue_id = issue.issue_id
+    comment.content = content
+    comment.user_id = user_id
+    if timestamp is not None:
+      comment.timestamp = timestamp
+    else:
+      comment.timestamp = 1234567890
+    if amendments:
+      comment.amendments.extend(amendments)
+    if inbound_message:
+      comment.inbound_message = inbound_message
+    comment.is_spam = is_spam
+    comment.is_description = is_description
+    if approval_id:
+      comment.approval_id = approval_id
+
+    pid = issue.project_id
+    self.comments_by_project.setdefault(pid, {})
+    self.comments_by_project[pid].setdefault(issue.local_id, []).append(comment)
+    self.comments_by_iid.setdefault(issue.issue_id, []).append(comment)
+    self.comments_by_cid[comment.id] = comment
+
+    if attachments:
+      for filename, filecontent, mimetype in attachments:
+        aid = len(self.attachments_by_id)
+        attach = tracker_pb2.Attachment(
+            attachment_id=aid,
+            filename=filename,
+            filesize=len(filecontent),
+            mimetype=mimetype,
+            gcs_object_id='gcs_object_id(%s)' % filename)
+        comment.attachments.append(attach)
+        self.attachments_by_id[aid] = attach, pid, comment.id
+
+    if kept_attachments:
+      comment.attachments.extend([
+          self.attachments_by_id[aid][0]
+          for aid in kept_attachments])
+
+    return comment
+
+  def GetOpenAndClosedIssues(self, _cnxn, issue_ids):
+    open_issues = []
+    closed_issues = []
+    for issue_id in issue_ids:
+      try:
+        issue = self.issues_by_iid[issue_id]
+        if issue.status == 'Fixed':
+          closed_issues.append(issue)
+        else:
+          open_issues.append(issue)
+      except KeyError:
+        continue
+
+    return open_issues, closed_issues
+
+  def GetIssuesDict(
+      self, _cnxn, issue_ids, use_cache=True, shard_id=None):
+    missing_ids = [iid for iid in issue_ids if iid not in self.issues_by_iid]
+    issues_by_id = {}
+    for iid in issue_ids:
+      if iid in self.issues_by_iid:
+        issue = self.issues_by_iid[iid]
+        if not use_cache:
+          issue.assume_stale = False
+        issues_by_id[iid] = issue
+
+    return issues_by_id, missing_ids
+
+  def GetIssues(self, cnxn, issue_ids, use_cache=True, shard_id=None):
+    issues_by_iid, _misses = self.GetIssuesDict(
+        cnxn, issue_ids, use_cache=use_cache, shard_id=shard_id)
+    results = [
+        issues_by_iid[issue_id]
+        for issue_id in issue_ids
+        if issue_id in issues_by_iid
+    ]
+
+    return results
+
+  def SoftDeleteIssue(
+      self, _cnxn, project_id, local_id, deleted, user_service):
+    issue = self.issues_by_project[project_id][local_id]
+    issue.deleted = deleted
+
+  def SoftDeleteComment(
+      self, cnxn, issue, comment, deleted_by_user_id, user_service,
+      delete=True, reindex=False, is_spam=False):
+    pid = comment.project_id
+    # Find the original comment by the sequence number.
+    c = None
+    by_iid_idx = -1
+    for by_iid_idx, c in enumerate(self.comments_by_iid[issue.issue_id]):
+      if c.sequence == comment.sequence:
+        break
+    comment = c
+    by_project_idx = (
+        self.comments_by_project[pid][issue.local_id].index(comment))
+    comment.is_spam = is_spam
+    if delete:
+      comment.deleted_by = deleted_by_user_id
+    else:
+      comment.reset('deleted_by')
+    self.comments_by_project[pid][issue.local_id][by_project_idx] = comment
+    self.comments_by_iid[issue.issue_id][by_iid_idx] = comment
+    self.comments_by_cid[comment.id] = comment
+
+  def DeleteComponentReferences(self, _cnxn, component_id):
+    for _, issue in self.issues_by_iid.items():
+      issue.component_ids = [
+          cid for cid in issue.component_ids if cid != component_id]
+
+  def RunIssueQuery(
+      self, cnxn, left_joins, where, order_by, shard_id=None, limit=None):
+    """This always returns empty results.  Mock it to test other cases."""
+    return [], False
+
+  def GetIIDsByLabelIDs(self, cnxn, label_ids, project_id, shard_id):
+    """This always returns empty results.  Mock it to test other cases."""
+    return []
+
+  def GetIIDsByParticipant(self, cnxn, user_ids, project_ids, shard_id):
+    """This always returns empty results.  Mock it to test other cases."""
+    return []
+
+  def SortBlockedOn(self, cnxn, issue, blocked_on_iids):
+    return blocked_on_iids, [0] * len(blocked_on_iids)
+
+  def ApplyIssueRerank(
+      self, cnxn, parent_id, relations_to_change, commit=True, invalidate=True):
+    issue = self.GetIssue(cnxn, parent_id)
+    relations_dict = dict(
+        list(zip(issue.blocked_on_iids, issue.blocked_on_ranks)))
+    relations_dict.update(relations_to_change)
+    issue.blocked_on_ranks = sorted(issue.blocked_on_ranks, reverse=True)
+    issue.blocked_on_iids = sorted(
+        issue.blocked_on_iids, key=relations_dict.get, reverse=True)
+
+  def SplitRanks(self, cnxn, parent_id, target_id, open_ids, split_above=False):
+    pass
+
+  def ExpungeUsersInIssues(self, cnxn, user_ids_by_email, limit=None):
+    user_ids = list(user_ids_by_email.values())
+    self.expunged_users_in_issues.extend(user_ids)
+    return []
+
+
+class TemplateService(object):
+  """Fake version of TemplateService that just works in-RAM."""
+
+  def __init__(self):
+    self.templates_by_id = {}  # template_id: template_pb
+    self.templates_by_project_id = {}  # project_id: [template_id]
+
+  def TestAddIssueTemplateDef(
+      self, template_id, project_id, name, content="", summary="",
+      summary_must_be_edited=False, status='New', members_only=False,
+      owner_defaults_to_member=False, component_required=False, owner_id=None,
+      labels=None, component_ids=None, admin_ids=None, field_values=None,
+      phases=None, approval_values=None):
+    template = tracker_bizobj.MakeIssueTemplate(
+        name,
+        summary,
+        status,
+        owner_id,
+        content,
+        labels,
+        field_values or [],
+        admin_ids or [],
+        component_ids,
+        summary_must_be_edited=summary_must_be_edited,
+        owner_defaults_to_member=owner_defaults_to_member,
+        component_required=component_required,
+        members_only=members_only,
+        phases=phases,
+        approval_values=approval_values)
+    template.template_id = template_id
+    self.templates_by_id[template_id] = template
+    if project_id not in self.templates_by_project_id:
+      self.templates_by_project_id[project_id] = []
+    self.templates_by_project_id[project_id].append(template_id)
+    return template
+
+  def GetTemplateByName(self, cnxn, template_name, project_id):
+    if project_id not in self.templates_by_project_id:
+      return None
+    else:
+      project_templates = self.templates_by_project_id[project_id]
+      for template_id in project_templates:
+        template = self.GetTemplateById(cnxn, template_id)
+        if template.name == template_name:
+          return template
+    return None
+
+  def GetTemplateById(self, cnxn, template_id):
+    return self.templates_by_id.get(template_id)
+
+  def GetTemplatesById(self, cnxn, template_ids):
+    return filter(
+        lambda template: template.template_id in template_ids,
+        self.templates_by_id.values())
+
+  def GetProjectTemplates(self, cnxn, project_id):
+    template_ids = self.templates_by_project_id[project_id]
+    return self.GetTemplatesById(cnxn, template_ids)
+
+  def ExpungeUsersInTemplates(self, cnxn, user_ids, limit=None):
+    for _, template in self.templates_by_id.items():
+      template.admin_ids = [user_id for user_id in template.admin_ids
+                            if user_id not in user_ids]
+      if template.owner_id in user_ids:
+        template.owner_id = None
+      template.field_values = [fv for fv in template.field_values
+                               if fv.user_id in user_ids]
+
+class SpamService(object):
+  """Fake version of SpamService that just works in-RAM."""
+
+  def __init__(self, user_id=None):
+    self.user_id = user_id
+    self.reports_by_issue_id = collections.defaultdict(list)
+    self.comment_reports_by_issue_id = collections.defaultdict(dict)
+    self.manual_verdicts_by_issue_id = collections.defaultdict(dict)
+    self.manual_verdicts_by_comment_id = collections.defaultdict(dict)
+    self.expunged_users_in_spam = []
+
+  def LookupIssuesFlaggers(self, cnxn, issue_ids):
+    return {
+        issue_id: (self.reports_by_issue_id.get(issue_id, []),
+                   self.comment_reports_by_issue_id.get(issue_id, {}))
+        for issue_id in issue_ids}
+
+  def LookupIssueFlaggers(self, cnxn, issue_id):
+    return self.LookupIssuesFlaggers(cnxn, [issue_id])[issue_id]
+
+  def FlagIssues(self, cnxn, issue_service, issues, user_id, flagged_spam):
+    for issue in issues:
+      if flagged_spam:
+        self.reports_by_issue_id[issue.issue_id].append(user_id)
+      else:
+        self.reports_by_issue_id[issue.issue_id].remove(user_id)
+
+  def FlagComment(
+      self, cnxn, issue, comment_id, reported_user_id, user_id, flagged_spam):
+    if not comment_id in self.comment_reports_by_issue_id[issue.issue_id]:
+      self.comment_reports_by_issue_id[issue.issue_id][comment_id] = []
+    if flagged_spam:
+      self.comment_reports_by_issue_id[issue.issue_id][comment_id].append(
+          user_id)
+    else:
+      self.comment_reports_by_issue_id[issue.issue_id][comment_id].remove(
+          user_id)
+
+  def RecordManualIssueVerdicts(
+      self, cnxn, issue_service, issues, user_id, is_spam):
+    for issue in issues:
+      self.manual_verdicts_by_issue_id[issue.issue_id][user_id] = is_spam
+
+  def RecordManualCommentVerdict(
+      self, cnxn, issue_service, user_service, comment_id,
+      user_id, is_spam):
+    self.manual_verdicts_by_comment_id[comment_id][user_id] = is_spam
+    comment = issue_service.GetComment(cnxn, comment_id)
+    comment.is_spam = is_spam
+    issue = issue_service.GetIssue(cnxn, comment.issue_id, use_cache=False)
+    issue_service.SoftDeleteComment(
+        cnxn, issue, comment, user_id, user_service, is_spam, True, is_spam)
+
+  def RecordClassifierIssueVerdict(self, cnxn, issue, is_spam, confidence,
+        failed_open):
+    return
+
+  def RecordClassifierCommentVerdict(self, cnxn, issue, is_spam, confidence,
+        failed_open):
+    return
+
+  def ClassifyComment(self, comment, commenter):
+    return {'outputLabel': 'ham',
+            'outputMulti': [{'label': 'ham', 'score': '1.0'}],
+            'failed_open': False}
+
+  def ClassifyIssue(self, issue, firstComment, reporter):
+    return {'outputLabel': 'ham',
+            'outputMulti': [{'label': 'ham', 'score': '1.0'}],
+            'failed_open': False}
+
+  def ExpungeUsersInSpam(self, cnxn, user_ids):
+    self.expunged_users_in_spam.extend(user_ids)
+
+
+class FeaturesService(object):
+  """A fake implementation of FeaturesService."""
+  def __init__(self):
+    # Test-only sequence of expunged projects and users.
+    self.expunged_saved_queries = []
+    self.expunged_users_in_saved_queries = []
+    self.expunged_filter_rules = []
+    self.expunged_users_in_filter_rules = []
+    self.expunged_quick_edit = []
+    self.expunged_users_in_quick_edits = []
+    self.expunged_hotlist_ids = []
+    self.expunged_users_in_hotlists = []
+
+    # filter rules, project_id => filterrule_pb
+    self.test_rules = collections.defaultdict(list)
+
+    # TODO(crbug/monorail/7104): Confirm that these are never reassigned
+    # to empty {} and then change these to collections.defaultdicts instead.
+    # hotlists
+    self.test_hotlists = {}  # (hotlist_name, owner_id) => hotlist_pb
+    self.hotlists_by_id = {}
+    self.hotlists_id_by_user = {}  # user_id => [hotlist_id, hotlist_id, ...]
+    self.hotlists_id_by_issue = {}  # issue_id => [hotlist_id, hotlist_id, ...]
+
+    # saved queries
+    self.saved_queries = []  # [(pid, uid, sq), ...]
+
+  def TestAddFilterRule(
+      self, project_id, predicate, default_status=None, default_owner_id=None,
+      add_cc_ids=None, add_labels=None, add_notify=None, warning=None,
+      error=None):
+    rule = filterrules_helpers.MakeRule(
+        predicate, default_status=default_status,
+        default_owner_id=default_owner_id, add_cc_ids=add_cc_ids,
+        add_labels=add_labels, add_notify=add_notify, warning=warning,
+        error=error)
+    self.test_rules[project_id].append(rule)
+    return rule
+
+  def TestAddHotlist(self, name, summary='', owner_ids=None, editor_ids=None,
+                     follower_ids=None, description=None, hotlist_id=None,
+                     is_private=False, hotlist_item_fields=None,
+                     default_col_spec=None):
+    """Add a hotlist to the fake FeaturesService object.
+
+    Args:
+      name: the name of the hotlist. Will replace any existing hotlist under
+        the same name.
+      summary: the summary string of the hotlist
+      owner_ids: List of user ids for the hotlist owners
+      editor_ids: List of user ids for the hotlist editors
+      follower_ids: List of user ids for the hotlist followers
+      description: The description string for this hotlist
+      hotlist_id: A unique integer identifier for the created hotlist
+      is_private: A boolean indicating whether the hotlist is private/public
+      hotlist_item_fields: a list of tuples ->
+        [(issue_id, rank, adder_id, date_added, note),...]
+      default_col_spec: string of default columns for the hotlist.
+
+    Returns:
+      A populated hotlist PB.
+    """
+    hotlist_pb = features_pb2.Hotlist()
+    hotlist_pb.hotlist_id = hotlist_id or hash(name) % 100000
+    hotlist_pb.name = name
+    hotlist_pb.summary = summary
+    hotlist_pb.is_private = is_private
+    hotlist_pb.default_col_spec = default_col_spec
+    if description is not None:
+      hotlist_pb.description = description
+
+    self.TestAddHotlistMembers(owner_ids, hotlist_pb, OWNER_ROLE)
+    self.TestAddHotlistMembers(follower_ids, hotlist_pb, FOLLOWER_ROLE)
+    self.TestAddHotlistMembers(editor_ids, hotlist_pb, EDITOR_ROLE)
+
+    if hotlist_item_fields is not None:
+      for(issue_id, rank, adder_id, date, note) in hotlist_item_fields:
+        hotlist_pb.items.append(
+            features_pb2.Hotlist.HotlistItem(
+                issue_id=issue_id, rank=rank, adder_id=adder_id,
+                date_added=date, note=note))
+        try:
+          self.hotlists_id_by_issue[issue_id].append(hotlist_pb.hotlist_id)
+        except KeyError:
+          self.hotlists_id_by_issue[issue_id] = [hotlist_pb.hotlist_id]
+
+    owner_id = None
+    if hotlist_pb.owner_ids:
+      owner_id = hotlist_pb.owner_ids[0]
+    self.test_hotlists[(name, owner_id)] = hotlist_pb
+    self.hotlists_by_id[hotlist_pb.hotlist_id] = hotlist_pb
+    return hotlist_pb
+
+  def TestAddHotlistMembers(self, user_id_list, hotlist_pb, role):
+    if user_id_list is not None:
+      for user_id in user_id_list:
+        if role == OWNER_ROLE:
+          hotlist_pb.owner_ids.append(user_id)
+        elif role == EDITOR_ROLE:
+          hotlist_pb.editor_ids.append(user_id)
+        elif role == FOLLOWER_ROLE:
+          hotlist_pb.follower_ids.append(user_id)
+        try:
+          self.hotlists_id_by_user[user_id].append(hotlist_pb.hotlist_id)
+        except KeyError:
+          self.hotlists_id_by_user[user_id] = [hotlist_pb.hotlist_id]
+
+  def CheckHotlistName(self, cnxn, name, owner_ids):
+    if not framework_bizobj.IsValidHotlistName(name):
+      raise exceptions.InputException(
+          '%s is not a valid name for a Hotlist' % name)
+    if self.LookupHotlistIDs(cnxn, [name], owner_ids):
+      raise features_svc.HotlistAlreadyExists()
+
+  def CreateHotlist(
+      self, _cnxn, hotlist_name, summary, description, owner_ids, editor_ids,
+      issue_ids=None, is_private=None, default_col_spec=None, ts=None):
+    """Create and store a Hotlist with the given attributes."""
+    if not framework_bizobj.IsValidHotlistName(hotlist_name):
+      raise exceptions.InputException()
+    if not owner_ids:  # Should never happen.
+      raise features_svc.UnownedHotlistException()
+    if (hotlist_name, owner_ids[0]) in self.test_hotlists:
+      raise features_svc.HotlistAlreadyExists()
+    hotlist_item_fields = [
+        (issue_id, rank*100, owner_ids[0] or None, ts, '') for
+        rank, issue_id in enumerate(issue_ids or [])]
+    return self.TestAddHotlist(hotlist_name, summary=summary,
+                               owner_ids=owner_ids, editor_ids=editor_ids,
+                               description=description, is_private=is_private,
+                               hotlist_item_fields=hotlist_item_fields,
+                               default_col_spec=default_col_spec)
+
+  def UpdateHotlist(
+      self, cnxn, hotlist_id, name=None, summary=None, description=None,
+      is_private=None, default_col_spec=None, owner_id=None,
+      add_editor_ids=None):
+    hotlist = self.hotlists_by_id.get(hotlist_id)
+    if not hotlist:
+      raise features_svc.NoSuchHotlistException(
+          'Hotlist "%s" not found!' % hotlist_id)
+
+    if owner_id:
+      old_owner_id = hotlist.owner_ids[0]
+      self.test_hotlists.pop((hotlist.name, old_owner_id), None)
+      self.test_hotlists[(hotlist.name, owner_id)] = hotlist
+
+    if add_editor_ids:
+      for editor_id in add_editor_ids:
+        self.hotlists_id_by_user.get(editor_id, []).append(hotlist_id)
+
+    if name is not None:
+      hotlist.name = name
+    if summary is not None:
+      hotlist.summary = summary
+    if description is not None:
+      hotlist.description = description
+    if is_private is not None:
+      hotlist.is_private = is_private
+    if default_col_spec is not None:
+      hotlist.default_col_spec = default_col_spec
+    if owner_id is not None:
+      hotlist.owner_ids = [owner_id]
+    if add_editor_ids:
+      hotlist.editor_ids.extend(add_editor_ids)
+
+  def RemoveHotlistEditors(self, cnxn, hotlist_id, remove_editor_ids):
+    hotlist = self.hotlists_by_id.get(hotlist_id)
+    if not hotlist:
+      raise features_svc.NoSuchHotlistException(
+          'Hotlist "%s" not found!' % hotlist_id)
+    for editor_id in remove_editor_ids:
+      hotlist.editor_ids.remove(editor_id)
+      self.hotlists_id_by_user[editor_id].remove(hotlist_id)
+
+  def AddIssuesToHotlists(self, cnxn, hotlist_ids, added_tuples, issue_svc,
+                          chart_svc, commit=True):
+    for hotlist_id in hotlist_ids:
+      self.UpdateHotlistItems(cnxn, hotlist_id, [], added_tuples, commit=commit)
+
+  def RemoveIssuesFromHotlists(self, cnxn, hotlist_ids, issue_ids, issue_svc,
+                               chart_svc, commit=True):
+    for hotlist_id in hotlist_ids:
+      self.UpdateHotlistItems(cnxn, hotlist_id, issue_ids, [], commit=commit)
+
+  def UpdateHotlistIssues(
+      self,
+      cnxn,
+      hotlist_id,
+      updated_items,
+      remove_issue_ids,
+      issue_svc,
+      chart_svc,
+      commit=True):
+    if not updated_items and not remove_issue_ids:
+      raise exceptions.InputException('No changes to make')
+
+    hotlist = self.hotlists_by_id.get(hotlist_id)
+    if not hotlist:
+      raise NoSuchHotlistException()
+
+    updated_ids = [item.issue_id for item in updated_items]
+    items = [
+        item for item in hotlist.items
+        if item.issue_id not in updated_ids + remove_issue_ids
+    ]
+    hotlist.items = sorted(updated_items + items, key=lambda item: item.rank)
+
+    # Remove all removed and updated issues.
+    for issue_id in remove_issue_ids + updated_ids:
+      try:
+        self.hotlists_id_by_issue[issue_id].remove(hotlist_id)
+      except (ValueError, KeyError):
+        pass
+    # Add all new or updated issues.
+    for item in updated_items:
+      self.hotlists_id_by_issue.setdefault(item.issue_id, []).append(hotlist_id)
+
+  def UpdateHotlistItems(
+      self, cnxn, hotlist_id, remove, added_issue_tuples, commit=True):
+    hotlist = self.hotlists_by_id.get(hotlist_id)
+    if not hotlist:
+      raise features_svc.NoSuchHotlistException(
+          'Hotlist "%s" not found!' % hotlist_id)
+    current_issues_ids = {
+        item.issue_id for item in hotlist.items}
+    items = [
+        item for item in hotlist.items if
+        item.issue_id not in remove]
+
+    if hotlist.items:
+      items_sorted = sorted(hotlist.items, key=lambda item: item.rank)
+      rank_base = items_sorted[-1].rank + 10
+    else:
+      rank_base = 1
+
+    new_hotlist_items = [
+        features_pb2.MakeHotlistItem(
+            issue_id, rank+rank_base*10, adder_id, date, note)
+        for rank, (issue_id, adder_id, date, note) in
+        enumerate(added_issue_tuples)
+        if issue_id not in current_issues_ids]
+    items.extend(new_hotlist_items)
+    hotlist.items = items
+
+    for issue_id in remove:
+      try:
+        self.hotlists_id_by_issue[issue_id].remove(hotlist_id)
+      except ValueError:
+        pass
+    for item in new_hotlist_items:
+      try:
+        self.hotlists_id_by_issue[item.issue_id].append(hotlist_id)
+      except KeyError:
+        self.hotlists_id_by_issue[item.issue_id] = [hotlist_id]
+
+  def UpdateHotlistItemsFields(
+      self, cnxn, hotlist_id, new_ranks=None, new_notes=None, commit=True):
+    hotlist = self.hotlists_by_id.get(hotlist_id)
+    if not hotlist:
+      raise features_svc.NoSuchHotlistException(
+          'Hotlist "%s" not found!' % hotlist_id)
+    if new_ranks is None:
+      new_ranks = {}
+    if new_notes is None:
+      new_notes = {}
+    for hotlist_item in hotlist.items:
+      if hotlist_item.issue_id in new_ranks:
+        hotlist_item.rank = new_ranks[hotlist_item.issue_id]
+      if hotlist_item.issue_id in new_notes:
+        hotlist_item.note = new_notes[hotlist_item.issue_id]
+
+    hotlist.items.sort(key=lambda item: item.rank)
+
+  def TransferHotlistOwnership(
+      self, cnxn, hotlist, new_owner_id, remain_editor, commit=True):
+    """Transfers ownership of a hotlist to a new owner."""
+    new_editor_ids = hotlist.editor_ids
+    if remain_editor:
+      new_editor_ids.extend(hotlist.owner_ids)
+    if new_owner_id in new_editor_ids:
+      new_editor_ids.remove(new_owner_id)
+    new_follower_ids = hotlist.follower_ids
+    if new_owner_id in new_follower_ids:
+      new_follower_ids.remove(new_owner_id)
+    self.UpdateHotlistRoles(
+        cnxn, hotlist.hotlist_id, [new_owner_id], new_editor_ids,
+        new_follower_ids, commit=commit)
+
+  def LookupUserHotlists(self, cnxn, user_ids):
+    """Return dict of {user_id: [hotlist_id, hotlist_id...]}."""
+    users_hotlists_dict = {
+        user_id: self.hotlists_id_by_user.get(user_id, [])
+        for user_id in user_ids
+    }
+    return users_hotlists_dict
+
+  def LookupIssueHotlists(self, cnxn, issue_ids):
+    """Return dict of {issue_id: [hotlist_id, hotlist_id...]}."""
+    issues_hotlists_dict = {
+        issue_id: self.hotlists_id_by_issue[issue_id]
+        for issue_id in issue_ids
+        if issue_id in self.hotlists_id_by_issue}
+    return issues_hotlists_dict
+
+  def LookupHotlistIDs(self, cnxn, hotlist_names, owner_ids):
+    id_dict = {}
+    for name in hotlist_names:
+      for owner_id in owner_ids:
+        hotlist = self.test_hotlists.get((name, owner_id))
+        if hotlist:
+          if not hotlist.owner_ids:  # Should never happen.
+            logging.warn('Unowned Hotlist: id:%r, name:%r',
+                         hotlist.hotlist_id, hotlist.name)
+            continue
+          id_dict[(name.lower(), owner_id)] = hotlist.hotlist_id
+    return id_dict
+
+  def GetHotlists(self, cnxn, hotlist_ids, use_cache=True):
+    """Returns dict of {hotlist_id: hotlist PB}."""
+    result = {}
+    for hotlist_id in hotlist_ids:
+      hotlist = self.hotlists_by_id.get(hotlist_id)
+      if hotlist:
+        result[hotlist_id] = hotlist
+      else:
+        raise features_svc.NoSuchHotlistException()
+    return result
+
+  def GetHotlistsByUserID(self, cnxn, user_id, use_cache=True):
+    """Get a list of hotlist PBs for a given user."""
+    hotlist_id_dict = self.LookupUserHotlists(cnxn, [user_id])
+    hotlists = self.GetHotlists(cnxn, hotlist_id_dict.get(
+        user_id, []), use_cache=use_cache)
+    return list(hotlists.values())
+
+  def GetHotlistsByIssueID(self, cnxn, issue_id, use_cache=True):
+    """Get a list of hotlist PBs for a given issue."""
+    hotlist_id_dict = self.LookupIssueHotlists(cnxn, [issue_id])
+    hotlists = self.GetHotlists(cnxn, hotlist_id_dict.get(
+        issue_id, []), use_cache=use_cache)
+    return list(hotlists.values())
+
+  def GetHotlist(self, cnxn, hotlist_id, use_cache=True):
+    """Return hotlist PB."""
+    hotlist_id_dict = self.GetHotlists(cnxn, [hotlist_id], use_cache=use_cache)
+    return hotlist_id_dict.get(hotlist_id)
+
+  def GetHotlistsByID(self, cnxn, hotlist_ids, use_cache=True):
+    hotlists_dict = {}
+    missed_ids = []
+    for hotlist_id in hotlist_ids:
+      hotlist = self.hotlists_by_id.get(hotlist_id)
+      if hotlist:
+        hotlists_dict[hotlist_id] = hotlist
+      else:
+        missed_ids.append(hotlist_id)
+    return hotlists_dict, missed_ids
+
+  def GetHotlistByID(self, cnxn, hotlist_id, use_cache=True):
+    hotlists_dict, _ = self.GetHotlistsByID(
+        cnxn, [hotlist_id], use_cache=use_cache)
+    return hotlists_dict[hotlist_id]
+
+  def UpdateHotlistRoles(
+      self, cnxn, hotlist_id, owner_ids, editor_ids, follower_ids, commit=True):
+    hotlist = self.hotlists_by_id.get(hotlist_id)
+    if not hotlist:
+      raise features_svc.NoSuchHotlistException(
+          'Hotlist "%s" not found!' % hotlist_id)
+
+    # Remove hotlist_ids to clear old roles
+    for user_id in (hotlist.owner_ids + hotlist.editor_ids +
+                    hotlist.follower_ids):
+      if hotlist_id in self.hotlists_id_by_user[user_id]:
+        self.hotlists_id_by_user[user_id].remove(hotlist_id)
+    old_owner_id = None
+    if hotlist.owner_ids:
+      old_owner_id = hotlist.owner_ids[0]
+    self.test_hotlists.pop((hotlist.name, old_owner_id), None)
+
+    hotlist.owner_ids = owner_ids
+    hotlist.editor_ids = editor_ids
+    hotlist.follower_ids = follower_ids
+
+    # Add new hotlist roles
+    for user_id in owner_ids+editor_ids+follower_ids:
+      try:
+        if hotlist_id not in self.hotlists_id_by_user[user_id]:
+          self.hotlists_id_by_user[user_id].append(hotlist_id)
+      except KeyError:
+        self.hotlists_id_by_user[user_id] = [hotlist_id]
+    new_owner_id = None
+    if owner_ids:
+      new_owner_id = owner_ids[0]
+    self.test_hotlists[(hotlist.name, new_owner_id)] = hotlist
+
+  def DeleteHotlist(self, cnxn, hotlist_id, commit=True):
+    hotlist = self.hotlists_by_id.pop(hotlist_id, None)
+    if hotlist is not None:
+      self.test_hotlists.pop((hotlist.name, hotlist.owner_ids[0]), None)
+      user_ids = hotlist.owner_ids+hotlist.editor_ids+hotlist.follower_ids
+      for user_id in user_ids:
+        try:
+          self.hotlists_id_by_user[user_id].remove(hotlist_id)
+        except (ValueError, KeyError):
+          pass
+      for item in hotlist.items:
+        try:
+          self.hotlists_id_by_issue[item.issue_id].remove(hotlist_id)
+        except (ValueError, KeyError):
+          pass
+      for owner_id in hotlist.owner_ids:
+        self.test_hotlists.pop((hotlist.name, owner_id), None)
+
+  def ExpungeHotlists(
+      self, cnxn, hotlist_ids, star_svc, user_svc, chart_svc, commit=True):
+    self.expunged_hotlist_ids.extend(hotlist_ids)
+    for hotlist_id in hotlist_ids:
+      self.DeleteHotlist(cnxn, hotlist_id)
+
+  def ExpungeUsersInHotlists(
+      self, cnxn, user_ids, star_svc, user_svc, chart_svc):
+    self.expunged_users_in_hotlists.extend(user_ids)
+
+  # end of Hotlist functions
+
+  def GetRecentCommands(self, cnxn, user_id, project_id):
+    return [], []
+
+  def ExpungeSavedQueriesExecuteInProject(self, _cnxn, project_id):
+    self.expunged_saved_queries.append(project_id)
+
+  def ExpungeSavedQueriesByUsers(self, cnxn, user_ids, limit=None):
+    self.expunged_users_in_saved_queries.extend(user_ids)
+
+  def ExpungeFilterRules(self, _cnxn, project_id):
+    self.expunged_filter_rules.append(project_id)
+
+  def ExpungeFilterRulesByUser(self, cnxn, user_ids_by_email):
+    emails = user_ids_by_email.keys()
+    user_ids = user_ids_by_email.values()
+    project_rules_dict = collections.defaultdict(list)
+    for project_id, rules in self.test_rules.iteritems():
+      for rule in rules:
+        if rule.default_owner_id in user_ids:
+          project_rules_dict[project_id].append(rule)
+          continue
+        if any(cc_id in user_ids for cc_id in rule.add_cc_ids):
+          project_rules_dict[project_id].append(rule)
+          continue
+        if any(addr in emails for addr in rule.add_notify_addrs):
+          project_rules_dict[project_id].append(rule)
+          continue
+        if any((email in rule.predicate) for email in emails):
+          project_rules_dict[project_id].append(rule)
+          continue
+      self.test_rules[project_id] = [
+          rule for rule in rules
+          if rule not in project_rules_dict[project_id]]
+    return project_rules_dict
+
+  def ExpungeQuickEditHistory(self, _cnxn, project_id):
+    self.expunged_quick_edit.append(project_id)
+
+  def ExpungeQuickEditsByUsers(self, cnxn, user_ids, limit=None):
+    self.expunged_users_in_quick_edits.extend(user_ids)
+
+  def GetFilterRules(self, cnxn, project_id):
+    return self.test_rules[project_id]
+
+  def GetCannedQueriesByProjectID(self, cnxn, project_id):
+    return [sq for (pid, _, sq) in self.saved_queries if pid == project_id]
+
+  def GetSavedQueriesByUserID(self, cnxn, user_id):
+    return [sq for (_, uid, sq) in self.saved_queries if uid == user_id]
+
+  def UpdateCannedQueries(self, cnxn, project_id, canned_queries):
+    self.saved_queries.extend(
+      [(project_id, None, cq) for cq in canned_queries])
+
+  def UpdateUserSavedQueries(self, cnxn, user_id, saved_queries):
+    self.saved_queries = [
+      (pid, uid, sq) for (pid, uid, sq) in self.saved_queries
+      if uid != user_id]
+    for sq in saved_queries:
+      if sq.executes_in_project_ids:
+        self.saved_queries.extend(
+          [(eipid, user_id, sq) for eipid in sq.executes_in_project_ids])
+      else:
+        self.saved_queries.append((None, user_id, sq))
+
+  def GetSubscriptionsInProjects(self, cnxn, project_ids):
+    sq_by_uid = {}
+    for pid, uid, sq in self.saved_queries:
+      if pid in project_ids:
+        if uid in sq_by_uid:
+          sq_by_uid[uid].append(sq)
+        else:
+          sq_by_uid[uid] = [sq]
+
+    return sq_by_uid
+
+  def GetSavedQuery(self, cnxn, query_id):
+    return tracker_pb2.SavedQuery()
+
+
+class PostData(object):
+  """A dictionary-like object that also implements getall()."""
+
+  def __init__(self, *args, **kwargs):
+    self.dictionary = dict(*args, **kwargs)
+
+  def getall(self, key):
+    """Return all values, assume that the value at key is already a list."""
+    return self.dictionary.get(key, [])
+
+  def get(self, key, default=None):
+    """Return first value, assume that the value at key is already a list."""
+    return self.dictionary.get(key, [default])[0]
+
+  def __getitem__(self, key):
+    """Return first value, assume that the value at key is already a list."""
+    return self.dictionary[key][0]
+
+  def __contains__(self, key):
+    return key in self.dictionary
+
+  def keys(self):
+    """Return the keys in the POST data."""
+    return list(self.dictionary.keys())
+
+
+class FakeFile:
+  def __init__(self, data=None):
+    self.data = data
+
+  def read(self):
+    return self.data
+
+  def write(self, content):
+    return
+
+  def __enter__(self):
+    return self
+
+  def __exit__(self, __1, __2, __3):
+    return None
+
+
+def gcs_open(filename, mode):
+  return FakeFile(filename)
diff --git a/testing/test/__init__.py b/testing/test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testing/test/__init__.py
diff --git a/testing/test/fake_test.py b/testing/test/fake_test.py
new file mode 100644
index 0000000..c098236
--- /dev/null
+++ b/testing/test/fake_test.py
@@ -0,0 +1,67 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Tests for the fake module."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import inspect
+import unittest
+
+from services import cachemanager_svc
+from services import config_svc
+from services import features_svc
+from services import issue_svc
+from services import project_svc
+from services import star_svc
+from services import user_svc
+from services import usergroup_svc
+from testing import fake
+
+fake_class_map = {
+    fake.AbstractStarService: star_svc.AbstractStarService,
+    fake.CacheManager: cachemanager_svc.CacheManager,
+    fake.ProjectService: project_svc.ProjectService,
+    fake.ConfigService: config_svc.ConfigService,
+    fake.IssueService: issue_svc.IssueService,
+    fake.UserGroupService: usergroup_svc.UserGroupService,
+    fake.UserService: user_svc.UserService,
+    fake.FeaturesService: features_svc.FeaturesService,
+    }
+
+
+class FakeMetaTest(unittest.TestCase):
+
+  def testFunctionsHaveSameSignatures(self):
+    """Verify that the fake class methods match the real ones."""
+    for fake_cls, real_cls in fake_class_map.items():
+      fake_attrs = set(dir(fake_cls))
+      real_attrs = set(dir(real_cls))
+      both_attrs = fake_attrs.intersection(real_attrs)
+      to_test = [x for x in both_attrs if '__' not in x]
+      for name in to_test:
+        real_attr = getattr(real_cls, name)
+        assert inspect.ismethod(real_attr)
+        real_spec = inspect.getargspec(real_attr)
+        fake_spec = inspect.getargspec(getattr(fake_cls, name))
+        # check same number of args and kwargs
+        real_kw_len = len(real_spec[3]) if real_spec[3] else 0
+        fake_kw_len = len(fake_spec[3]) if fake_spec[3] else 0
+
+        self.assertEqual(
+            len(real_spec[0]) - real_kw_len,
+            len(fake_spec[0]) - fake_kw_len,
+            'Unequal number of args on %s.%s' % (fake_cls.__name__, name))
+        self.assertEqual(
+            real_kw_len, fake_kw_len,
+            'Unequal number of kwargs on %s.%s' % (fake_cls.__name__, name))
+        if real_kw_len:
+          self.assertEqual(
+              real_spec[0][-real_kw_len:], fake_spec[0][-fake_kw_len:],
+              'Mismatched kwargs on %s.%s' % (fake_cls.__name__, name))
+        self.assertEqual(
+            real_spec[3], fake_spec[3],
+            'Mismatched kwarg defaults on %s.%s' % (fake_cls.__name__, name))
diff --git a/testing/test/testing_helpers_test.py b/testing/test/testing_helpers_test.py
new file mode 100644
index 0000000..7493b04
--- /dev/null
+++ b/testing/test/testing_helpers_test.py
@@ -0,0 +1,74 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Tests for the testing_helpers module."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import unittest
+
+from testing import testing_helpers
+
+
+class TestingHelpersTest(unittest.TestCase):
+
+  def testMakeMonorailRequest(self):
+    mr = testing_helpers.MakeMonorailRequest(
+        path='/foo?key1=2&key2=&key3')
+
+    self.assertEqual(None, mr.GetIntParam('foo'))
+    self.assertEqual(2, mr.GetIntParam('key1'))
+    self.assertEqual(None, mr.GetIntParam('key2'))
+    self.assertEqual(None, mr.GetIntParam('key3'))
+    self.assertEqual(3, mr.GetIntParam('key2', default_value=3))
+    self.assertEqual(3, mr.GetIntParam('foo', default_value=3))
+
+  def testGetRequestObjectsBasics(self):
+    request, mr = testing_helpers.GetRequestObjects(
+        path='/foo/bar/wee?sna=foo',
+        params={'ya': 'hoo'}, method='POST')
+
+    # supplied as part of the url
+    self.assertEqual('foo', mr.GetParam('sna'))
+
+    # supplied as a param
+    self.assertEqual('hoo', mr.GetParam('ya'))
+
+    # default Host header
+    self.assertEqual('127.0.0.1', request.host)
+
+  def testGetRequestObjectsHeaders(self):
+    # with some headers
+    request, _mr = testing_helpers.GetRequestObjects(
+        headers={'Accept-Language': 'en', 'Host': 'pickledsheep.com'},
+        path='/foo/bar/wee?sna=foo')
+
+    # default Host header
+    self.assertEqual('pickledsheep.com', request.host)
+
+    # user specified headers
+    self.assertEqual('en', request.headers['Accept-Language'])
+
+  def testGetRequestObjectsUserInfo(self):
+    user_id = '123'
+
+    _request, mr = testing_helpers.GetRequestObjects(
+        user_info={'user_id': user_id})
+
+    self.assertEqual(user_id, mr.auth.user_id)
+
+
+class BlankTest(unittest.TestCase):
+
+  def testBlank(self):
+    blank = testing_helpers.Blank(
+        foo='foo',
+        bar=123,
+        inc=lambda x: x + 1)
+
+    self.assertEqual('foo', blank.foo)
+    self.assertEqual(123, blank.bar)
+    self.assertEqual(5, blank.inc(4))
diff --git a/testing/testing_helpers.py b/testing/testing_helpers.py
new file mode 100644
index 0000000..097275a
--- /dev/null
+++ b/testing/testing_helpers.py
@@ -0,0 +1,160 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Helpers for testing."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import email
+
+from framework import emailfmt
+from framework import framework_bizobj
+from proto import user_pb2
+from services import service_manager
+from services import template_svc
+from testing import fake
+from tracker import tracker_constants
+import webapp2
+
+DEFAULT_HOST = '127.0.0.1'
+
+MINIMAL_HEADER_LINES = [
+    ('From', 'user@example.com'),
+    ('To', 'proj@monorail.example.com'),
+    ('Cc', 'ningerso@chromium.org'),
+    ('Subject', 'Issue 123 in proj: broken link'),
+]
+
+# Add one more (long) line for In-Reply-To
+HEADER_LINES = MINIMAL_HEADER_LINES + [
+    ('In-Reply-To', '<0=969704940193871313=13442892928193434663='
+     'proj@monorail.example.com>'),
+]
+
+AlertEmailHeader = emailfmt.AlertEmailHeader
+ALERT_EMAIL_HEADER_LINES = HEADER_LINES + [
+    (AlertEmailHeader.INCIDENT_ID, '1234567890123456789'),
+    (AlertEmailHeader.OWNER, 'owner@example.com'),
+    (AlertEmailHeader.CC, 'cc1@example.com,cc2@example.com'),
+    (AlertEmailHeader.PRIORITY, '0'),
+    (AlertEmailHeader.STATUS, 'Unconfirmed'),
+    (AlertEmailHeader.COMPONENT, 'Component'),
+    (AlertEmailHeader.TYPE, 'Bug'),
+    (AlertEmailHeader.OS, 'Android,Windows'),
+    (AlertEmailHeader.LABEL, ''),
+]
+
+
+# TODO(crbug/monorail/7238): this should be moved to framework_bizobj
+# as this is no longer only used for testing.
+def ObscuredEmail(address):
+  (_username, _domain, _obs_username,
+   obs_email) = framework_bizobj.ParseAndObscureAddress(address)
+  return obs_email
+
+def MakeMessage(header_list, body):
+  """Convenience function to make an email.message.Message."""
+  msg = email.message.Message()
+  for key, value in header_list:
+    msg[key] = value
+  msg.set_payload(body)
+  return msg
+
+
+def MakeMonorailRequest(*args, **kwargs):
+  """Get just the monorailrequest.MonorailRequest() from GetRequestObjects."""
+  _request, mr = GetRequestObjects(*args, **kwargs)
+  return mr
+
+
+def GetRequestObjects(
+    headers=None, path='/', params=None, payload=None, user_info=None,
+    project=None, method='GET', perms=None, services=None, hotlist=None):
+  """Make fake request and MonorailRequest objects for testing.
+
+  Host param will override the 'Host' header, and has a default value of
+  '127.0.0.1'.
+
+  Args:
+    headers: Dict of HTTP header strings.
+    path: Path part of the URL in the request.
+    params: Dict of query-string parameters.
+    user_info: Dict of user attributes to set on a MonorailRequest object.
+        For example, "user_id: 5" causes self.auth.user_id=5.
+    project: optional Project object for the current request.
+    method: 'GET' or 'POST'.
+    perms: PermissionSet to use for this request.
+    services: Connections to backends.
+    hotlist: optional Hotlist object for the current request
+
+  Returns:
+    A tuple of (http Request, monorailrequest.MonorailRequest()).
+  """
+  headers = headers or {}
+  params = params or {}
+
+  headers.setdefault('Host', DEFAULT_HOST)
+  post_items=None
+  if method == 'POST' and payload:
+    post_items = payload
+  elif method == 'POST' and params:
+    post_items = params
+
+  if not services:
+    services = service_manager.Services(
+        project=fake.ProjectService(),
+        user=fake.UserService(),
+        usergroup=fake.UserGroupService(),
+        features=fake.FeaturesService())
+    services.project.TestAddProject('proj')
+    services.features.TestAddHotlist('hotlist')
+
+  request = webapp2.Request.blank(path, headers=headers, POST=post_items)
+  mr = fake.MonorailRequest(
+      services, user_info=user_info, project=project, perms=perms,
+      params=params, hotlist=hotlist)
+  mr.ParseRequest(
+      request, services, do_user_lookups=False)
+  mr.auth.user_pb = user_pb2.MakeUser(0)
+  return request, mr
+
+
+class Blank(object):
+  """Simple class that assigns all named args to attributes.
+
+  Tip: supply a lambda to define a method.
+  """
+
+  def __init__(self, **kwargs):
+    vars(self).update(kwargs)
+
+  def __repr__(self):
+    return '%s(%s)' % (self.__class__.__name__, str(vars(self)))
+
+  def __eq__(self, other):
+    if other is None:
+      return False
+    return vars(self) == vars(other)
+
+
+def DefaultTemplateRows():
+  return [(
+    None,
+    789,
+    template_dict['name'],
+    template_dict['content'],
+    template_dict['summary'],
+    template_dict.get('summary_must_be_edited'),
+    None,
+    template_dict['status'],
+    template_dict.get('members_only', False),
+    template_dict.get('owner_defaults_to_member', True),
+    template_dict.get('component_required', False),
+    ) for template_dict in tracker_constants.DEFAULT_TEMPLATES]
+
+
+def DefaultTemplates():
+  return [template_svc.UnpackTemplate(t) for t in DefaultTemplateRows()]
