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