cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# -*- coding: utf-8 -*-
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# $Id$
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# pylint: disable=C0302
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync## @todo Rename this file to testresult.py!
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTest Manager - Fetch test results.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__copyright__ = \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCopyright (C) 2012-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThis file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncavailable from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncyou can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGeneral Public License (GPL) as published by the Free Software
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncFoundation, in version 2 as it comes in the "COPYING" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution. VirtualBox OSE is distributed in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsynchope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThe contents of this file may alternatively be used under the terms
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncof the Common Development and Distribution License Version 1.0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync(CDDL) only, as it comes in the "COPYING.CDDL" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution, in which case the provisions of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCDDL are applicable instead of those of the GPL.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncYou may elect to license modified versions of this file under the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncterms and conditions of either the GPL or the CDDL or both.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__version__ = "$Revision$"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Standard python imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport unittest;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Validation Kit imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom common import constants;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager import config;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.base import ModelDataBase, ModelLogicBase, ModelDataBaseTestCase, TMExceptionBase, TMTooManyRows;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testgroup import TestGroupData
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.build import BuildDataEx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testbox import TestBoxData
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testcase import TestCaseData
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.schedgroup import SchedGroupData
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.systemlog import SystemLogData, SystemLogLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultData(ModelDataBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Test case execution result data
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @name TestStatus_T
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # @{
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Running = 'running';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Success = 'success';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Skipped = 'skipped';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_BadTestBox = 'bad-testbox';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Aborted = 'aborted';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Failure = 'failure';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_TimedOut = 'timed-out';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Rebooted = 'rebooted';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## List of relatively harmless (to testgroup/case) statuses.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasHarmlessTestStatuses = [ ksTestStatus_Skipped, ksTestStatus_BadTestBox, ksTestStatus_Aborted, ];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## List of bad statuses.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasBadTestStatuses = [ ksTestStatus_Failure, ksTestStatus_TimedOut, ksTestStatus_Rebooted, ];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksIdAttr = 'idTestResult';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestResult = 'TestResultData_idTestResult';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestResultParent = 'TestResultData_idTestResultParent';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestSet = 'TestResultData_idTestSet';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsCreated = 'TestResultData_tsCreated';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsElapsed = 'TestResultData_tsElapsed';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idStrName = 'TestResultData_idStrName';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_cErrors = 'TestResultData_cErrors';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_enmStatus = 'TestResultData_enmStatus';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_iNestingDepth = 'TestResultData_iNestingDepth';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasValidValues_enmStatus = [
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Running,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Success,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Skipped,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_BadTestBox,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Aborted,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Failure,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_TimedOut,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksTestStatus_Rebooted
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ModelDataBase.__init__(self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResultParent = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSet = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsElapsed = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrName = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cErrors = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.enmStatus = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iNestingDepth = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitialize from a SELECT * FROM TestResults.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Return self. Raises exception if no row.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Test result record not found.')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = aoRow[0]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResultParent = aoRow[1]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSet = aoRow[2]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = aoRow[3]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsElapsed = aoRow[4]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrName = aoRow[5]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cErrors = aoRow[6]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.enmStatus = aoRow[7]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iNestingDepth = aoRow[8]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def isFailure(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Check if it's a real failure. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.enmStatus in self.kasBadTestStatuses;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultDataEx(TestResultData):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Extended test result data class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This is intended for use as a node in a result tree. This is not intended
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for serialization to parameters or vice versa. Use TestResultLogic to
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync construct the tree.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestResultData.__init__(self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sName = None; # idStrName resolved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oParent = None; # idTestResultParent within the tree.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoChildren = []; # TestResultDataEx;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoValues = []; # TestResultValue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoMsgs = []; # TestResultMsg;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoFiles = []; # TestResultFile;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Initialize from a query like this:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync SELECT TestResults.*, TestResultStrTab.sValue
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync FROM TestResults, TestResultStrTab
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync WHERE TestResultStrTab.idStr = TestResults.idStrName
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Note! The caller is expected to fetch children, values, failure
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync details, and files.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sName = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oParent = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoChildren = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoValues = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoMsgs = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoFiles = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestResultData.initFromDbRow(self, aoRow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sName = aoRow[9];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultValueData(ModelDataBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Test result value data.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksIdAttr = 'idTestResultValue';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestResultValue = 'TestResultValue_idTestResultValue';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestResult = 'TestResultValue_idTestResult';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestSet = 'TestResultValue_idTestSet';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsCreated = 'TestResultValue_tsCreated';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idStrName = 'TestResultValue_idStrName';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_lValue = 'TestResultValue_lValue';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_iUnit = 'TestResultValue_iUnit';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ModelDataBase.__init__(self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResultValue = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSet = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrName = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.lValue = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iUnit = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitialize from a SELECT * FROM TestResultValues.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Return self. Raises exception if no row.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Test result value record not found.')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResultValue = aoRow[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = aoRow[1];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSet = aoRow[2];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = aoRow[3];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrName = aoRow[4];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.lValue = aoRow[5];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iUnit = aoRow[6];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultValueDataEx(TestResultValueData):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Extends TestResultValue by resolving the value name and unit string.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestResultValueData.__init__(self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sName = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sUnit = '';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitialize from a query like this:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync SELECT TestResultValues.*, TestResultStrTab.sValue
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync FROM TestResultValues, TestResultStrTab
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync WHERE TestResultStrTab.idStr = TestResultValues.idStrName
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Return self. Raises exception if no row.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestResultValueData.initFromDbRow(self, aoRow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sName = aoRow[7];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.iUnit < len(constants.valueunit.g_asNames):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sUnit = constants.valueunit.g_asNames[self.iUnit];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sUnit = '<%d>' % (self.iUnit,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultMsgData(ModelDataBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Test result message data.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksIdAttr = 'idTestResultMsg';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestResultMsg = 'TestResultValue_idTestResultMsg';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestResult = 'TestResultValue_idTestResult';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsCreated = 'TestResultValue_tsCreated';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idStrMsg = 'TestResultValue_idStrMsg';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_enmLevel = 'TestResultValue_enmLevel';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ModelDataBase.__init__(self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResultMsg = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrMsg = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.enmLevel = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitialize from a SELECT * FROM TestResultMsgs.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Return self. Raises exception if no row.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Test result value record not found.')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResultMsg = aoRow[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = aoRow[1];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = aoRow[2];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrMsg = aoRow[3];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.enmLevel = aoRow[4];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultMsgDataEx(TestResultMsgData):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Extends TestResultMsg by resolving the message string.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestResultMsgData.__init__(self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sMsg = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitialize from a query like this:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync SELECT TestResultMsg.*, TestResultStrTab.sValue
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync FROM TestResultMsg, TestResultStrTab
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync WHERE TestResultStrTab.idStr = TestResultMsgs.idStrName
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Return self. Raises exception if no row.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestResultMsgData.initFromDbRow(self, aoRow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sMsg = aoRow[5];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultFileData(ModelDataBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Test result message data.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksIdAttr = 'idTestResultFile';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestResultFile = 'TestResultFile_idTestResultFile';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestResult = 'TestResultFile_idTestResult';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsCreated = 'TestResultFile_tsCreated';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idStrFile = 'TestResultFile_idStrFile';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idStrDescription = 'TestResultFile_idStrDescription';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idStrKind = 'TestResultFile_idStrKind';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idStrMime = 'TestResultFile_idStrMime';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ModelDataBase.__init__(self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResultFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrDescription = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrKind = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrMime = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitialize from a SELECT * FROM TestResultFiles.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Return self. Raises exception if no row.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Test result file record not found.')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResultFile = aoRow[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = aoRow[1];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = aoRow[2];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrFile = aoRow[3];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrDescription = aoRow[4];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrKind = aoRow[5];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrMime = aoRow[6];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultFileDataEx(TestResultFileData):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Extends TestResultFile by resolving the strings.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestResultFileData.__init__(self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sDescription = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sKind = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sMime = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitialize from a query like this:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync SELECT TestResultFiles.*,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync StrTabFile.sValue AS sFile,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync StrTabDesc.sValue AS sDescription
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync StrTabKind.sValue AS sKind,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync StrTabMime.sValue AS sMime,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync FROM ...
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Return self. Raises exception if no row.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestResultFileData.initFromDbRow(self, aoRow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sFile = aoRow[7];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sDescription = aoRow[8];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sKind = aoRow[9];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sMime = aoRow[10];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFakeMainLog(self, oTestSet):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitializes to represent the main.log object (not in DB).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns self.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResultFile = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = oTestSet.idTestResult;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = oTestSet.tsCreated;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrFile = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrDescription = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrKind = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idStrMime = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sFile = 'main.log';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sDescription = '';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sKind = 'log/main';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sMime = 'text/plain';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def isProbablyUtf8Encoded(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Checks if the file is likely to be UTF-8 encoded.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.sMime in [ 'text/plain', 'text/html' ]:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getMimeWithEncoding(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets the MIME type with encoding if likely to be UTF-8.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.isProbablyUtf8Encoded():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return '%s; charset=utf-8' % (self.sMime,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.sMime;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultListingData(ModelDataBase): # pylint: disable=R0902
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Test case result data representation for table listing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Initialize"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ModelDataBase.__init__(self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSet = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuildCategory = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sProduct = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sRepository = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sBranch = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sType = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuild = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sVersion = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iRevision = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sOs = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sOsVersion = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sArch = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sCpuVendor = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sCpuName = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cCpus = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fCpuHwVirt = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fCpuNestedPaging = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fCpu64BitGuest = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestBox = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sTestBoxName = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsElapsed = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.enmStatus = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cErrors = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestCase = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sTestCaseName = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sBaseCmd = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sArgs = None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuildTestSuite = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iRevisionTestSuite = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitialize from a database query.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Return self. Raises exception if no row.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Test result record not found.')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSet = aoRow[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuildCategory = aoRow[1];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sProduct = aoRow[2];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sRepository = aoRow[3];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sBranch = aoRow[4];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sType = aoRow[5];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuild = aoRow[6];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sVersion = aoRow[7];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iRevision = aoRow[8];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sOs = aoRow[9];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sOsVersion = aoRow[10];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sArch = aoRow[11];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sCpuVendor = aoRow[12];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sCpuName = aoRow[13];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cCpus = aoRow[14];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fCpuHwVirt = aoRow[15];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fCpuNestedPaging = aoRow[16];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fCpu64BitGuest = aoRow[17];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestBox = aoRow[18];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sTestBoxName = aoRow[19];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = aoRow[20];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsElapsed = aoRow[21];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.enmStatus = aoRow[22];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cErrors = aoRow[23];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestCase = aoRow[24];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sTestCaseName = aoRow[25];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sBaseCmd = aoRow[26];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sArgs = aoRow[27];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuildTestSuite = aoRow[28];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iRevisionTestSuite = aoRow[29];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultHangingOffence(TMExceptionBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Hanging offence committed by test case."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultLogic(ModelLogicBase): # pylint: disable=R0903
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Results grouped by scheduling group.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Result grinding for displaying in the WUI.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeNone = 'ResultsGroupingTypeNone'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeTestGroup = 'ResultsGroupingTypeTestGroup'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeBuildRev = 'ResultsGroupingTypeBuild'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeTestBox = 'ResultsGroupingTypeTestBox'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeTestCase = 'ResultsGroupingTypeTestCase'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeSchedGroup = 'ResultsGroupingTypeSchedGroup'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
044c12a522da4180f67ab7a51a66446647a1f15dvboxsync ksBaseTables = 'BuildCategories, Builds, TestBoxes, TestResults, TestCases, TestCaseArgs,\n' \
044c12a522da4180f67ab7a51a66446647a1f15dvboxsync + ' TestSets LEFT OUTER JOIN Builds AS TestSuiteBits\n' \
044c12a522da4180f67ab7a51a66446647a1f15dvboxsync ' ON TestSets.idBuildTestSuite = TestSuiteBits.idBuild\n';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBasePreCondition = 'TestSets.idTestSet = TestResults.idTestSet\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + ' AND TestResults.idTestResultParent is NULL\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + ' AND TestSets.idBuild = Builds.idBuild\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + ' AND Builds.tsExpire > TestSets.tsCreated\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + ' AND Builds.tsEffective <= TestSets.tsCreated\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + ' AND Builds.idBuildCategory = BuildCategories.idBuildCategory\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + ' AND TestSets.idGenTestBox = TestBoxes.idGenTestBox\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + ' AND TestSets.idGenTestCase = TestCases.idGenTestCase\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + ' AND TestSets.idGenTestCaseArgs = TestCaseArgs.idGenTestCaseArgs\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kdResultGroupingMap = {
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeNone: (ksBaseTables,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBasePreCondition,),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeTestGroup: (ksBaseTables,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBasePreCondition + ' AND TestSets.idTestGroup',),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeBuildRev: (ksBaseTables,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBasePreCondition + ' AND Builds.iRevision',),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeTestBox: (ksBaseTables,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBasePreCondition + ' AND TestSets.idTestBox',),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeTestCase: (ksBaseTables,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBasePreCondition + ' AND TestSets.idTestCase',),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksResultsGroupingTypeSchedGroup: (ksBaseTables,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBasePreCondition + ' AND TestBoxes.idSchedGroup',),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync }
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _getTimePeriodQueryPart(self, tsNow, sInterval):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get part of SQL query responsible for SELECT data within
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync specified period of time.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert sInterval is not None; # too many rows.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cMonthsMourningPeriod = 2; # Stop reminding everyone about testboxes after 2 months. (May also speed up the query.)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if tsNow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRet = '(TestSets.tsDone IS NULL OR TestSets.tsDone >= (CURRENT_TIMESTAMP - \'%s\'::interval))\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestSets.tsCreated >= (CURRENT_TIMESTAMP - \'%s\'::interval - \'%u months\'::interval)\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (sInterval, sInterval, cMonthsMourningPeriod);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTsNow = '\'%s\'::TIMESTAMP' % (tsNow,); # It's actually a string already. duh.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRet = 'TestSets.tsCreated <= %s\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestSets.tsCreated >= (%s - \'%s\'::interval - \'%u months\'::interval)\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND (TestSets.tsDone IS NULL OR TestSets.tsDone >= (%s - \'%s\'::interval))\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % ( sTsNow,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTsNow, sInterval, cMonthsMourningPeriod,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTsNow, sInterval );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return sRet
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _getSqlQueryForGroupSearch(self, sWhat, tsNow, sInterval, enmResultsGroupingType, iResultsGroupingValue, fOnlyFailures):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns an SQL query that limits SELECT result
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync in order to satisfy @param enmResultsGroupingType.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if enmResultsGroupingType is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Unknown grouping type')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if enmResultsGroupingType not in self.kdResultGroupingMap:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Unknown grouping type')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Get SQL query parameters
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTables, sCondition = self.kdResultGroupingMap[enmResultsGroupingType]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Extend SQL query with time period limitation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTimePeriodQuery = self._getTimePeriodQueryPart(tsNow, sInterval)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iResultsGroupingValue is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCondition += ' = %d' % iResultsGroupingValue + '\n';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCondition += ' AND ' + sTimePeriodQuery
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Extend the condition with test status limitations if requested.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fOnlyFailures:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCondition += '\n AND TestSets.enmStatus != \'success\'::TestStatus_T' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync '\n AND TestSets.enmStatus != \'running\'::TestStatus_T';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Assemble the query.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sQuery = 'SELECT DISTINCT %s\n' % sWhat
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sQuery += 'FROM %s\n' % sTables
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sQuery += 'WHERE %s\n' % sCondition
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return sQuery
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def fetchResultsForListing(self, iStart, cMaxRows, tsNow, sInterval, enmResultsGroupingType, iResultsGroupingValue,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fOnlyFailures):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Fetches TestResults table content.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync If @param enmResultsGroupingType and @param iResultsGroupingValue
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync are not None, then resulting (returned) list contains only records
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync that match specified @param enmResultsGroupingType.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync If @param enmResultsGroupingType is None, then
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @param iResultsGroupingValue is ignored.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns an array (list) of TestResultData items, empty list if none.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception on error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sWhat = 'TestSets.idTestSet,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' BuildCategories.idBuildCategory,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' BuildCategories.sProduct,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' BuildCategories.sRepository,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' BuildCategories.sBranch,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' BuildCategories.sType,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' Builds.idBuild,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' Builds.sVersion,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' Builds.iRevision,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.sOs,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.sOsVersion,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.sCpuArch,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.sCpuVendor,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.sCpuName,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.cCpus,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.fCpuHwVirt,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.fCpuNestedPaging,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.fCpu64BitGuest,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.idTestBox,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestBoxes.sName,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResults.tsCreated,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' COALESCE(TestResults.tsElapsed, CURRENT_TIMESTAMP - TestResults.tsCreated),\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestSets.enmStatus,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResults.cErrors,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestCases.idTestCase,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestCases.sName,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestCases.sBaseCmd,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestCaseArgs.sArgs,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestSuiteBits.idBuild AS idBuildTestSuite,\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestSuiteBits.iRevision AS iRevisionTestSuite,\n' \
044c12a522da4180f67ab7a51a66446647a1f15dvboxsync ' (TestSets.tsDone IS NULL) SortRunningFirst' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sSqlQuery = self._getSqlQueryForGroupSearch(sWhat, tsNow, sInterval, enmResultsGroupingType, iResultsGroupingValue,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fOnlyFailures);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sSqlQuery += 'ORDER BY SortRunningFirst DESC, TestSets.idTestSet DESC\n';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sSqlQuery += 'LIMIT %s OFFSET %s\n' % (cMaxRows, iStart,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute(sSqlQuery);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRows = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRows.append(TestResultListingData().initFromDbRow(aoRow))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoRows
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getEntriesCount(self, tsNow, sInterval, enmResultsGroupingType, iResultsGroupingValue, fOnlyFailures):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get number of table records.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync If @param enmResultsGroupingType and @param iResultsGroupingValue
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync are not None, then we count only only those records
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync that match specified @param enmResultsGroupingType.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync If @param enmResultsGroupingType is None, then
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @param iResultsGroupingValue is ignored.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sSqlQuery = self._getSqlQueryForGroupSearch('COUNT(TestSets.idTestSet)', tsNow, sInterval,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync enmResultsGroupingType, iResultsGroupingValue, fOnlyFailures)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute(sSqlQuery)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._oDb.fetchOne()[0]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getTestGroups(self, tsNow, sPeriod):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get list of uniq TestGroupData objects which
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync found in all test results.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT DISTINCT TestGroups.*\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestGroups, TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestSets.idTestGroup = TestGroups.idTestGroup\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestGroups.tsExpire > TestSets.tsCreated\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestGroups.tsEffective <= TestSets.tsCreated'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND ' + self._getTimePeriodQueryPart(tsNow, sPeriod))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aaoRows = self._oDb.fetchAll()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet = []
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in aaoRows:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo Need to take time into consideration. Will go belly up if we delete a testgroup.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet.append(TestGroupData().initFromDbRow(aoRow))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoRet
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getBuilds(self, tsNow, sPeriod):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get list of uniq BuildDataEx objects which
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync found in all test results.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT DISTINCT Builds.*, BuildCategories.*\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM Builds, BuildCategories, TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestSets.idBuild = Builds.idBuild\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND Builds.idBuildCategory = BuildCategories.idBuildCategory\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND Builds.tsExpire > TestSets.tsCreated\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND Builds.tsEffective <= TestSets.tsCreated'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND ' + self._getTimePeriodQueryPart(tsNow, sPeriod))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aaoRows = self._oDb.fetchAll()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet = []
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in aaoRows:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet.append(BuildDataEx().initFromDbRow(aoRow))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoRet
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getTestBoxes(self, tsNow, sPeriod):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get list of uniq TestBoxData objects which
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync found in all test results.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo do all in one query.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT DISTINCT TestBoxes.idTestBox, TestBoxes.idGenTestBox\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestBoxes, TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestSets.idGenTestBox = TestBoxes.idGenTestBox\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND ' + self._getTimePeriodQueryPart(tsNow, sPeriod) +
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY TestBoxes.idTestBox, TestBoxes.idGenTestBox DESC' );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idPrevTestBox = -1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asIdGenTestBoxes = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow[0] != idPrevTestBox:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idPrevTestBox = aoRow[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asIdGenTestBoxes.append(str(aoRow[1]));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet = []
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(asIdGenTestBoxes) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestBoxes\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idGenTestBox IN (' + ','.join(asIdGenTestBoxes) + ')\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY sName');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet.append(TestBoxData().initFromDbRow(aoRow));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoRet
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getTestCases(self, tsNow, sPeriod):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get a list of unique TestCaseData objects which is appears in the test
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync specified result period.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT DISTINCT TestCases.idTestCase, TestCases.idGenTestCase, TestSets.tsConfig\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestCases, TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestSets.idTestCase = TestCases.idTestCase\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestCases.tsExpire > TestSets.tsCreated\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestCases.tsEffective <= TestSets.tsCreated\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND ' + self._getTimePeriodQueryPart(tsNow, sPeriod) +
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY TestCases.idTestCase, TestCases.idGenTestCase DESC\n');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aaoRows = self._oDb.fetchAll()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet = []
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idPrevTestCase = -1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in aaoRows:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo reduce subqueries
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow[0] != idPrevTestCase:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idPrevTestCase = aoRow[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet.append(TestCaseData().initFromDbWithGenId(self._oDb, aoRow[1], aoRow[2]))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoRet
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getSchedGroups(self, tsNow, sPeriod):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get list of uniq SchedGroupData objects which
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync found in all test results.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT DISTINCT TestBoxes.idSchedGroup\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestBoxes, TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestSets.idGenTestBox = TestBoxes.idGenTestBox\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestBoxes.tsExpire > TestSets.tsCreated\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestBoxes.tsEffective <= TestSets.tsCreated'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND ' + self._getTimePeriodQueryPart(tsNow, sPeriod))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aiRows = self._oDb.fetchAll()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet = []
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for iRow in aiRows:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo reduce subqueries
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet.append(SchedGroupData().initFromDbWithId(self._oDb, iRow))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoRet
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getById(self, idTestResult):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get build record by its id
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResult = %s\n',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (idTestResult,))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aRows = self._oDb.fetchAll()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aRows) not in (0, 1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Found more than one test result with the same credentials. Database structure is corrupted.')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return TestResultData().initFromDbRow(aRows[0])
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except IndexError:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Details view and interface.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def fetchResultTree(self, idTestSet, cMaxDepth = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Fetches the result tree for the given test set.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns a tree of TestResultDataEx nodes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception on invalid input and database issues.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Depth first, i.e. just like the XML added them.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo this still isn't performing extremely well, consider optimizations.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sQuery = self._oDb.formatBindArgs(
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SELECT TestResults.*,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResultStrTab.sValue,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' EXISTS ( SELECT idTestResultValue\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' FROM TestResultValues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' WHERE TestResultValues.idTestResult = TestResults.idTestResult ) AS fHasValues,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' EXISTS ( SELECT idTestResultMsg\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' FROM TestResultMsgs\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' WHERE TestResultMsgs.idTestResult = TestResults.idTestResult ) AS fHasMsgs,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' EXISTS ( SELECT idTestResultFile\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' FROM TestResultFiles\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' WHERE TestResultFiles.idTestResult = TestResults.idTestResult ) AS fHasFiles\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults, TestResultStrTab\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestResults.idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResults.idStrName = TestResultStrTab.idStr\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestSet, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cMaxDepth is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sQuery += self._oDb.formatBindArgs(' AND TestResults.iNestingDepth <= %s\n', (cMaxDepth,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sQuery += 'ORDER BY idTestResult ASC\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute(sQuery);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cRows = self._oDb.getRowCount();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cRows > 65536:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMTooManyRows('Too many rows returned for idTestSet=%d: %d' % (idTestSet, cRows,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aaoRows = self._oDb.fetchAll();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aaoRows) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('No test results for idTestSet=%d.' % (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Set up the root node first.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRow = aaoRows[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oRoot = TestResultDataEx().initFromDbRow(aoRow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oRoot.idTestResultParent is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise self._oDb.integrityException('The root TestResult (#%s) has a parent (#%s)!'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oRoot.idTestResult, oRoot.idTestResultParent));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fetchResultTreeNodeExtras(oRoot, aoRow[-3], aoRow[-2], aoRow[-1]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # The chilren (if any).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dLookup = { oRoot.idTestResult: oRoot };
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oParent = oRoot;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for iRow in range(1, len(aaoRows)):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRow = aaoRows[iRow];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oCur = TestResultDataEx().initFromDbRow(aoRow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fetchResultTreeNodeExtras(oCur, aoRow[-3], aoRow[-2], aoRow[-1]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Figure out and vet the parent.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oParent.idTestResult != oCur.idTestResultParent:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oParent = dLookup.get(oCur.idTestResultParent, None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oParent is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise self._oDb.integrityException('TestResult #%d is orphaned from its parent #%s.'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oCur.idTestResult, oCur.idTestResultParent,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oParent.iNestingDepth + 1 != oCur.iNestingDepth:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise self._oDb.integrityException('TestResult #%d has incorrect nesting depth (%d instead of %d)'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oCur.idTestResult, oCur.iNestingDepth, oParent.iNestingDepth + 1,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Link it up.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oCur.oParent = oParent;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oParent.aoChildren.append(oCur);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dLookup[oCur.idTestResult] = oCur;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (oRoot, dLookup);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _fetchResultTreeNodeExtras(self, oCurNode, fHasValues, fHasMsgs, fHasFiles):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fetchResultTree worker that fetches values, message and files for the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync specified node.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert(oCurNode.aoValues == []);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert(oCurNode.aoMsgs == []);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert(oCurNode.aoFiles == []);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fHasValues:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT TestResultValues.*,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResultStrTab.sValue\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResultValues, TestResultStrTab\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestResultValues.idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResultValues.idStrName = TestResultStrTab.idStr\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY idTestResultValue ASC\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( oCurNode.idTestResult, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oCurNode.aoValues.append(TestResultValueDataEx().initFromDbRow(aoRow));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fHasMsgs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT TestResultMsgs.*,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResultStrTab.sValue\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResultMsgs, TestResultStrTab\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestResultMsgs.idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResultMsgs.idStrMsg = TestResultStrTab.idStr\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY idTestResultMsg ASC\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( oCurNode.idTestResult, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oCurNode.aoMsgs.append(TestResultMsgDataEx().initFromDbRow(aoRow));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fHasFiles:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT TestResultFiles.*,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' StrTabFile.sValue AS sFile,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' StrTabDesc.sValue AS sDescription,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' StrTabKind.sValue AS sKind,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' StrTabMime.sValue AS sMime\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResultFiles,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResultStrTab AS StrTabFile,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResultStrTab AS StrTabDesc,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResultStrTab AS StrTabKind,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResultStrTab AS StrTabMime\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestResultFiles.idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResultFiles.idStrFile = StrTabFile.idStr\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResultFiles.idStrDescription = StrTabDesc.idStr\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResultFiles.idStrKind = StrTabKind.idStr\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResultFiles.idStrMime = StrTabMime.idStr\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY idTestResultFile ASC\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( oCurNode.idTestResult, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oCurNode.aoFiles.append(TestResultFileDataEx().initFromDbRow(aoRow));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # TestBoxController interface(s).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _inhumeTestResults(self, aoStack, idTestSet, sError):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The test produces too much output, kill and bury it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Note! We leave the test set open, only the test result records are
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync completed. Thus, _getResultStack will return an empty stack and
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cause XML processing to fail immediately, while we can still
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync record when it actually completed in the test set the normal way.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.dprint('** _inhumeTestResults: idTestSet=%d\n%s' % (idTestSet, self._stringifyStack(aoStack),));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # First add a message.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._newFailureDetails(aoStack[0].idTestResult, sError, None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # The complete all open test results.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestResult in aoStack:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestResult.cErrors += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._completeTestResults(oTestResult, None, TestResultData.ksTestStatus_Failure, oTestResult.cErrors);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # A bit of paranoia.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET cErrors = cErrors + 1,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' enmStatus = \'failure\'::TestStatus_T,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsElapsed = CURRENT_TIMESTAMP - tsCreated\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND enmStatus = \'running\'::TestStatus_T\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestSet, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.commit();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def strTabString(self, sString, fCommit = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets the string table id for the given string, adding it if new.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Note! A copy of this code is also in TestSetLogic.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo move this and make a stored procedure for it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT idStr\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResultStrTab\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE sValue = %s'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (sString,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._oDb.getRowCount() == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResultStrTab (sValue)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES (%s)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'RETURNING idStr\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (sString,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fCommit:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.commit();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @staticmethod
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _stringifyStack(aoStack):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Returns a string rep of the stack."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRet = '';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for i in range(len(aoStack)):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRet += 'aoStack[%d]=%s\n' % (i, aoStack[i]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return sRet;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _getResultStack(self, idTestSet):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets the current stack of result sets.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND enmStatus = \'running\'::TestStatus_T\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY idTestResult DESC'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestSet, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoStack = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoStack.append(TestResultData().initFromDbRow(aoRow));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for i in range(len(aoStack)):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert aoStack[i].iNestingDepth == len(aoStack) - i - 1, self._stringifyStack(aoStack);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoStack;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _newTestResult(self, idTestResultParent, idTestSet, iNestingDepth, tsCreated, sName, dCounts, fCommit = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Creates a new test result.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns the TestResultData object for the new record.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync May raise exception on database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert idTestResultParent is not None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert idTestResultParent > 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # This isn't necessarily very efficient, but it's necessary to prevent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # a wild test or testbox from filling up the database.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCountName = 'cTestResults';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sCountName not in dCounts:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(idTestResult)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dCounts[sCountName] > config.g_kcMaxTestResultsPerTS:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestResultHangingOffence('Too many sub-tests in total!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCountName = 'cTestResultsIn%d' % (idTestResultParent,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sCountName not in dCounts:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(idTestResult)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResultParent = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResultParent,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dCounts[sCountName] > config.g_kcMaxTestResultsPerTR:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestResultHangingOffence('Too many immediate sub-tests!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # This is also a hanging offence.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iNestingDepth > config.g_kcMaxTestResultDepth:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestResultHangingOffence('To deep sub-test nesting!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Ditto.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(sName) > config.g_kcchMaxTestResultName:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestResultHangingOffence('Test name is too long: %d chars - "%s"' % (len(sName), sName));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Within bounds, do the job.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idStrName = self.strTabString(sName, fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResults (\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestResultParent,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestSet,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsCreated,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idStrName,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' iNestingDepth )\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES (%s, %s, TIMESTAMP WITH TIME ZONE %s, %s, %s)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'RETURNING *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResultParent, idTestSet, tsCreated, idStrName, iNestingDepth) )
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = TestResultData().initFromDbRow(self._oDb.fetchOne());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.maybeCommit(fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oData;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _newTestValue(self, idTestResult, idTestSet, sName, lValue, sUnit, dCounts, tsCreated = None, fCommit = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Creates a test value.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync May raise exception on database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Bounds checking.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCountName = 'cTestValues';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sCountName not in dCounts:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(idTestResultValue)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResultValues, TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestResultValues.idTestResult = TestResults.idTestResult\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResults.idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dCounts[sCountName] > config.g_kcMaxTestValuesPerTS:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestResultHangingOffence('Too many values in total!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCountName = 'cTestValuesIn%d' % (idTestResult,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sCountName not in dCounts:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(idTestResultValue)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResultValues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResult,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dCounts[sCountName] > config.g_kcMaxTestValuesPerTR:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestResultHangingOffence('Too many immediate values for one test result!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(sName) > config.g_kcchMaxTestValueName:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestResultHangingOffence('Value name is too long: %d chars - "%s"' % (len(sName), sName));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Do the job.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iUnit = constants.valueunit.g_kdNameToConst.get(sUnit, constants.valueunit.NONE);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idStrName = self.strTabString(sName, fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if tsCreated is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResultValues (\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestResult,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestSet,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idStrName,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' lValue,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' iUnit)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( %s, %s, %s, %s, %s )\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResult, idTestSet, idStrName, lValue, iUnit,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResultValues (\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestResult,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestSet,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsCreated,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idStrName,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' lValue,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' iUnit)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( %s, %s, TIMESTAMP WITH TIME ZONE %s, %s, %s, %s )\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResult, idTestSet, tsCreated, idStrName, lValue, iUnit,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.maybeCommit(fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _newFailureDetails(self, idTestResult, sText, dCounts, tsCreated = None, fCommit = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Creates a record detailing cause of failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync May raise exception on database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Overflow protection.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dCounts is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCountName = 'cTestMsgsIn%d' % (idTestResult,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sCountName not in dCounts:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(idTestResultMsg)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResultMsgs\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResult,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts[sCountName] += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dCounts[sCountName] > config.g_kcMaxTestMsgsPerTR:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestResultHangingOffence('Too many messages under for one test result!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(sText) > config.g_kcchMaxTestMsg:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestResultHangingOffence('Failure details message is too long: %d chars - "%s"' % (len(sText), sText));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Do the job.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idStrMsg = self.strTabString(sText, fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if tsCreated is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResultMsgs (\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestResult,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idStrMsg,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' enmLevel)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( %s, %s, %s)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResult, idStrMsg, 'failure',) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResultMsgs (\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestResult,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsCreated,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idStrMsg,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' enmLevel)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( %s, TIMESTAMP WITH TIME ZONE %s, %s, %s)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResult, tsCreated, idStrMsg, 'failure',) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.maybeCommit(fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _completeTestResults(self, oTestResult, tsDone, enmStatus, cErrors = 0, fCommit = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Completes a test result. Updates the oTestResult object.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync May raise exception on database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.dprint('** _completeTestResults: cErrors=%s tsDone=%s enmStatus=%s oTestResults=\n%s'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (cErrors, tsDone, enmStatus, oTestResult,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Sanity check: No open sub tests (aoStack should make sure about this!).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(idTestResult)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResultParent = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND enmStatus = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( oTestResult.idTestResult, TestResultData.ksTestStatus_Running,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cOpenSubTest = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert cOpenSubTest == 0, 'cOpenSubTest=%d - %s' % (cOpenSubTest, oTestResult,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oTestResult.enmStatus == TestResultData.ksTestStatus_Running;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Make sure the reporter isn't lying about successes or error counts.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COALESCE(SUM(cErrors), 0)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResultParent = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( oTestResult.idTestResult, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cMinErrors = self._oDb.fetchOne()[0] + oTestResult.cErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cErrors < cMinErrors:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cErrors = cMinErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cErrors > 0 and enmStatus == TestResultData.ksTestStatus_Success:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync enmStatus = TestResultData.ksTestStatus_Failure
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Do the update.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if tsDone is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET cErrors = %s,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' enmStatus = %s,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsElapsed = CURRENT_TIMESTAMP - tsCreated\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'RETURNING tsElapsed'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( cErrors, enmStatus, oTestResult.idTestResult,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET cErrors = %s,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' enmStatus = %s,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsElapsed = TIMESTAMP WITH TIME ZONE %s - tsCreated\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'RETURNING tsElapsed'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( cErrors, enmStatus, tsDone, oTestResult.idTestResult,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestResult.tsElapsed = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestResult.enmStatus = enmStatus;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestResult.cErrors = cErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.maybeCommit(fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _doPopHint(self, aoStack, cStackEntries, dCounts):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Executes a PopHint. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert cStackEntries >= 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while len(aoStack) > cStackEntries:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoStack[0].enmStatus == TestResultData.ksTestStatus_Running:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._newFailureDetails(aoStack[0].idTestResult, 'XML error: Missing </Test>', dCounts);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._completeTestResults(aoStack[0], tsDone = None, cErrors = 1,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync enmStatus = TestResultData.ksTestStatus_Failure, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoStack.pop(0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @staticmethod
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _validateElement(sName, dAttribs, fClosed):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Validates an element and its attributes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Validate attributes by name.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Validate integer attributes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sAttr in [ 'errors', 'testdepth' ]:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sAttr in dAttribs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = int(dAttribs[sAttr]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'Element %s has an invalid %s attribute value: %s.' % (sName, sAttr, dAttribs[sAttr],);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Validate long attributes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sAttr in [ 'value', ]:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sAttr in dAttribs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = long(dAttribs[sAttr]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'Element %s has an invalid %s attribute value: %s.' % (sName, sAttr, dAttribs[sAttr],);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Validate string attributes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sAttr in [ 'name', 'unit', 'text' ]:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sAttr in dAttribs and len(dAttribs[sAttr]) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'Element %s has an empty %s attribute value.' % (sName, sAttr,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Validate the timestamp attribute.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if 'timestamp' in dAttribs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (dAttribs['timestamp'], sError) = ModelDataBase.validateTs(dAttribs['timestamp'], fAllowNull = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sError is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'Element %s has an invalid timestamp ("%s"): %s' % (sName, dAttribs['timestamp'], sError,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check that attributes that are required are present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We ignore extra attributes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dElementAttribs = \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync {
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Test': [ 'timestamp', 'name', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Value': [ 'timestamp', 'name', 'unit', 'value', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FailureDetails': [ 'timestamp', 'text', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Passed': [ 'timestamp', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Skipped': [ 'timestamp', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Failed': [ 'timestamp', 'errors', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'TimedOut': [ 'timestamp', 'errors', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'End': [ 'timestamp', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'PushHint': [ 'testdepth', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'PopHint': [ 'testdepth', ],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync };
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sName not in dElementAttribs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'Unknown element "%s".' % (sName,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sAttr in dElementAttribs[sName]:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sAttr not in dAttribs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'Element %s requires attribute "%s".' % (sName, sAttr);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Only the Test element can (and must) remain open.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sName == 'Test' and fClosed:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return '<Test/> is not allowed.';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sName != 'Test' and not fClosed:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'All elements except <Test> must be closed.';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @staticmethod
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _parseElement(sElement):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Parses an element.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Element level bits.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName = sElement.split()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sElement = sElement[len(sName):];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fClosed = sElement[-1] == '/';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fClosed:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sElement = sElement[:-1];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Attributes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dAttribs = {};
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sElement = sElement.strip();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while len(sElement) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Extract attribute name.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync off = sElement.find('=');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if off < 0 or not sElement[:off].isalnum():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Attributes shall have alpha numberical names and have values.';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sAttr = sElement[:off];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Extract attribute value.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if off + 2 >= len(sElement) or sElement[off + 1] != '"':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Attribute (%s) value is missing or not in double quotes.' % (sAttr,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync off += 2;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync offEndQuote = sElement.find('"', off);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if offEndQuote < 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Attribute (%s) value is missing end quotation mark.' % (sAttr,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sElement[off:offEndQuote];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check for duplicates.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sAttr in dAttribs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Attribute "%s" appears more than once.' % (sAttr,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Unescape the value.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('&lt;', '<');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('&gt;', '>');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('&apos;', '\'');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('&quot;', '"');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('&#xA;', '\n');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('&#xD;', '\r');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = sValue.replace('&amp;', '&'); # last
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Done.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dAttribs[sAttr] = sValue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # advance
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sElement = sElement[offEndQuote + 1:];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sElement = sElement.lstrip();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Validate the element before we return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sError is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = TestResultLogic._validateElement(sName, dAttribs, fClosed);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (sName, dAttribs, sError)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _handleElement(self, sName, dAttribs, idTestSet, aoStack, aaiHints, dCounts):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Worker for processXmlStream that handles one element.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns None on success, error string on bad XML or similar.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception on hanging offence and on database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sName == 'Test':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iNestingDepth = aoStack[0].iNestingDepth + 1 if len(aoStack) > 0 else 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoStack.insert(0, self._newTestResult(idTestResultParent = aoStack[0].idTestResult, idTestSet = idTestSet,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync tsCreated = dAttribs['timestamp'], sName = dAttribs['name'],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iNestingDepth = iNestingDepth, dCounts = dCounts, fCommit = True) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sName == 'Value':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._newTestValue(idTestResult = aoStack[0].idTestResult, idTestSet = idTestSet, tsCreated = dAttribs['timestamp'],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName = dAttribs['name'], sUnit = dAttribs['unit'], lValue = long(dAttribs['value']),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts = dCounts, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sName == 'FailureDetails':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._newFailureDetails(idTestResult = aoStack[0].idTestResult, tsCreated = dAttribs['timestamp'],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sText = dAttribs['text'], dCounts = dCounts, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sName == 'Passed':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._completeTestResults(aoStack[0], tsDone = dAttribs['timestamp'],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync enmStatus = TestResultData.ksTestStatus_Success, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sName == 'Skipped':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._completeTestResults(aoStack[0], tsDone = dAttribs['timestamp'],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync enmStatus = TestResultData.ksTestStatus_Skipped, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sName == 'Failed':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._completeTestResults(aoStack[0], tsDone = dAttribs['timestamp'], cErrors = int(dAttribs['errors']),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync enmStatus = TestResultData.ksTestStatus_Failure, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sName == 'TimedOut':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._completeTestResults(aoStack[0], tsDone = dAttribs['timestamp'], cErrors = int(dAttribs['errors']),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync enmStatus = TestResultData.ksTestStatus_TimedOut, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sName == 'End':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._completeTestResults(aoStack[0], tsDone = dAttribs['timestamp'],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cErrors = int(dAttribs.get('errors', '1')),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync enmStatus = TestResultData.ksTestStatus_Success, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sName == 'PushHint':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aaiHints) > 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'PushHint cannot be nested.'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aaiHints.insert(0, [len(aoStack), int(dAttribs['testdepth'])]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sName == 'PopHint':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aaiHints) < 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'No hint to pop.'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iDesiredTestDepth = int(dAttribs['testdepth']);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cStackEntries, iTestDepth = aaiHints.pop(0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._doPopHint(aoStack, cStackEntries, dCounts); # Fake the necessary '<End/></Test>' tags.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iDesiredTestDepth != iTestDepth:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'PopHint tag has different testdepth: %d, on stack %d.' % (iDesiredTestDepth, iTestDepth);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return 'Unexpected element "%s".' % (sName,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def processXmlStream(self, sXml, idTestSet):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Processes the "XML" stream section given in sXml.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The sXml isn't a complete XML document, even should we save up all sXml
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for a given set, they may not form a complete and well formed XML
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync document since the test may be aborted, abend or simply be buggy. We
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync therefore do our own parsing and treat the XML tags as commands more
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync than anything else.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns (sError, fUnforgivable), where sError is None on success.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync May raise database exception.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoStack = self._getResultStack(idTestSet); # [0] == top; [-1] == bottom.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aoStack) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return ('No open results', True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.dprint('** processXmlStream len(aoStack)=%s' % (len(aoStack),));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #self._oDb.dprint('processXmlStream: %s' % (self._stringifyStack(aoStack),));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #self._oDb.dprint('processXmlStream: sXml=%s' % (sXml,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dCounts = {};
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aaiHints = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fExpectCloseTest = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sXml = sXml.strip();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while len(sXml) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sXml.startswith('</Test>'): # Only closing tag.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync offNext = len('</Test>');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aoStack) <= 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Trying to close the top test results.'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # ASSUMES that we've just seen an <End/>, <Passed/>, <Failed/>,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # <TimedOut/> or <Skipped/> tag earlier in this call!
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoStack[0].enmStatus == TestResultData.ksTestStatus_Running or not fExpectCloseTest:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Missing <End/>, <Passed/>, <Failed/>, <TimedOut/> or <Skipped/> tag.';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoStack.pop(0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fExpectCloseTest = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif fExpectCloseTest:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Expected </Test>.'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sXml.startswith('<?xml '): # Ignore (included files).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync offNext = sXml.find('?>');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if offNext < 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Unterminated <?xml ?> element.';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync offNext += 2;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sXml[0] == '<':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Parse and check the tag.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not sXml[1].isalpha():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Malformed element.';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync offNext = sXml.find('>')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if offNext < 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Unterminated element.';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sName, dAttribs, sError) = self._parseElement(sXml[1:offNext]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync offNext += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sError is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Handle it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = self._handleElement(sName, dAttribs, idTestSet, aoStack, aaiHints, dCounts);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except TestResultHangingOffence as oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._inhumeTestResults(aoStack, idTestSet, str(oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (str(oXcpt), True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fExpectCloseTest = sName in [ 'End', 'Passed', 'Failed', 'TimedOut', 'Skipped', ];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Unexpected content.';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Advance.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sXml = sXml[offNext:];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sXml = sXml.lstrip();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Post processing checks.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sError is None and fExpectCloseTest:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Expected </Test> before the end of the XML section.'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sError is None and len(aaiHints) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError = 'Expected </PopHint> before the end of the XML section.'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aaiHints) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._doPopHint(aoStack, aaiHints[-1][0], dCounts);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Log the error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sError is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync SystemLogLogic(self._oDb).addEntry(SystemLogData.ksEvent_XmlResultMalformed,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'idTestSet=%s idTestResult=%s XML="%s" %s'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % ( idTestSet,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoStack[0].idTestResult if len(aoStack) > 0 else -1,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sXml[:30 if len(sXml) >= 30 else len(sXml)],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sError, ),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cHoursRepeat = 6, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (sError, False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Unit testing.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# pylint: disable=C0111
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultDataTestCase(ModelDataBaseTestCase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def setUp(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoSamples = [TestResultData(),];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestResultValueDataTestCase(ModelDataBaseTestCase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def setUp(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoSamples = [TestResultValueData(),];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncif __name__ == '__main__':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync unittest.main();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # not reached.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync