cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# -*- coding: utf-8 -*-
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# $Id$
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# pylint: disable=C0302
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTestdriver reporter module.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__copyright__ = \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCopyright (C) 2010-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThis file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncavailable from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncyou can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGeneral Public License (GPL) as published by the Free Software
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncFoundation, in version 2 as it comes in the "COPYING" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution. VirtualBox OSE is distributed in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsynchope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThe contents of this file may alternatively be used under the terms
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncof the Common Development and Distribution License Version 1.0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync(CDDL) only, as it comes in the "COPYING.CDDL" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution, in which case the provisions of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCDDL are applicable instead of those of the GPL.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncYou may elect to license modified versions of this file under the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncterms and conditions of either the GPL or the CDDL or both.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__version__ = "$Revision$"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Standard Python imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport array
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport datetime
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport errno
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport os
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport os.path
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport sys
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport time
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport threading
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport traceback
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Validation Kit imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom common import utils;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync## test reporter instance
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncg_oReporter = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncg_sReporterName = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncg_oLock = threading.Lock();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass PythonLoggingStream(object):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Python logging => testdriver/reporter.py stream.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def write(self, sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Writes python log message to our stream."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if g_oReporter != None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sText = sText.rstrip("\r\n");
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #g_oReporter.log(0, 'python: %s' % (sText), utils.getCallerName(), utils.getTimePrefix());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def flush(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Flushes the stream."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass ReporterBase(object):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Base class for the reporters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iVerbose = 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iDebug = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cErrors = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fTimedOut = False; # Once set, it trickles all the way up.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.atTests = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sName = os.path.splitext(os.path.basename(sys.argv[0]))[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Hook into the python logging.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync import logging;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logging.basicConfig(stream = PythonLoggingStream(),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync level = logging.DEBUG,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync format = '%(name)-12s %(levelname)-8s %(message)s');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Introspection and configuration.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def isLocal(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Is this a local reporter?"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def incVerbosity(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Increases the verbosity level."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iVerbose += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def incDebug(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Increases the debug level."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iDebug += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Generic logging.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def log(self, iLevel, sText, sCaller, sTsPrf):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Writes the specfied text to the log if iLevel is less or requal
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync to iVerbose.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = iLevel; _ = sText; _ = sCaller; _ = sTsPrf;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # XML output from the reporter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _xmlEscAttr(self, sValue):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Escapes an XML attribute value."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('&', '&');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('<', '&lt;');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('>', '&gt;');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #sValue = sValue.replace('\'', '&apos;');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('"', '&quot;');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('\n', '&#xA');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('\r', '&#xD');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return sValue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _xmlWrite(self, asText, fIndent = True):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """XML output function for the reporter."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = asText; _ = fIndent;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def xmlFlush(self, fRetry = False, fForce = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Flushes XML output if buffered."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = fRetry; _ = fForce;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # XML output from child.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def subXmlStart(self, oFileWrapper):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Called by the file wrapper when the first bytes are written to the test pipe."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = oFileWrapper;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def subXmlWrite(self, oFileWrapper, sRawXml, sCaller):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Called by the file wrapper write method for test pipes."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.log(0, 'raw xml%s: %s' % (oFileWrapper.sPrefix, sRawXml), sCaller, utils.getTimePrefix());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def subXmlEnd(self, oFileWrapper):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Called by the file wrapper __del__ method for test pipes."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = oFileWrapper;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # File output.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def addLogFile(self, oSrcFile, sSrcFilename, sAltName, sDescription, sKind, sCaller, sTsPrf):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Adds the file to the report.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True on success, False on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = oSrcFile; _ = sSrcFilename; _ = sAltName; _ = sDescription; _ = sKind; _ = sCaller; _ = sTsPrf;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Test reporting
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _testGetFullName(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Mangles the test names in atTest into a single name to make it easier
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync to spot where we are.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName = '';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for t in self.atTests:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sName != '':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName += ', ';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName += t[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return sName;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def testIncErrors(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Increates the error count."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cErrors += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.cErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def testSetTimedOut(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Sets time out indicator for the current test and increases the error counter."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fTimedOut = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cErrors += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def testStart(self, sName, sCaller):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Starts a new test, may be nested. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sTsPrf, sTsIso) = utils.getTimePrefixAndIsoTimestamp();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ '<Test timestamp="%s" name="%s">' % (sTsIso, self._xmlEscAttr(sName),), ]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.atTests.append((sName, self.cErrors, self.fTimedOut));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fTimedOut = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.log(1, '%-50s: TESTING' % (self._testGetFullName()), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def testValue(self, sName, sValue, sUnit, sCaller):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Reports a benchmark value or something simiarlly useful. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sTsPrf, sTsIso) = utils.getTimePrefixAndIsoTimestamp();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ '<Value timestamp="%s" name="%s" unit="%s" value="%s"/>'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (sTsIso, self._xmlEscAttr(sName), self._xmlEscAttr(sUnit), self._xmlEscAttr(sValue)), ]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.log(0, ' %-48s: %12s %s' % (sName, sValue, sUnit), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def testFailure(self, sDetails, sCaller):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Reports a failure. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sTsPrf, sTsIso) = utils.getTimePrefixAndIsoTimestamp();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cErrors = self.cErrors + 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ '<FailureDetails timestamp="%s" text="%s"/>' % (sTsIso, self._xmlEscAttr(sDetails),), ]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.log(0, sDetails, sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def testDone(self, fSkipped, sCaller):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Marks the current test as DONE, pops it and maks the next test on the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync stack current.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns (name, errors).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sTsPrf, sTsIso) = utils.getTimePrefixAndIsoTimestamp();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFullName = self._testGetFullName();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # safe pop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self.atTests) <= 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, 'testDone on empty test stack!', sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return ('internal error', 0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fTimedOut = self.fTimedOut;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName, cErrorsStart, self.fTimedOut = self.atTests.pop();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # log + xml.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cErrors = self.cErrors - cErrorsStart;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cErrors == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fSkipped is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ ' <Passed timestamp="%s"/>' % (sTsIso,), '</Test>' ],);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(1, '%-50s: PASSED' % (sFullName,), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ ' <Skipped timestamp="%s"/>' % (sTsIso,), '</Test>' ]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(1, '%-50s: SKIPPED' % (sFullName,), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif fTimedOut:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ ' <TimedOut timestamp="%s" errors="%d"/>' % (sTsIso, cErrors), '</Test>' ]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, '%-50s: TIMED-OUT - %d errors' % (sFullName, cErrors), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ ' <Failed timestamp="%s" errors="%d"/>' % (sTsIso, cErrors), '</Test>' ]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, '%-50s: FAILED - %d errors' % (sFullName, cErrors), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Flush buffers when reaching the last test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self.atTests) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.xmlFlush(fRetry = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (sName, cErrors);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def testErrorCount(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns the number of errors accumulated by the current test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cTests = len(self.atTests);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cTests <= 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.cErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.cErrors - self.atTests[cTests - 1][1];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def testCleanup(self, sCaller):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Closes all open test as failed.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True if no open tests, False if there were open tests.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self.atTests) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for _ in range(len(self.atTests)):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.testFailure('Test not closed by test drver', sCaller)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.testDone(False, sCaller);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass LocalReporter(ReporterBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Local reporter instance.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ReporterBase.__init__(self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oLogFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oXmlFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fXmlOk = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iSubXml = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iOtherFile = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fnGetIsoTimestamp = utils.getIsoTimestamp; # Hack to get a timestamp in __del__.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oStdErr = sys.stderr; # Hack for __del__ output.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Figure the main log directory.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync import user;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sDefLogDir = os.path.abspath(os.path.join(user.home, "VBoxTestLogs"));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sDefLogDir = os.path.abspath("VBoxTestLogs");
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sLogDir = os.path.abspath(os.environ.get('TESTBOX_REPORTER_LOG_DIR', self.sDefLogDir));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not os.path.isdir(sLogDir):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.makedirs(sLogDir, 0750);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sLogDir = self.sDefLogDir;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not os.path.isdir(sLogDir):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.makedirs(sLogDir, 0750);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Make a subdirectory for this test run.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTs = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H-%M-%S.log');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sLogDir = sLogDir = os.path.join(sLogDir, '%s-%s' % (sTs, self.sName));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.makedirs(self.sLogDir, 0750);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sLogDir = '%s-%s' % (self.sLogDir, os.getpid());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.makedirs(self.sLogDir, 0750);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Open the log file and write a header.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sLogName = os.path.join(self.sLogDir, 'testsuite.log');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTsIso = utils.getIsoTimestamp();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oLogFile = utils.openNoInherit(sLogName, "w");
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oLogFile.write(('Created log file at %s.\nRunning: %s' % (sTsIso, sys.argv)).encode('utf-8'));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Open the xml log file and write the mandatory introduction.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Note! This is done here and not in the base class because the remote
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # logger doesn't really need this. It doesn't need the outer
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # test wrapper either.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sXmlName = os.path.join(self.sLogDir, 'testsuite.xml');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oXmlFile = utils.openNoInherit(sXmlName, "w");
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ '<?xml version="1.0" encoding="UTF-8" ?>',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync '<Test timestamp="%s" name="%s">' % (sTsIso, self._xmlEscAttr(self.sName),), ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fIndent = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __del__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Ends and completes the log files."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try: sTsIso = self.fnGetIsoTimestamp();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTsIso = str(oXcpt);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.oLogFile is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oLogFile.write(('\nThe End %s\n' % (sTsIso,)).encode('utf-8'));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oLogFile.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except: pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oLogFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.oXmlFile is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._closeXml(sTsIso);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oXmlFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _closeXml(self, sTsIso):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Closes the XML file."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.oXmlFile is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # pop the test stack
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while len(self.atTests) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName, cErrorsStart, self.fTimedOut = self.atTests.pop();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ '<End timestamp="%s" errors="%d"/>' % (sTsIso, self.cErrors - cErrorsStart,),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync '</%s>' % (sName,), ]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # The outer one is not on the stack.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite([ ' <End timestamp="%s"/>' % (sTsIso,),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync '</Test>', ], fIndent = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oXmlFile.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oXmlFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _xmlWrite(self, asText, fIndent = True):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Writes to the XML file."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sText in asText:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fIndent:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sIndent = ''.ljust((len(self.atTests) + 1) * 2);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sText = sIndent + sText;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sText += '\n';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oXmlFile.write(sText.encode('utf-8'));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.fXmlOk:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync traceback.print_exc();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fXmlOk = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Overridden methods.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def isLocal(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Is this a local reporter?"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def log(self, iLevel, sText, sCaller, sTsPrf):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iLevel <= self.iVerbose:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # format it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.iDebug > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sLogText = '%s %30s: %s' % (sTsPrf, sCaller, sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sLogText = '%s %s' % (sTsPrf, sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # output it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sAscii = sLogText.encode('ascii', 'replace');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.iDebug == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync print >> self.oStdErr, '%s: %s' % (self.sName, sAscii)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync print >> self.oStdErr, '%s' % (sAscii)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sLogText += '\n';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oLogFile.write(sLogText.encode('utf-8'));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def addLogFile(self, oSrcFile, sSrcFilename, sAltName, sDescription, sKind, sCaller, sTsPrf):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Figure the destination filename.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iOtherFile = self.iOtherFile;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iOtherFile += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sDstFilename = os.path.join(self.sLogDir, 'other-%d-%s.log' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (iOtherFile, os.path.splitext(os.path.basename(sSrcFilename))[0]));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, 'Other log file: %s - %s (%s)' % (sDstFilename, sDescription, sSrcFilename), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Open the destination file and copy over the data.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDstFile = utils.openNoInherit(sDstFilename, 'w');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, 'error opening %s: %s' % (sDstFilename, oXcpt), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync abBuf = oSrcFile.read(65536);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, 'error reading %s: %s' % (sSrcFilename, oXcpt), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDstFile.write(abBuf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, 'error writing %s: %s' % (sDstFilename, oXcpt), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(abBuf) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDstFile.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Leave a mark in the XML log.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite('<LogFile timestamp="%s" filename="%s" source="%s" kind="%s" ok="%s">%s</LogFile>\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (utils.getIsoTimestamp(), self._xmlEscAttr(os.path.basename(sDstFilename)), self._xmlEscAttr(sSrcFilename), \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlEscAttr(sKind), fRc, self._xmlEscAttr(sDescription)) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = sAltName;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def subXmlStart(self, oFileWrapper):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Open a new file and just include it from the main XML.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iSubXml = self.iSubXml;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iSubXml += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sSubXmlName = os.path.join(self.sLogDir, 'sub-%d.xml' % (iSubXml,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFileWrapper.oSubXmlFile = utils.openNoInherit(sSubXmlName, "w");
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync errorXcpt('open(%s)' % oFileWrapper.oSubXmlName);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFileWrapper.oSubXmlFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlWrite('<Include timestamp="%s" filename="%s"/>\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (utils.getIsoTimestamp(), self._xmlEscAttr(os.path.basename(sSubXmlName))));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def subXmlWrite(self, oFileWrapper, sRawXml, sCaller):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oFileWrapper.oSubXmlFile is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFileWrapper.oSubXmlFile.write(sRawXml);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sCaller is None: pass; # pychecker - NOREF
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def subXmlEnd(self, oFileWrapper):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oFileWrapper.oSubXmlFile is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFileWrapper.oSubXmlFile.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFileWrapper.oSubXmlFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass RemoteReporter(ReporterBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reporter that talks to the test manager server.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The XML sync min time (seconds).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kcSecXmlFlushMin = 30;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The XML sync max time (seconds).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kcSecXmlFlushMax = 120;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The XML sync idle time before flushing (seconds).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kcSecXmlFlushIdle = 5;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The XML sync line count threshold.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kcLinesXmlFlush = 512;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The retry timeout.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kcSecTestManagerRetryTimeout = 120;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The request timeout.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kcSecTestManagerRequestTimeout = 30;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ReporterBase.__init__(self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sTestManagerUrl = os.environ.get('TESTBOX_MANAGER_URL');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sTestBoxUuid = os.environ.get('TESTBOX_UUID');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestBox = int(os.environ.get('TESTBOX_ID'));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSet = int(os.environ.get('TESTBOX_TEST_SET_ID'));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asXml = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._secTsXmlFlush = utils.timestampSecond();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._secTsXmlLast = self._secTsXmlFlush;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fXmlFlushing = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oOutput = sys.stdout; # Hack for __del__ output.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fFlushEachLine = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fDebugXml = 'TESTDRIVER_REPORTER_DEBUG_XML' in os.environ;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Prepare the TM connecting.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync import urlparse;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync import httplib;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync import urllib;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync from common import constants;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fnUrlEncode = urllib.urlencode;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fnUrlParseQs = urlparse.parse_qs;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oParsedTmUrl = urlparse.urlparse(self.sTestManagerUrl);
d647812a5f298e3b8764218362dbc27b25d30d1avboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sys.version_info[0] >= 3 \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or (sys.version_info[0] == 2 and sys.version_info[1] >= 6):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._oParsedTmUrl.scheme == 'https': # pylint: disable=E1101
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fnTmConnect = lambda: httplib.HTTPSConnection(self._oParsedTmUrl.hostname,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync timeout = self.kcSecTestManagerRequestTimeout);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fnTmConnect = lambda: httplib.HTTPConnection( self._oParsedTmUrl.hostname,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync timeout = self.kcSecTestManagerRequestTimeout);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._oParsedTmUrl.scheme == 'https': # pylint: disable=E1101
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fnTmConnect = lambda: httplib.HTTPSConnection(self._oParsedTmUrl.hostname);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fnTmConnect = lambda: httplib.HTTPConnection( self._oParsedTmUrl.hostname);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._dHttpHeader = \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync {
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'User-Agent': 'TestDriverReporter/%s.0 (%s, %s)' % (__version__, utils.getHostOs(), utils.getHostArch(),),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Accept': 'text/plain,application/x-www-form-urlencoded',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Accept-Encoding': 'identity',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Cache-Control': 'max-age=0',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #'Connection': 'keep-alive',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync };
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dParams = {
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.ALL_PARAM_TESTBOX_UUID: self.sTestBoxUuid,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.ALL_PARAM_TESTBOX_ID: self.idTestBox,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.RESULT_PARAM_TEST_SET_ID: self.idTestSet,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync };
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._sTmServerPath = '/%s/testboxdisp.py?%s' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % ( self._oParsedTmUrl.path.strip('/'), # pylint: disable=E1101
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync urllib.urlencode(dParams), );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __del__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Flush pending log messages?"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self._asXml) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlDoFlush(self._asXml, fRetry = True, fDtor = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _writeOutput(self, sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Does the actual writing and flushing. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync print >> self.oOutput, sText.encode('ascii', 'replace');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.fFlushEachLine: self.oOutput.flush();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Talking to TM.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _processTmStatusResponse(self, oConn, sOperation, fClose = True):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Processes HTTP reponse from the test manager.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True, False or None. None should be retried, the others not.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync May raise exception on HTTP issue (retry ok).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync import httplib;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync from common import constants;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Read the response and (optionally) close the connection.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oResponse = oConn.getresponse();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRspBody = oResponse.read();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except httplib.IncompleteRead, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('%s: %s: Warning: httplib.IncompleteRead: %s [expected %s, got %s]'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (utils.getTimePrefix(), sOperation, oXcpt, oXcpt.expected, len(oXcpt.partial),));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRspBody = oXcpt.partial;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fClose is True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try: oConn.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except: pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check the content type.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sContentType = oResponse.getheader('Content-Type');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sContentType is not None and sContentType == 'application/x-www-form-urlencoded; charset=utf-8':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Parse the body and check the RESULT parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = self._fnUrlParseQs(sRspBody, strict_parsing = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sResult = dResponse.get(constants.tbresp.ALL_PARAM_RESULT, None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if isinstance(sResult, list):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sResult = sResult[0] if len(sResult) == 1 else '%d results' % (len(sResult),);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sResult is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sResult == constants.tbresp.STATUS_ACK:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sResult == constants.tbresp.STATUS_NACK:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('%s: %s: Failed (%s). (dResponse=%s)'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (utils.getTimePrefix(), sOperation, sResult, dResponse,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('%s: %s: Failed - dResponse=%s' % (utils.getTimePrefix(), sOperation, dResponse,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('%s: %s: Unexpected Content-Type: %s' % (utils.getTimePrefix(), sOperation, sContentType,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('%s: %s: Body: %s' % (utils.getTimePrefix(), sOperation, sRspBody,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _doUploadFile(self, oSrcFile, sSrcFilename, sDescription, sKind, sMime):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Uploads the given file to the test manager. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Prepare header and url.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dHeader = dict(self._dHttpHeader);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dHeader['Content-Type'] = 'application/octet-stream';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('%s: _doUploadFile: sHeader=%s' % (utils.getTimePrefix(), dHeader,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSrcFile.seek(0, 2);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('%s: _doUploadFile: size=%d' % (utils.getTimePrefix(), oSrcFile.tell(),));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSrcFile.seek(0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync from common import constants;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sUrl = self._sTmServerPath + '&' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + self._fnUrlEncode({ constants.tbreq.UPLOAD_PARAM_NAME: os.path.basename(sSrcFilename),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.UPLOAD_PARAM_DESC: sDescription,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.UPLOAD_PARAM_KIND: sKind,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.UPLOAD_PARAM_MIME: sMime,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.ALL_PARAM_ACTION: constants.tbreq.UPLOAD,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync });
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Retry loop.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync secStart = utils.timestampSecond();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oConn = self._fnTmConnect();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oConn.request('POST', sUrl, oSrcFile.read(), dHeader);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = self._processTmStatusResponse(oConn, '_doUploadFile', fClose = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oConn.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fRc is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcpt('warning: exception during UPLOAD request');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if utils.timestampSecond() - secStart >= self.kcSecTestManagerRetryTimeout:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('%s: _doUploadFile: Timed out.' % (utils.getTimePrefix(),));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try: oSrcFile.seek(0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcpt();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('%s: _doUploadFile: Retrying...' % (utils.getTimePrefix(), ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync time.sleep(2);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _xmlDoFlush(self, asXml, fRetry = False, fDtor = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The code that does the actual talking to the server.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Used by both xmlFlush and __del__.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync secStart = utils.timestampSecond();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Post.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync from common import constants;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sPostBody = self._fnUrlEncode({constants.tbreq.XML_RESULT_PARAM_BODY: '\n'.join(asXml),});
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oConn = self._fnTmConnect();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oConn.request('POST',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._sTmServerPath + ('&%s=%s' % (constants.tbreq.ALL_PARAM_ACTION, constants.tbreq.XML_RESULTS)),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sPostBody,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._dHttpHeader);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = self._processTmStatusResponse(oConn, '_xmlDoFlush', fClose = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fRc is True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.fDebugXml:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('_xmlDoFlush:\n%s' % ('\n'.join(asXml),));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (None, False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fRc is False:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('_xmlDoFlush: Failed - we should abort the test, really.');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (None, True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not fDtor:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcpt('warning: exception during XML_RESULTS request');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput('warning: exception during XML_RESULTS request: %s' % (oXcpt,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fRetry is not True \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or utils.timestampSecond() - secStart >= self.kcSecTestManagerRetryTimeout:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync time.sleep(2);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (asXml, False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Overridden methods.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def isLocal(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def log(self, iLevel, sText, sCaller, sTsPrf):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iLevel <= self.iVerbose:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.iDebug > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sLogText = '%s %30s: %s' % (sTsPrf, sCaller, sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sLogText = '%s %s: %s' % (sTsPrf, self.sName, sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._writeOutput(sLogText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def addLogFile(self, oSrcFile, sSrcFilename, sAltName, sDescription, sKind, sCaller, sTsPrf):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sKind in [ 'text', 'log', ] or sKind.startswith('log/'):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, '*** Uploading "%s" - KIND: "%s" - DESC: "%s" ***'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (sSrcFilename, sKind, sDescription), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._doUploadFile(oSrcFile, sAltName, sDescription, sKind, 'text/plain');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sKind.startswith('screenshot/'):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, '*** Uploading "%s" - KIND: "%s" - DESC: "%s" ***'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (sSrcFilename, sKind, sDescription), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._doUploadFile(oSrcFile, sAltName, sDescription, sKind, 'image/png');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.log(0, '*** UNKNOWN FILE "%s" - KIND "%s" - DESC "%s" ***'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (sSrcFilename, sKind, sDescription), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def xmlFlush(self, fRetry = False, fForce = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Flushes the XML back log. Called with the lock held, may leave it
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while communicating with the server.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not self._fXmlFlushing:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asXml = self._asXml;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asXml = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(asXml) > 0 or fForce is True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fXmlFlushing = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (asXml, fIncErrors) = self._xmlDoFlush(asXml, fRetry = fRetry);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fIncErrors:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.testIncErrors();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fXmlFlushing = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if asXml is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._secTsXmlFlush = utils.timestampSecond();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asXml = asXml + self._asXml;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._secTsXmlFlush = utils.timestampSecond();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _xmlFlushIfNecessary(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Flushes the XML back log if necessary."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync tsNow = utils.timestampSecond();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cSecs = tsNow - self._secTsXmlFlush;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cSecsLast = tsNow - self._secTsXmlLast;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._secTsXmlLast = tsNow;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Absolute flush thresholds.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cSecs >= self.kcSecXmlFlushMax:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.xmlFlush();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self._asXml) >= self.kcLinesXmlFlush:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.xmlFlush();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Flush if idle long enough.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cSecs >= self.kcSecXmlFlushMin \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and cSecsLast >= self.kcSecXmlFlushIdle:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.xmlFlush();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _xmlWrite(self, asText, fIndent = True):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """XML output function for the reporter."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asXml += asText;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlFlushIfNecessary();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = fIndent; # No pretty printing, thank you.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def subXmlStart(self, oFileWrapper):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFileWrapper.sXmlBuffer = '';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def subXmlWrite(self, oFileWrapper, sRawXml, sCaller):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFileWrapper.sXmlBuffer += sRawXml;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = sCaller;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def subXmlEnd(self, oFileWrapper):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRawXml = oFileWrapper.sXmlBuffer;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo should validate the document here and maybe auto terminate things. Adding some hints to have the server do
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # this instead.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asXml += [ '<PushHint testdepth="%d"/>' % (len(self.atTests),),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRawXml,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync '<PopHint testdepth="%d"/>' % (len(self.atTests),),];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._xmlFlushIfNecessary();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Helpers
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef logXcptWorker(iLevel, fIncErrors, sPrefix="", sText=None, cFrames=1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log an exception, optionally with a preceeding message and more than one
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call frame.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fIncErrors:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.testIncErrors();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo skip all this if iLevel is too high!
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try get exception info.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTsPrf = utils.getTimePrefix();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oType, oValue, oTraceback = sys.exc_info();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oType = oValue = oTraceback = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oType is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try format the info
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCaller = utils.getCallerName(oTraceback.tb_frame);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sText is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = g_oReporter.log(iLevel, "%s%s" % (sPrefix, sText), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asInfo = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asInfo = asInfo + traceback.format_exception_only(oType, oValue);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cFrames is not None and cFrames <= 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asInfo = asInfo + traceback.format_tb(oTraceback, 1);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asInfo.append('Traceback:')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asInfo = asInfo + traceback.format_tb(oTraceback, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asInfo.append('Stack:')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asInfo = asInfo + traceback.format_stack(oTraceback.tb_frame.f_back, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(0, 'internal-error: Hit exception #2! %s' % (traceback.format_exc()), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(asInfo) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Do the logging.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sItem in asInfo:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asLines = sItem.splitlines();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sLine in asLines:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = g_oReporter.log(iLevel, '%s%s' % (sPrefix, sLine), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(iLevel, 'No exception info...', sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = -3;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(0, 'internal-error: Hit exception! %s' % (traceback.format_exc()), None, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = -2;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(0, 'internal-error: No exception! %s'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (utils.getCallerName(iFrame=3)), utils.getCallerName(iFrame=3), sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = -1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return rc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# The public Classes
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass FileWrapper(object):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ File like class for TXS EXEC and similar. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self, sPrefix):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sPrefix = sPrefix;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def read(self, cb):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """file.read"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = cb;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return "";
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def write(self, sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """file.write"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if isinstance(sText, array.array):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sText = sText.tostring();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTsPrf = utils.getTimePrefix();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCaller = utils.getCallerName();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asLines = sText.splitlines();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sLine in asLines:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(0, '%s: %s' % (self.sPrefix, sLine), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync traceback.print_exc();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass FileWrapperTestPipe(object):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ File like class for the test pipe (TXS EXEC and similar). """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sPrefix = '';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fStarted = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fClosed = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __del__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def close(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ file.close """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.fStarted is True and self.fClosed is False:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fClosed = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try: g_oReporter.subXmlEnd(self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try: traceback.print_exc();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except: pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def read(self, cb = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """file.read"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = cb;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return "";
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def write(self, sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """file.write"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # lazy start.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.fStarted is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.subXmlStart(self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync traceback.print_exc();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fStarted = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if isinstance(sText, array.array):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sText = sText.tostring();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.subXmlWrite(self, sText, utils.getCallerName());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync traceback.print_exc();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# The public APIs.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef log(sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Writes the specfied text to the log."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = g_oReporter.log(1, sText, utils.getCallerName(), utils.getTimePrefix());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = -1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return rc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef logXcpt(sText=None, cFrames=1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log an exception, optionally with a preceeding message and more than one
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call frame.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return logXcptWorker(1, False, "", sText, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef log2(sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Log level 2: Writes the specfied text to the log."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = g_oReporter.log(2, sText, utils.getCallerName(), utils.getTimePrefix());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = -1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return rc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef log2Xcpt(sText=None, cFrames=1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log level 2: Log an exception, optionally with a preceeding message and
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync more than one call frame.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return logXcptWorker(2, False, "", sText, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef maybeErr(fIsError, sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Maybe error or maybe normal log entry. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fIsError is True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return error(sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return log(sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef maybeErrXcpt(fIsError, sText=None, cFrames=1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Maybe error or maybe normal log exception entry. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fIsError is True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return errorXcpt(sText, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return logXcpt(sText, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef maybeLog(fIsNotError, sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Maybe error or maybe normal log entry. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fIsNotError is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return error(sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return log(sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef maybeLogXcpt(fIsNotError, sText=None, cFrames=1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Maybe error or maybe normal log exception entry. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fIsNotError is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return errorXcpt(sText, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return logXcpt(sText, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef error(sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Writes the specfied error message to the log.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This will add an error to the current test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Always returns False for the convenience of methods returning boolean
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync success indicators.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.testIncErrors();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(0, 'error: %s' % (sText), utils.getCallerName(), utils.getTimePrefix());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef errorXcpt(sText=None, cFrames=1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log an error caused by an exception. If sText is given, it will preceed
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync the exception information. cFrames can be used to display more stack.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This will add an error to the current test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Always returns False for the convenience of methods returning boolean
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync success indicators.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcptWorker(0, True, "error: ", sText, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef errorTimeout(sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Flags the current test as having timed out and writes the specified message to the log.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This will add an error to the current test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Always returns False for the convenience of methods returning boolean
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync success indicators.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.testSetTimedOut();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(0, 'timeout-error: %s' % (sText), utils.getCallerName(), utils.getTimePrefix());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef fatal(sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Writes a fatal error to the log.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This will add an error to the current test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Always returns False for the convenience of methods returning boolean
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync success indicators.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.testIncErrors();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(0, 'fatal error: %s' % (sText), utils.getCallerName(), utils.getTimePrefix());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef fatalXcpt(sText=None, cFrames=1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Log a fatal error caused by an exception. If sText is given, it will
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync preceed the exception information. cFrames can be used to display more
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync stack.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This will add an error to the current test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Always returns False for the convenience of methods returning boolean
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync success indicators.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcptWorker(1, True, "fatal error: ", sText, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef addLogFile(sFilename, sKind, sDescription = '', sAltName = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Adds the specified log file to the report if the file exists.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The sDescription is a free form description of the log file.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The sKind parameter is for adding some machine parsable hint what kind of
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync log file this really is.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True on success, False on failure (no ENOENT errors are logged).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTsPrf = utils.getTimePrefix();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCaller = utils.getCallerName();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sAltName is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sAltName = sFilename;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSrcFile = utils.openNoInherit(sFilename, 'rb');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except IOError, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oXcpt.errno != errno.ENOENT:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcpt('addLogFile(%s,%s,%s)' % (sFilename, sDescription, sKind));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcpt('addLogFile(%s,%s,%s) IOError' % (sFilename, sDescription, sKind));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcpt('addLogFile(%s,%s,%s)' % (sFilename, sDescription, sKind));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = g_oReporter.addLogFile(oSrcFile, sFilename, sAltName, sDescription, sKind, sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSrcFile.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef isLocal():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Is this a local reporter?"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return g_oReporter.isLocal()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef incVerbosity():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Increases the verbosity level."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return g_oReporter.incVerbosity()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef incDebug():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Increases the debug level."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return g_oReporter.incDebug()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef getErrorCount():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get the current error count for the entire test run.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cErrors = g_oReporter.cErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return cErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Test reporting, a bit similar to RTTestI*.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef testStart(sName):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Starts a new test (pushes it).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = g_oReporter.testStart(sName, utils.getCallerName());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return rc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef testValue(sName, sValue, sUnit):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reports a benchmark value or something simiarlly useful.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = g_oReporter.testValue(sName, str(sValue), sUnit, utils.getCallerName());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return rc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef testFailure(sDetails):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reports a failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync We count these calls and testDone will use them to report PASSED or FAILED.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns False so that a return False line can be saved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.testFailure(sDetails, utils.getCallerName());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef testFailureXcpt(sDetails = ''):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reports a failure with exception.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync We count these calls and testDone will use them to report PASSED or FAILED.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns False so that a return False line can be saved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Extract exception info.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oType, oValue, oTraceback = sys.exc_info();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oType = oValue, oTraceback = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oType is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCaller = utils.getCallerName(oTraceback.tb_frame);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sXcpt = ' '.join(traceback.format_exception_only(oType, oValue));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCaller = utils.getCallerName();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sXcpt = 'No exception at %s' % (sCaller,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Use testFailure to do the work.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sDetails == '':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.testFailure('Exception: %s' % (sXcpt,), sCaller);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.testFailure('%s: %s' % (sDetails, sXcpt), sCaller);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef testDone(fSkipped = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Completes the current test (pops it), logging PASSED / FAILURE.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns a tuple with the name of the test and its error count.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync rc = g_oReporter.testDone(fSkipped, utils.getCallerName());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return rc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef testErrorCount():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets the error count of the current test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns the number of errors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cErrors = g_oReporter.testErrorCount();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return cErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef testCleanup():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Closes all open tests with a generic error condition.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True if no open tests, False if something had to be closed with failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = g_oReporter.testCleanup(utils.getCallerName());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.xmlFlush(fRetry = False, fForce = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Sub XML stuff.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef addSubXmlFile(sFilename):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Adds a sub-xml result file to the party.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSrcFile = utils.openNoInherit(sFilename, 'r');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except IOError, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oXcpt.errno != errno.ENOENT:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcpt('addSubXmlFile(%s)' % (sFilename,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcpt('addSubXmlFile(%s)' % (sFilename,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oWrapper = FileWrapperTestPipe()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oWrapper.write(oSrcFile.read());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oWrapper.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync logXcpt('addSubXmlFile(%s)' % (sFilename,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSrcFile.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Other useful debugging tools.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef logAllStacks(cFrames = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Logs the stacks of all python threads.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTsPrf = utils.getTimePrefix();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCaller = utils.getCallerName();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cThread = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for idThread, oStack in sys._current_frames().items(): # >=2.5, a bit ugly - pylint: disable=W0212
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cThread > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(1, '', sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(1, 'Thread %s (%#x)' % (idThread, idThread), sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asInfo = traceback.format_stack(oStack, cFrames);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(1, ' Stack formatting failed w/ exception', sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sInfo in asInfo:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asLines = sInfo.splitlines();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sLine in asLines:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter.log(1, sLine, sCaller, sTsPrf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cThread += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef checkTestManagerConnection():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Checks the connection to the test manager.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True if the connection is fine, False if not, None if not remote
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Note! This as the sideeffect of flushing XML.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.acquire();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = g_oReporter.xmlFlush(fRetry = False, fForce = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oLock.release();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef flushall():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Flushes all output streams, both standard and logger related.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try: sys.stdout.flush();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except: pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try: sys.stderr.flush();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except: pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Note! Current no logger specific streams to flush.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Module initialization.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef _InitReporterModule():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Instantiate the test reporter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync global g_oReporter, g_sReporterName
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_sReporterName = os.getenv("TESTBOX_REPORTER", "local");
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if g_sReporterName == "local":
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter = LocalReporter();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif g_sReporterName == "remote":
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync g_oReporter = RemoteReporter();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync print >> sys.stderr, os.path.basename(__file__) + ": Unknown TESTBOX_REPORTER value: '" + g_sReporterName + "'";
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise Exception("Unknown TESTBOX_REPORTER value '" + g_sReporterName + "'");
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncif __name__ != "checker": # pychecker avoidance.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _InitReporterModule();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync