testresults.py revision cf22150eaeeb72431bf1cf65c309a431454fb22b
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync# -*- coding: utf-8 -*-
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync# pylint: disable=C0302
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync## @todo Rename this file to testresult.py!
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncTest Manager - Fetch test results.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncCopyright (C) 2012-2014 Oracle Corporation
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncThis file is part of VirtualBox Open Source Edition (OSE), as
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncavailable from http://www.virtualbox.org. This file is free software;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncyou can redistribute it and/or modify it under the terms of the GNU
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncGeneral Public License (GPL) as published by the Free Software
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncFoundation, in version 2 as it comes in the "COPYING" file of the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncVirtualBox OSE distribution. VirtualBox OSE is distributed in the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsynchope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncThe contents of this file may alternatively be used under the terms
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncof the Common Development and Distribution License Version 1.0
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync(CDDL) only, as it comes in the "COPYING.CDDL" file of the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncVirtualBox OSE distribution, in which case the provisions of the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncCDDL are applicable instead of those of the GPL.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncYou may elect to license modified versions of this file under the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncterms and conditions of either the GPL or the CDDL or both.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync# Standard python imports.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync# Validation Kit imports.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncfrom testmanager.core.base import ModelDataBase, ModelLogicBase, ModelDataBaseTestCase, TMExceptionBase, TMTooManyRows;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncfrom testmanager.core.testgroup import TestGroupData
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncfrom testmanager.core.schedgroup import SchedGroupData
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncfrom testmanager.core.systemlog import SystemLogData, SystemLogLogic;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync Test case execution result data
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ## @name TestStatus_T
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ## List of relatively harmless (to testgroup/case) statuses.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync kasHarmlessTestStatuses = [ ksTestStatus_Skipped, ksTestStatus_BadTestBox, ksTestStatus_Aborted, ];
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ## List of bad statuses.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync kasBadTestStatuses = [ ksTestStatus_Failure, ksTestStatus_TimedOut, ksTestStatus_Rebooted, ];
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ksParam_idTestResult = 'TestResultData_idTestResult';
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ksParam_idTestResultParent = 'TestResultData_idTestResultParent';
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ksParam_iNestingDepth = 'TestResultData_iNestingDepth';
if aoRow is None:
return self;
return self;
if aoRow is None:
return self;
return self;
if aoRow is None:
return self;
return self;
if aoRow is None:
return self;
return self;
return self;
return True;
return False;
if aoRow is None:
return self
'TestResults LEFT OUTER JOIN TestResults as MsgTab ON TestResults.idTestResult=MsgTab.idTestResultParent\n' \
cMonthsMourningPeriod = 2; # Stop reminding everyone about testboxes after 2 months. (May also speed up the query.)
if tsNow is None:
% ( sTsNow,
return sRet
def _getSqlQueryForGroupSearch(self, sWhat, tsNow, sInterval, enmResultsGroupingType, iResultsGroupingValue, fOnlyFailures):
if enmResultsGroupingType is None:
if iResultsGroupingValue is not None:
if fOnlyFailures:
return sQuery
def fetchResultsForListing(self, iStart, cMaxRows, tsNow, sInterval, enmResultsGroupingType, iResultsGroupingValue,
sSqlQuery = self._getSqlQueryForGroupSearch(sWhat, tsNow, sInterval, enmResultsGroupingType, iResultsGroupingValue,
aoRows = [];
return aoRows
def getEntriesCount(self, tsNow, sInterval, enmResultsGroupingType, iResultsGroupingValue, fOnlyFailures):
aoRet = []
return aoRet
aoRet = []
return aoRet
asIdGenTestBoxes = [];
aoRet = []
return aoRet
self._oDb.execute('SELECT DISTINCT TestCases.idTestCase, TestCases.idGenTestCase, TestSets.tsConfig\n'
aoRet = []
return aoRet
aoRet = []
return aoRet
(idTestResult,))
raise TMExceptionBase('Found more than one test result with the same credentials. Database structure is corrupted.')
except IndexError:
, ( idTestSet, ));
if cMaxDepth is not None:
if oParent is None:
if fHasValues:
if fHasMsgs:
if fHasFiles:
return True;
self._oDb.dprint('** _inhumeTestResults: idTestSet=%d\n%s' % (idTestSet, self._stringifyStack(aoStack),));
self._completeTestResults(oTestResult, None, TestResultData.ksTestStatus_Failure, oTestResult.cErrors);
, ( idTestSet, ));
, (sString,));
, (sString,));
if fCommit:
return sRet;
, ( idTestSet, ));
aoStack = [];
return aoStack;
def _newTestResult(self, idTestResultParent, idTestSet, iNestingDepth, tsCreated, sName, dCounts, fCommit = False):
assert idTestResultParent is not None;
, ( idTestSet,));
, ( idTestResultParent,));
return oData;
def _newTestValue(self, idTestResult, idTestSet, sName, lValue, sUnit, dCounts, tsCreated = None, fCommit = False):
, ( idTestSet,));
, ( idTestResult,));
if tsCreated is None:
return True;
if dCounts is not None:
, ( idTestResult,));
raise TestResultHangingOffence('Failure details message is too long: %d chars - "%s"' % (len(sText), sText));
if tsCreated is None:
return True;
if tsDone is None:
return True;
(dAttribs['timestamp'], sError) = ModelDataBase.validateTs(dAttribs['timestamp'], fAllowNull = False);
if sError is not None:
dElementAttribs = \
if fClosed:
sError = None;
dAttribs = {};
if sError is None:
aoStack.insert(0, self._newTestResult(idTestResultParent = aoStack[0].idTestResult, idTestSet = idTestSet,
self._newTestValue(idTestResult = aoStack[0].idTestResult, idTestSet = idTestSet, tsCreated = dAttribs['timestamp'],
self._completeTestResults(aoStack[0], tsDone = dAttribs['timestamp'], cErrors = int(dAttribs['errors']),
self._completeTestResults(aoStack[0], tsDone = dAttribs['timestamp'], cErrors = int(dAttribs['errors']),
dCounts = {};
aaiHints = [];
sError = None;
elif fExpectCloseTest:
if sError is not None:
if sError is not None:
% ( idTestSet,
sError, ),