diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-02-14 03:08:18 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-02-14 03:08:18 +0000 |
commit | db729d703a0bf8fc92f011d160abd063c338b2f3 (patch) | |
tree | 35fa0fbaeaaddd9cc2a126a05eee3527b51e83a8 /deprecated/automation/common/command_executer_test.py | |
parent | dddbf2c6f79f2334de6d41b86d63698714ba1124 (diff) | |
parent | b75f321fc8978b92ce3db6886ccb966768f0c7a8 (diff) | |
download | toolchain-utils-db729d703a0bf8fc92f011d160abd063c338b2f3.tar.gz |
Snap for 6206568 from b75f321fc8978b92ce3db6886ccb966768f0c7a8 to rvc-releaseandroid-vts-11.0_r9android-vts-11.0_r8android-vts-11.0_r7android-vts-11.0_r6android-vts-11.0_r5android-vts-11.0_r4android-vts-11.0_r3android-vts-11.0_r2android-vts-11.0_r16android-vts-11.0_r15android-vts-11.0_r14android-vts-11.0_r13android-vts-11.0_r12android-vts-11.0_r11android-vts-11.0_r10android-vts-11.0_r1android-security-11.0.0_r76android-security-11.0.0_r75android-security-11.0.0_r74android-security-11.0.0_r73android-security-11.0.0_r72android-security-11.0.0_r71android-security-11.0.0_r70android-security-11.0.0_r69android-security-11.0.0_r68android-security-11.0.0_r67android-security-11.0.0_r66android-security-11.0.0_r65android-security-11.0.0_r64android-security-11.0.0_r63android-security-11.0.0_r62android-security-11.0.0_r61android-security-11.0.0_r60android-security-11.0.0_r59android-security-11.0.0_r58android-security-11.0.0_r57android-security-11.0.0_r56android-security-11.0.0_r55android-security-11.0.0_r54android-security-11.0.0_r53android-security-11.0.0_r52android-security-11.0.0_r51android-security-11.0.0_r50android-security-11.0.0_r49android-security-11.0.0_r1android-platform-11.0.0_r9android-platform-11.0.0_r8android-platform-11.0.0_r7android-platform-11.0.0_r6android-platform-11.0.0_r5android-platform-11.0.0_r4android-platform-11.0.0_r3android-platform-11.0.0_r2android-platform-11.0.0_r13android-platform-11.0.0_r12android-platform-11.0.0_r11android-platform-11.0.0_r10android-platform-11.0.0_r1android-cts-11.0_r9android-cts-11.0_r8android-cts-11.0_r7android-cts-11.0_r6android-cts-11.0_r5android-cts-11.0_r4android-cts-11.0_r3android-cts-11.0_r2android-cts-11.0_r16android-cts-11.0_r15android-cts-11.0_r14android-cts-11.0_r13android-cts-11.0_r12android-cts-11.0_r11android-cts-11.0_r10android-cts-11.0_r1android-11.0.0_r6android-11.0.0_r5android-11.0.0_r4android-11.0.0_r3android-11.0.0_r25android-11.0.0_r2android-11.0.0_r17android-11.0.0_r1android11-tests-releaseandroid11-security-releaseandroid11-s1-releaseandroid11-releaseandroid11-platform-releaseandroid11-gsi
Change-Id: I997cf91dd612b5e50d502271baf665232843c30a
Diffstat (limited to 'deprecated/automation/common/command_executer_test.py')
-rwxr-xr-x | deprecated/automation/common/command_executer_test.py | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/deprecated/automation/common/command_executer_test.py b/deprecated/automation/common/command_executer_test.py new file mode 100755 index 00000000..2caaa146 --- /dev/null +++ b/deprecated/automation/common/command_executer_test.py @@ -0,0 +1,210 @@ +#!/usr/bin/python2 +# +# Copyright 2011 Google Inc. All Rights Reserved. +# + +__author__ = 'kbaclawski@google.com (Krystian Baclawski)' + +import cStringIO +import logging +import os +import signal +import socket +import sys +import time +import unittest + + +def AddScriptDirToPath(): + """Required for remote python script execution.""" + path = os.path.abspath(__file__) + + for _ in range(3): + path, _ = os.path.split(path) + + if not path in sys.path: + sys.path.append(path) + + +AddScriptDirToPath() + +from automation.common.command_executer import CommandExecuter + + +class LoggerMock(object): + + def LogCmd(self, cmd, machine='', user=''): + if machine: + logging.info('[%s] Executing: %s', machine, cmd) + else: + logging.info('Executing: %s', cmd) + + def LogError(self, msg): + logging.error(msg) + + def LogWarning(self, msg): + logging.warning(msg) + + def LogOutput(self, msg): + logging.info(msg) + + +class CommandExecuterUnderTest(CommandExecuter): + + def __init__(self): + CommandExecuter.__init__(self, logger_to_set=LoggerMock()) + + # We will record stdout and stderr. + self._stderr = cStringIO.StringIO() + self._stdout = cStringIO.StringIO() + + @property + def stdout(self): + return self._stdout.getvalue() + + @property + def stderr(self): + return self._stderr.getvalue() + + def DataReceivedOnOutput(self, data): + self._stdout.write(data) + + def DataReceivedOnError(self, data): + self._stderr.write(data) + + +class CommandExecuterLocalTests(unittest.TestCase): + HOSTNAME = None + + def setUp(self): + self._executer = CommandExecuterUnderTest() + + def tearDown(self): + pass + + def RunCommand(self, method, **kwargs): + program = os.path.abspath(sys.argv[0]) + + return self._executer.RunCommand('%s runHelper %s' % (program, method), + machine=self.HOSTNAME, + **kwargs) + + def testCommandTimeout(self): + exit_code = self.RunCommand('SleepForMinute', command_timeout=3) + + self.assertTrue(-exit_code in [signal.SIGTERM, signal.SIGKILL], + 'Invalid exit code: %d' % exit_code) + + def testCommandTimeoutIfSigTermIgnored(self): + exit_code = self.RunCommand('IgnoreSigTerm', command_timeout=3) + + self.assertTrue(-exit_code in [signal.SIGTERM, signal.SIGKILL]) + + def testCommandSucceeded(self): + self.assertFalse(self.RunCommand('ReturnTrue')) + + def testCommandFailed(self): + self.assertTrue(self.RunCommand('ReturnFalse')) + + def testStringOnOutputStream(self): + self.assertFalse(self.RunCommand('EchoToOutputStream')) + self.assertEquals(self._executer.stderr, '') + self.assertEquals(self._executer.stdout, 'test') + + def testStringOnErrorStream(self): + self.assertFalse(self.RunCommand('EchoToErrorStream')) + self.assertEquals(self._executer.stderr, 'test') + self.assertEquals(self._executer.stdout, '') + + def testOutputStreamNonInteractive(self): + self.assertFalse( + self.RunCommand('IsOutputStreamInteractive'), + 'stdout stream is a terminal!') + + def testErrorStreamNonInteractive(self): + self.assertFalse( + self.RunCommand('IsErrorStreamInteractive'), + 'stderr stream is a terminal!') + + def testAttemptToRead(self): + self.assertFalse(self.RunCommand('WaitForInput', command_timeout=3)) + + def testInterruptedProcess(self): + self.assertEquals(self.RunCommand('TerminateBySigAbrt'), -signal.SIGABRT) + + +class CommandExecuterRemoteTests(CommandExecuterLocalTests): + HOSTNAME = socket.gethostname() + + def testCommandTimeoutIfSigTermIgnored(self): + exit_code = self.RunCommand('IgnoreSigTerm', command_timeout=6) + + self.assertEquals(exit_code, 255) + + lines = self._executer.stdout.splitlines() + pid = int(lines[0]) + + try: + with open('/proc/%d/cmdline' % pid) as f: + cmdline = f.read() + except IOError: + cmdline = '' + + self.assertFalse('IgnoreSigTerm' in cmdline, 'Process is still alive.') + + +class CommandExecuterTestHelpers(object): + + def SleepForMinute(self): + time.sleep(60) + return 1 + + def ReturnTrue(self): + return 0 + + def ReturnFalse(self): + return 1 + + def EchoToOutputStream(self): + sys.stdout.write('test') + return 0 + + def EchoToErrorStream(self): + sys.stderr.write('test') + return 0 + + def IsOutputStreamInteractive(self): + return sys.stdout.isatty() + + def IsErrorStreamInteractive(self): + return sys.stderr.isatty() + + def IgnoreSigTerm(self): + os.write(1, '%d' % os.getpid()) + signal.signal(signal.SIGTERM, signal.SIG_IGN) + time.sleep(30) + return 0 + + def WaitForInput(self): + try: + # can only read end-of-file marker + return os.read(0, 1) != '' + except OSError: + # that means that stdin descriptor is closed + return 0 + + def TerminateBySigAbrt(self): + os.kill(os.getpid(), signal.SIGABRT) + return 0 + + +if __name__ == '__main__': + FORMAT = '%(asctime)-15s %(levelname)s %(message)s' + logging.basicConfig(format=FORMAT, level=logging.DEBUG) + + if len(sys.argv) > 1: + if sys.argv[1] == 'runHelper': + helpers = CommandExecuterTestHelpers() + sys.exit(getattr(helpers, sys.argv[2])()) + + unittest.main() |