cros_sdk: add --strace for ease of debugging
Trying to run cros_sdk through strace is difficult -- it requires being
root, otherwise the sudo call fails in confusing ways. Add an --strace
option for devs to easily run things themselves. This aids in debugging
some of the lower level calls we make in chromite.
BUG=None
TEST=`cros_sdk --strace -- true` works
Change-Id: I879d35d49f45594b9da2cef538ff60ae623a6d47
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/3779418
Reviewed-by: Ram Chandrasekar <rchandrasekar@google.com>
Auto-Submit: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Ram Chandrasekar <rchandrasekar@google.com>
diff --git a/scripts/cros_sdk_unittest.py b/scripts/cros_sdk_unittest.py
index 6812bd5..9366370 100644
--- a/scripts/cros_sdk_unittest.py
+++ b/scripts/cros_sdk_unittest.py
@@ -6,9 +6,12 @@
import logging
import os
+import re
import subprocess
+import sys
import unittest
+from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_sdk_lib
from chromite.lib import cros_test_lib
@@ -84,6 +87,72 @@
cros_sdk.FetchRemoteTarballs(self.tempdir, ['gs://x/tar']))
+class CrosSdkParserCommandLineTest(cros_test_lib.MockTestCase):
+ """Tests involving the CLI."""
+
+ # pylint: disable=protected-access
+
+ # A typical sys.argv[0] that cros_sdk sees.
+ ARGV0 = '/home/chronos/chromiumos/chromite/bin/cros_sdk'
+
+ def setUp(self):
+ self.parser, _ = cros_sdk._CreateParser('1', '2')
+
+ def testSudoCommand(self):
+ """Verify basic sudo command building works."""
+ # Stabilize the env for testing.
+ for v in constants.CHROOT_ENVIRONMENT_ALLOWLIST + constants.ENV_PASSTHRU:
+ os.environ[v] = 'value'
+ os.environ['PATH'] = 'path'
+
+ cmd = cros_sdk._SudoCommand()
+ assert cmd[0] == 'sudo'
+ assert 'CHROMEOS_SUDO_PATH=path' in cmd
+ rlimits = [x for x in cmd if x.startswith('CHROMEOS_SUDO_RLIMITS=')]
+ assert len(rlimits) == 1
+
+ # Spot check some pass thru vars.
+ assert 'GIT_AUTHOR_EMAIL=value' in cmd
+ assert 'https_proxy=value' in cmd
+
+ # Make sure we only pass vars after `sudo`.
+ for i in range(1, len(cmd)):
+ assert '=' in cmd[i]
+ v = cmd[i].split('=', 1)[0]
+ assert re.match(r'^[A-Za-z0-9_]+$', v) is not None
+
+ def testReexecCommand(self):
+ """Verify reexec command line building."""
+ # Stub sudo logic since we tested it above already.
+ self.PatchObject(cros_sdk, '_SudoCommand', return_value=['sudo'])
+ opts = self.parser.parse_args([])
+ new_cmd = cros_sdk._BuildReExecCommand([self.ARGV0], opts)
+ assert new_cmd == ['sudo', '--', sys.executable, self.ARGV0]
+
+ def testReexecCommandStrace(self):
+ """Verify reexec command line building w/strace."""
+ # Stub sudo logic since we tested it above already.
+ self.PatchObject(cros_sdk, '_SudoCommand', return_value=['sudo'])
+
+ # Strace args passed, but not enabled.
+ opts = self.parser.parse_args(['--strace-arguments=-s4096 -v'])
+ new_cmd = cros_sdk._BuildReExecCommand([self.ARGV0], opts)
+ assert new_cmd == ['sudo', '--', sys.executable, self.ARGV0]
+
+ # Strace enabled.
+ opts = self.parser.parse_args(['--strace'])
+ new_cmd = cros_sdk._BuildReExecCommand([self.ARGV0], opts)
+ assert new_cmd == ['sudo', '--', 'strace', '--', sys.executable, self.ARGV0]
+
+ # Strace enabled w/args.
+ opts = self.parser.parse_args(['--strace', '--strace-arguments=-s4096 -v'])
+ new_cmd = cros_sdk._BuildReExecCommand([self.ARGV0], opts)
+ assert new_cmd == [
+ 'sudo', '--', 'strace', '-s4096', '-v', '--', sys.executable,
+ self.ARGV0,
+ ]
+
+
@unittest.skipIf(cros_build_lib.IsInsideChroot(),
'Tests only make sense outside the chroot')
@unittest.skip(