owners: Cache code-owners result.

Cache result of ListOwners to avoid making duplicate REST API calls.

Change-Id: Ie97fd7b605b73e1baed74302615f9df44fb622d2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2693914
Auto-Submit: Edward Lesmes <ehmaldonado@chromium.org>
Reviewed-by: Gavin Mak <gavinmak@google.com>
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
diff --git a/owners_client.py b/owners_client.py
index d97c5a5..5fcd555 100644
--- a/owners_client.py
+++ b/owners_client.py
@@ -205,14 +205,20 @@
     self._host = host
     self._project = project
     self._branch = branch
+    self._owners_cache = {}
 
   def ListOwners(self, path):
-    # GetOwnersForFile returns a list of account details sorted by order of
-    # best reviewer for path. If owners have the same score, the order is
-    # random.
-    data = gerrit_util.GetOwnersForFile(
-        self._host, self._project, self._branch, path)
-    return [d['account']['email'] for d in data['code_owners']]
+    if path not in self._owners_cache:
+      # GetOwnersForFile returns a list of account details sorted by order of
+      # best reviewer for path. If owners have the same score, the order is
+      # random.
+      data = gerrit_util.GetOwnersForFile(
+          self._host, self._project, self._branch, path)
+      self._owners_cache[path] = [
+        d['account']['email']
+        for d in data['code_owners']
+      ]
+    return self._owners_cache[path]
 
 
 def GetCodeOwnersClient(root, host, project, branch):
diff --git a/tests/owners_client_test.py b/tests/owners_client_test.py
index 2a0d128..1332f1d 100644
--- a/tests/owners_client_test.py
+++ b/tests/owners_client_test.py
@@ -87,6 +87,13 @@
         ['approver@example.com', 'reviewer@example.com', 'missing@example.com'],
         self.client.ListOwners('bar/everyone/foo.txt'))
 
+    # Result should be cached.
+    self.assertEquals(
+        ['approver@example.com', 'reviewer@example.com', 'missing@example.com'],
+        self.client.ListOwners('bar/everyone/foo.txt'))
+    gerrit_util.GetOwnersForFile.assert_called_once_with(
+        'host', 'project', 'branch', 'bar/everyone/foo.txt')
+
 
 class TestClient(owners_client.OwnersClient):
   def __init__(self, owners_by_path):