Пример #1
0
    def testRunCommandCaptureOutput(self):
        """Test that RunCommand can capture stdout if a command succeeds."""

        result = cros_build_lib.RunCommand(
            ['echo', '-n', 'Hi'],
            # Keep the test quiet options
            print_cmd=False,
            redirect_stdout=True,
            redirect_stderr=True)
        self.assertEqual(result, 'Hi')
Пример #2
0
    def testRunCommandErrorException(self):
        """Test that RunCommand can throw an exception when a command fails."""

        function = lambda: cros_build_lib.RunCommand(
            ['ls', '/nosuchdir'],
            # Keep the test quiet options
            print_cmd=False,
            redirect_stdout=True,
            redirect_stderr=True)
        self.assertRaises(cros_build_lib.RunCommandException, function)
Пример #3
0
 def testRunCommandSimple(self):
     """Test that RunCommand can run a simple successful command."""
     result = cros_build_lib.RunCommand(
         ['ls'],
         # Keep the test quiet options
         print_cmd=False,
         redirect_stdout=True,
         redirect_stderr=True,
         # Test specific options
         exit_code=True)
     self.assertEqual(result, 0)
Пример #4
0
 def testRunCommandError(self):
     """Test that RunCommand can return an error code for a failed command."""
     result = cros_build_lib.RunCommand(
         ['ls', '/nosuchdir'],
         # Keep the test quiet options
         print_cmd=False,
         redirect_stdout=True,
         redirect_stderr=True,
         # Test specific options
         exit_code=True)
     self.assertNotEqual(result, 0)
     self.assertEquals(type(result), int)
Пример #5
0
 def testRunCommandLogToFile(self):
     """Test that RunCommand can log output to a file correctly."""
     log_file = tempfile.mktemp()
     cros_build_lib.RunCommand(
         ['echo', '-n', 'Hi'],
         # Keep the test quiet options
         print_cmd=False,
         # Test specific options
         log_to_file=log_file)
     log_fh = open(log_file)
     log_data = log_fh.read()
     self.assertEquals('Hi', log_data)
     log_fh.close()
     os.remove(log_file)
Пример #6
0
    def testRunCommandErrorCodeNoException(self):
        """Test that RunCommand doesn't throw an exception with exit_code."""

        result = cros_build_lib.RunCommand(
            ['ls', '/nosuchdir'],
            # Keep the test quiet options
            print_cmd=False,
            redirect_stdout=True,
            redirect_stderr=True,
            # Test specific options
            exit_code=True)
        # We are really testing that it doesn't throw an exception if exit_code
        #  if true.
        self.assertNotEqual(result, 0)
        self.assertEquals(type(result), int)
Пример #7
0
    def testRunCommandErrorRetries(self):
        """Test that RunCommand can retry a failed command that always fails."""

        # We don't actually check that it's retrying, just exercise the code path.
        result = cros_build_lib.RunCommand(
            ['ls', '/nosuchdir'],
            # Keep the test quiet options
            print_cmd=False,
            redirect_stdout=True,
            redirect_stderr=True,
            # Test specific options
            num_retries=2,
            error_ok=True,
            exit_code=True)
        self.assertNotEqual(result, 0)
        self.assertEquals(type(result), int)
Пример #8
0
    def _enter(self):
        if os.getuid() == 0:
            cros_build_lib.Die('This script cannot be run as root.')

        start_for_tty = self._DaemonNeeded()
        if not start_for_tty:
            # Daemon is already started.
            return

        # Note despite the impulse to use 'sudo -v' instead of 'sudo true', the
        # builder's sudoers configuration is slightly whacked resulting in it
        # asking for password everytime.  As such use 'sudo true' instead.
        cmds = [
            'sudo -n true 2>/dev/null',
            'sudo -n true < /dev/null > /dev/null 2>&1'
        ]

        # First check to see if we're already authed.  If so, then we don't
        # need to prompt the user for their password.
        for idx, cmd in enumerate(cmds):
            ret = cros_build_lib.RunCommand(cmd,
                                            print_cmd=False,
                                            shell=True,
                                            error_code_ok=True)

            if ret.returncode != 0:
                tty_msg = 'Please disable tty_tickets using these instructions: %s'
                if os.path.exists("/etc/goobuntu"):
                    url = 'https://goto.google.com/chromeos-sudoers'
                else:
                    url = 'https://goo.gl/fz9YW'

                # If ttyless sudo is not strictly required for this script, don't
                # prompt for a password a second time. Instead, just complain.
                if idx > 0:
                    cros_build_lib.Error(tty_msg, url)
                    if not self._ttyless_sudo:
                        break

                # We need to go interactive and allow sudo to ask for credentials.
                interactive_cmd = cmd.replace(' -n', '')
                cros_build_lib.RunCommand(interactive_cmd,
                                          shell=True,
                                          print_cmd=False)

                # Verify that sudo access is set up properly.
                try:
                    cros_build_lib.RunCommand(cmd, shell=True, print_cmd=False)
                except cros_build_lib.RunCommandError:
                    if idx == 0:
                        raise
                    cros_build_lib.Die(
                        'tty_tickets must be disabled. ' + tty_msg, url)

        # Anything other than a timeout results in us shutting down.
        repeat_interval = self._repeat_interval * 60
        cmd = ('while :; do read -t %i; [ $? -le 128 ] && exit; %s; done' %
               (repeat_interval, '; '.join(cmds)))

        def ignore_sigint():
            # We don't want our sudo process shutdown till we shut it down;
            # since it's part of the session group it however gets SIGINT.
            # Thus suppress it (which bash then inherits).
            signal.signal(signal.SIGINT, signal.SIG_IGN)

        self._proc = subprocess.Popen(['bash', '-c', cmd],
                                      shell=False,
                                      close_fds=True,
                                      preexec_fn=ignore_sigint,
                                      stdin=subprocess.PIPE)

        self._existing_keepalive_value = os.environ.get('CROS_SUDO_KEEP_ALIVE')
        os.environ['CROS_SUDO_KEEP_ALIVE'] = start_for_tty