Эх сурвалжийг харах

[reclient] Add cred cache status as a metrics label

This will help analyze startup metrics

Bug: b/294945709
Change-Id: Ia397dbebef7cc30b49c614dda51e56f482b6145b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4847325
Commit-Queue: Ben Segall <bentekkie@google.com>
Auto-Submit: Ben Segall <bentekkie@google.com>
Reviewed-by: Junji Watanabe <jwata@google.com>
Ben Segall 1 жил өмнө
parent
commit
29282b581b

+ 25 - 1
reclient_helper.py

@@ -94,6 +94,26 @@ def find_cache_dir(tmp_dir):
     return os.path.join(tmp_dir, 'cache')
 
 
+def auth_cache_status():
+    cred_file = os.path.join(os.environ["RBE_cache_dir"], "reproxy.creds")
+    if not os.path.isfile(cred_file):
+        return "missing", "UNSPECIFIED"
+    try:
+        with open(cred_file) as f:
+            status = "valid"
+            mechanism = "UNSPECIFIED"
+            for line in f.readlines():
+                if "seconds:" in line:
+                    exp = int(line.strip()[len("seconds:"):].strip())
+                    if exp < (time.time() + 5 * 60):
+                        status = "expired"
+                elif "mechanism:" in line:
+                    mechanism = line.strip()[len("mechanism:"):].strip()
+            return status, mechanism
+    except OSError:
+        return "missing", "UNSPECIFIED"
+
+
 def set_reproxy_metrics_flags(tool):
     """Helper to setup metrics collection flags for reproxy.
 
@@ -109,7 +129,11 @@ def set_reproxy_metrics_flags(tool):
         os.environ.setdefault("RBE_invocation_id", autoninja_id)
     os.environ.setdefault("RBE_metrics_project", "chromium-reclient-metrics")
     os.environ.setdefault("RBE_metrics_table", "rbe_metrics.builds")
-    os.environ.setdefault("RBE_metrics_labels", "source=developer,tool=" + tool)
+    labels = "source=developer,tool=" + tool
+    auth_status, auth_mechanism = auth_cache_status()
+    labels += ",creds_cache_status=" + auth_status
+    labels += ",creds_cache_mechanism=" + auth_mechanism
+    os.environ.setdefault("RBE_metrics_labels", labels)
     os.environ.setdefault("RBE_metrics_prefix", "go.chromium.org")
 
 

+ 182 - 4
tests/ninja_reclient_test.py

@@ -7,6 +7,7 @@ import hashlib
 import os
 import os.path
 import sys
+import time
 import unittest
 import unittest.mock
 
@@ -42,8 +43,8 @@ class NinjaReclientTest(trial_dir.TestCase):
     @unittest.mock.patch('subprocess.call', return_value=0)
     @unittest.mock.patch('ninja.main', return_value=0)
     @unittest.mock.patch('reclient_metrics.check_status', return_value=True)
-    def test_ninja_reclient_collect_metrics(self, mock_metrics_status,
-                                            mock_ninja, mock_call):
+    def test_ninja_reclient_collect_metrics_cache_missing(
+            self, mock_metrics_status, mock_ninja, mock_call):
         reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
         reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
                                     'reproxy.cfg')
@@ -99,8 +100,185 @@ class NinjaReclientTest(trial_dir.TestCase):
                          "chromium-reclient-metrics")
         self.assertEqual(os.environ.get('RBE_metrics_table'),
                          "rbe_metrics.builds")
-        self.assertEqual(os.environ.get('RBE_metrics_labels'),
-                         "source=developer,tool=ninja_reclient")
+        self.assertEqual(
+            os.environ.get('RBE_metrics_labels'),
+            "source=developer,tool=ninja_reclient,"
+            "creds_cache_status=missing,creds_cache_mechanism=UNSPECIFIED")
+        self.assertEqual(os.environ.get('RBE_metrics_prefix'),
+                         "go.chromium.org")
+
+        mock_metrics_status.assert_called_once_with("out/a")
+        mock_ninja.assert_called_once_with(argv)
+        mock_call.assert_has_calls([
+            unittest.mock.call([
+                os.path.join(self.root_dir, reclient_bin_dir,
+                             'bootstrap' + gclient_paths.GetExeSuffix()),
+                "--re_proxy=" +
+                os.path.join(self.root_dir, reclient_bin_dir,
+                             'reproxy' + gclient_paths.GetExeSuffix()),
+                "--cfg=" + os.path.join(self.root_dir, reclient_cfg)
+            ]),
+            unittest.mock.call([
+                os.path.join(self.root_dir, reclient_bin_dir,
+                             'bootstrap' + gclient_paths.GetExeSuffix()),
+                "--shutdown",
+                "--cfg=" + os.path.join(self.root_dir, reclient_cfg)
+            ]),
+        ])
+
+    @unittest.mock.patch.dict(os.environ, {})
+    @unittest.mock.patch('subprocess.call', return_value=0)
+    @unittest.mock.patch('ninja.main', return_value=0)
+    @unittest.mock.patch('reclient_metrics.check_status', return_value=True)
+    def test_ninja_reclient_collect_metrics_cache_valid(self,
+                                                        mock_metrics_status,
+                                                        mock_ninja, mock_call):
+        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
+        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
+                                    'reproxy.cfg')
+        cache_dir = os.path.join(
+            self.root_dir, ".reproxy_cache",
+            hashlib.md5(
+                os.path.join(self.root_dir, "out", "a",
+                             ".reproxy_tmp").encode()).hexdigest())
+        write('.gclient', '')
+        write('.gclient_entries', 'entries = {"buildtools": "..."}')
+        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
+        write(reclient_cfg, '0.0')
+        write(
+            os.path.join(cache_dir, "reproxy.creds"), """
+mechanism:  GCLOUD
+expiry:  {
+  seconds:  %d
+}
+              """ % (int(time.time()) + 10 * 60))
+        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]
+
+        self.assertEqual(0, ninja_reclient.main(argv))
+
+        self.assertTrue(
+            os.path.isdir(
+                os.path.join(self.root_dir, "out", "a", ".reproxy_tmp")))
+        self.assertTrue(os.path.isdir(cache_dir))
+        self.assertTrue(
+            os.path.isdir(
+                os.path.join(self.root_dir, "out", "a", ".reproxy_tmp",
+                             "logs")))
+        self.assertEqual(
+            os.environ.get('RBE_output_dir'),
+            os.path.join(self.root_dir, "out", "a", ".reproxy_tmp", "logs"))
+        self.assertEqual(
+            os.environ.get('RBE_proxy_log_dir'),
+            os.path.join(self.root_dir, "out", "a", ".reproxy_tmp", "logs"))
+        self.assertEqual(os.environ.get('RBE_cache_dir'), cache_dir)
+        if sys.platform.startswith('win'):
+            self.assertEqual(
+                os.environ.get('RBE_server_address'),
+                "pipe://%s/reproxy.pipe" % hashlib.md5(
+                    os.path.join(self.root_dir, "out", "a",
+                                 ".reproxy_tmp").encode()).hexdigest())
+        else:
+            self.assertEqual(
+                os.environ.get('RBE_server_address'),
+                "unix:///tmp/reproxy_%s.sock" % hashlib.sha256(
+                    os.path.join(self.root_dir, "out", "a",
+                                 ".reproxy_tmp").encode()).hexdigest())
+
+        self.assertEqual(os.environ.get('RBE_metrics_project'),
+                         "chromium-reclient-metrics")
+        self.assertEqual(os.environ.get('RBE_metrics_table'),
+                         "rbe_metrics.builds")
+        self.assertEqual(
+            os.environ.get('RBE_metrics_labels'),
+            "source=developer,tool=ninja_reclient,"
+            "creds_cache_status=valid,creds_cache_mechanism=GCLOUD")
+        self.assertEqual(os.environ.get('RBE_metrics_prefix'),
+                         "go.chromium.org")
+
+        mock_metrics_status.assert_called_once_with("out/a")
+        mock_ninja.assert_called_once_with(argv)
+        mock_call.assert_has_calls([
+            unittest.mock.call([
+                os.path.join(self.root_dir, reclient_bin_dir,
+                             'bootstrap' + gclient_paths.GetExeSuffix()),
+                "--re_proxy=" +
+                os.path.join(self.root_dir, reclient_bin_dir,
+                             'reproxy' + gclient_paths.GetExeSuffix()),
+                "--cfg=" + os.path.join(self.root_dir, reclient_cfg)
+            ]),
+            unittest.mock.call([
+                os.path.join(self.root_dir, reclient_bin_dir,
+                             'bootstrap' + gclient_paths.GetExeSuffix()),
+                "--shutdown",
+                "--cfg=" + os.path.join(self.root_dir, reclient_cfg)
+            ]),
+        ])
+
+    @unittest.mock.patch.dict(os.environ, {})
+    @unittest.mock.patch('subprocess.call', return_value=0)
+    @unittest.mock.patch('ninja.main', return_value=0)
+    @unittest.mock.patch('reclient_metrics.check_status', return_value=True)
+    def test_ninja_reclient_collect_metrics_cache_expired(
+            self, mock_metrics_status, mock_ninja, mock_call):
+        reclient_bin_dir = os.path.join('src', 'buildtools', 'reclient')
+        reclient_cfg = os.path.join('src', 'buildtools', 'reclient_cfgs',
+                                    'reproxy.cfg')
+        cache_dir = os.path.join(
+            self.root_dir, ".reproxy_cache",
+            hashlib.md5(
+                os.path.join(self.root_dir, "out", "a",
+                             ".reproxy_tmp").encode()).hexdigest())
+        write('.gclient', '')
+        write('.gclient_entries', 'entries = {"buildtools": "..."}')
+        write(os.path.join(reclient_bin_dir, 'version.txt'), '0.0')
+        write(reclient_cfg, '0.0')
+        write(
+            os.path.join(cache_dir, "reproxy.creds"), """
+mechanism:  GCLOUD
+expiry:  {
+  seconds:  %d
+}
+              """ % (int(time.time())))
+        argv = ["ninja_reclient.py", "-C", "out/a", "chrome"]
+
+        self.assertEqual(0, ninja_reclient.main(argv))
+
+        self.assertTrue(
+            os.path.isdir(
+                os.path.join(self.root_dir, "out", "a", ".reproxy_tmp")))
+        self.assertTrue(os.path.isdir(cache_dir))
+        self.assertTrue(
+            os.path.isdir(
+                os.path.join(self.root_dir, "out", "a", ".reproxy_tmp",
+                             "logs")))
+        self.assertEqual(
+            os.environ.get('RBE_output_dir'),
+            os.path.join(self.root_dir, "out", "a", ".reproxy_tmp", "logs"))
+        self.assertEqual(
+            os.environ.get('RBE_proxy_log_dir'),
+            os.path.join(self.root_dir, "out", "a", ".reproxy_tmp", "logs"))
+        self.assertEqual(os.environ.get('RBE_cache_dir'), cache_dir)
+        if sys.platform.startswith('win'):
+            self.assertEqual(
+                os.environ.get('RBE_server_address'),
+                "pipe://%s/reproxy.pipe" % hashlib.md5(
+                    os.path.join(self.root_dir, "out", "a",
+                                 ".reproxy_tmp").encode()).hexdigest())
+        else:
+            self.assertEqual(
+                os.environ.get('RBE_server_address'),
+                "unix:///tmp/reproxy_%s.sock" % hashlib.sha256(
+                    os.path.join(self.root_dir, "out", "a",
+                                 ".reproxy_tmp").encode()).hexdigest())
+
+        self.assertEqual(os.environ.get('RBE_metrics_project'),
+                         "chromium-reclient-metrics")
+        self.assertEqual(os.environ.get('RBE_metrics_table'),
+                         "rbe_metrics.builds")
+        self.assertEqual(
+            os.environ.get('RBE_metrics_labels'),
+            "source=developer,tool=ninja_reclient,"
+            "creds_cache_status=expired,creds_cache_mechanism=GCLOUD")
         self.assertEqual(os.environ.get('RBE_metrics_prefix'),
                          "go.chromium.org")