cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# -*- coding: utf-8 -*-
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# $Id$
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTest Manager - TestSet.
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
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Standard python imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport os;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport zipfile;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport unittest;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Validation Kit imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom common import utils;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager import config;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.base import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testbox import TestBoxData;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testresults import TestResultFileDataEx;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestSetData(ModelDataBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestSet 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 ksIdAttr = 'idTestSet';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestSet = 'TestSet_idTestSet';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsConfig = 'TestSet_tsConfig';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsCreated = 'TestSet_tsCreated';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsDone = 'TestSet_tsDone';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_enmStatus = 'TestSet_enmStatus';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idBuild = 'TestSet_idBuild';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idBuildCategory = 'TestSet_idBuildCategory';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idBuildTestSuite = 'TestSet_idBuildTestSuite';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idGenTestBox = 'TestSet_idGenTestBox';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestBox = 'TestSet_idTestBox';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestGroup = 'TestSet_idTestGroup';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idGenTestCase = 'TestSet_idGenTestCase';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestCase = 'TestSet_idTestCase';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idGenTestCaseArgs = 'TestSet_idGenTestCaseArgs';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestCaseArgs = 'TestSet_idTestCaseArgs';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestResult = 'TestSet_idTestResult';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_sBaseFilename = 'TestSet_sBaseFilename';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_iGangMemberNo = 'TestSet_iGangMemberNo';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestSetGangLeader = 'TestSet_idTestSetGangLeader';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasAllowNullAttributes = ['tsDone', 'idBuildTestSuite', 'idTestSetGangLeader' ];
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 kiMin_iGangMemberNo = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kiMax_iGangMemberNo = 1023;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ModelDataBase.__init__(self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Initialize with defaults.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # See the database for explanations of each of these fields.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSet = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsConfig = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsDone = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.enmStatus = 'running';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuild = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuildCategory = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuildTestSuite = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idGenTestBox = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestBox = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestGroup = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idGenTestCase = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestCase = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idGenTestCaseArgs = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestCaseArgs = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sBaseFilename = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iGangMemberNo = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSetGangLeader = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Internal worker for initFromDbWithId and initFromDbWithGenId as well as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxSetLogic.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('TestSet not found.');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSet = aoRow[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsConfig = aoRow[1];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsCreated = aoRow[2];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsDone = aoRow[3];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.enmStatus = aoRow[4];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuild = aoRow[5];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuildCategory = aoRow[6];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idBuildTestSuite = aoRow[7];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idGenTestBox = aoRow[8];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestBox = aoRow[9];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestGroup = aoRow[10];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idGenTestCase = aoRow[11];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestCase = aoRow[12];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idGenTestCaseArgs = aoRow[13];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestCaseArgs = aoRow[14];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestResult = aoRow[15];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.sBaseFilename = aoRow[16];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iGangMemberNo = aoRow[17];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSetGangLeader = aoRow[18];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbWithId(self, oDb, idTestSet):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Initialize the object from the database.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.execute('SELECT *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (idTestSet, ) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRow = oDb.fetchOne()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('idTestSet=%s not found' % (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.initFromDbRow(aoRow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def openFile(self, sFilename, sMode = 'rb'):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Opens a file.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns (oFile, cbFile, fIsStream) on success.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns (None, sErrorMsg, None) on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Will not raise exceptions, unless the class instance is invalid.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert sMode in [ 'rb', 'r', 'rU' ];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try raw file first.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFile1 = os.path.join(config.g_ksFileAreaRootDir, self.sBaseFilename + '-' + sFilename);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFile = open(sFile1, sMode);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (oFile, os.fstat(oFile.fileno()).st_size, False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception as oXcpt1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try the zip archive next.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFile2 = os.path.join(config.g_ksZipFileAreaRootDir, self.sBaseFilename + '.zip');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oZipFile = zipfile.ZipFile(sFile2, 'r');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFile = oZipFile.open(sFilename, sMode if sMode != 'rb' else 'r');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cbFile = oZipFile.getinfo(sFilename).file_size;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (oFile, cbFile, True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception as oXcpt2:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Construct a meaningful error message.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if os.path.exists(sFile1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (None, 'Error opening "%s": %s' % (sFile1, oXcpt1), None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not os.path.exists(sFile2):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (None, 'File "%s" not found. [%s, %s]' % (sFilename, sFile1, sFile2,), None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (None, 'Error opening "%s" inside "%s": %s' % (sFilename, sFile2, oXcpt2), None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception as oXcpt3:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (None, 'Aa! Megami-sama! %s; %s; %s' % (oXcpt1, oXcpt2, oXcpt3,), None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (None, 'Code not reachable!', None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def createFile(self, sFilename, sMode = 'wb'):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Creates a new file.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns oFile on success.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns sErrorMsg on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert sMode in [ 'wb', 'w', 'wU' ];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try raw file first.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFile1 = os.path.join(config.g_ksFileAreaRootDir, self.sBaseFilename + '-' + sFilename);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not os.path.exists(os.path.dirname(sFile1)):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.makedirs(os.path.dirname(sFile1), 0o755);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFile = open(sFile1, sMode);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception as oXcpt1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return str(oXcpt1);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oFile;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestSetLogic(ModelLogicBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestSet logic.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self, oDb):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ModelLogicBase.__init__(self, oDb);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def tryFetch(self, idTestSet):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Attempts to fetch a test set.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns a TestSetData object on success.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns None if no status was found.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception on other errors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._oDb.getRowCount() == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = TestSetData();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oData.initFromDbRow(self._oDb.fetchOne());
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 ## @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 def complete(self, idTestSet, sStatus, fCommit = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Completes the testset.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns the test set ID of the gang leader, None if no gang involvement.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exceptions on database errors and invalid input.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert sStatus != TestSetData.ksTestStatus_Running;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Get the basic test set data and check if there is anything to do here.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = TestSetData().initFromDbWithId(self._oDb, idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oData.enmStatus != TestSetData.ksTestStatus_Running:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('TestSet %s is already completed as %s.' % (idTestSet, oData.enmStatus));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oData.idTestResult is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise self._oDb.integrityException('idTestResult is NULL for TestSet %u' % (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Close open sub test results, count these as errors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Note! No need to propagate error counts here. Only one tree line will
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # have open sets, and it will go all the way to the root.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT idTestResult\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND enmStatus = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND idTestResult <> %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY idTestResult DESC\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (idTestSet, TestSetData.ksTestStatus_Running, oData.idTestResult));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aaoRows = self._oDb.fetchAll();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aaoRows):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idStr = self.strTabString('Unclosed test result', fCommit = fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in aaoRows:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET enmStatus = \'failure\',\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsElapsed = CURRENT_TIMESTAMP - tsCreated,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' cErrors = cErrors + 1\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (aoRow[0],));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResultMsgs (idTestResult, idStrMsg, enmLevel)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( %s, %s, \'failure\'::TestResultMsgLevel_T)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (aoRow[0], idStr,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # If it's a success result, check it against error counters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sStatus not in TestSetData.kasBadTestStatuses:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(*)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND cErrors > 0\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cErrors = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cErrors > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sStatus = TestSetData.ksTestStatus_Failure;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # If it's an pure 'failure', check for timeouts and propagate it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sStatus == TestSetData.ksTestStatus_Failure:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(*)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND enmStatus = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestSet, TestSetData.ksTestStatus_TimedOut, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._oDb.fetchOne()[0] > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sStatus = TestSetData.ksTestStatus_TimedOut;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Complete the top level test result and then the test set.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET cErrors = (SELECT COALESCE(SUM(cErrors), 0)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' WHERE idTestResultParent = %s)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'RETURNING cErrors\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (oData.idTestResult, oData.idTestResult));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cErrors = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cErrors == 0 and sStatus in TestSetData.kasBadTestStatuses:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET cErrors = 1\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (oData.idTestResult,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif cErrors > 0 and sStatus not in TestSetData.kasBadTestStatuses:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sStatus = TestSetData.ksTestStatus_Failure; # Impossible.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET enmStatus = %s,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsElapsed = CURRENT_TIMESTAMP - tsCreated\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (sStatus, oData.idTestResult,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET enmStatus = %s,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsDone = CURRENT_TIMESTAMP\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (sStatus, idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.maybeCommit(fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oData.idTestSetGangLeader;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def completeAsAbandond(self, idTestSet, fCommit = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Completes the testset as abandoned if necessary.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync See scenario #9:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync file://../../docs/AutomaticTestingRevamp.html#cleaning-up-abandond-testcase
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True if successfully completed as abandond, False if it's already
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync completed, and raises exceptions under exceptional circumstances.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Get the basic test set data and check if there is anything to do here.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = self.tryFetch(idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oData is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oData.enmStatus != TestSetData.ksTestStatus_Running:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oData.idTestResult is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Clean up test results, adding a message why they failed.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET enmStatus = \'failure\',\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsElapsed = CURRENT_TIMESTAMP - tsCreated,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' cErrors = cErrors + 1\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND enmStatus = \'running\'::TestStatus_T\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idStr = self.strTabString('The test was abandond by the testbox', fCommit = fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResultMsgs (idTestResult, idStrMsg, enmLevel)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( %s, %s, \'failure\'::TestResultMsgLevel_T)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (oData.idTestResult, idStr,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Complete the testset.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET enmStatus = \'failure\',\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsDone = CURRENT_TIMESTAMP\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND enmStatus = \'running\'::TestStatus_T\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.maybeCommit(fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def completeAsGangGatheringTimeout(self, idTestSet, fCommit = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Completes the testset with a gang-gathering timeout.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exceptions on database errors and invalid input.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Get the basic test set data and check if there is anything to do here.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = TestSetData().initFromDbWithId(self._oDb, idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oData.enmStatus != TestSetData.ksTestStatus_Running:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('TestSet %s is already completed as %s.' % (idTestSet, oData.enmStatus));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oData.idTestResult is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise self._oDb.integrityException('idTestResult is NULL for TestSet %u' % (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Complete the top level test result and then the test set.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET enmStatus = \'failure\',\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsElapsed = CURRENT_TIMESTAMP - tsCreated,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' cErrors = cErrors + 1\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND enmStatus = \'running\'::TestStatus_T\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idStr = self.strTabString('Gang gathering timed out', fCommit = fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResultMsgs (idTestResult, idStrMsg, enmLevel)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( %s, %s, \'failure\'::TestResultMsgLevel_T)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (oData.idTestResult, idStr,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'SET enmStatus = \'failure\',\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsDone = CURRENT_TIMESTAMP\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.maybeCommit(fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def createFile(self, oTestSet, sName, sMime, sKind, sDesc, cbFile, fCommit = False): # pylint: disable=R0914
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Creates a file and associating with the current test result record in
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync the test set.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns file object that the file content can be written to.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception on database error, I/O errors, if there are too many
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync files in the test set or if they take up too much disk space.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The caller (testboxdisp.py) is expected to do basic input validation,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync so we skip that and get on with the bits only we can do.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Furhter input and limit checks.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestSet.enmStatus != TestSetData.ksTestStatus_Running:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Cannot create files on a test set with status "%s".' % (oTestSet.enmStatus,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT TestResultStrTab.sValue\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResultFiles,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResults,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestResultStrTab\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestResults.idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResultFiles.idTestResult = TestResults.idTestResult\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResultStrTab.idStr = TestResultFiles.idStrFile\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( oTestSet.idTestSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._oDb.getRowCount() + 1 > config.g_kcMaxUploads:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Uploaded too many files already (%d).' % (self._oDb.getRowCount(),));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dFiles = {}
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cbTotalFiles = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dFiles[aoRow[0].lower()] = 1; # For determining a unique filename further down.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFile = os.path.join(config.g_ksFileAreaRootDir, oTestSet.sBaseFilename + '-' + aoRow[0]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cbTotalFiles += os.path.getsize(sFile);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cbTotalFiles += config.g_kcMbMaxUploadSingle * 1048576;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (cbTotalFiles + cbFile + 1048575) / 1048576 > config.g_kcMbMaxUploadTotal:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Will exceed total upload limit: %u bytes + %u bytes > %s MiB.' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (cbTotalFiles, cbFile, config.g_kcMbMaxUploadTotal));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Create a new file.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT idTestResult\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND enmStatus = \'running\'::TestStatus_T\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY idTestResult\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'LIMIT 1\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % ( oTestSet.idTestSet, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._oDb.getRowCount() < 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('No open test results - someone committed a capital offence or we ran into a race.');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idTestResult = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sName.lower() in dFiles:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Note! There is in theory a race here, but that's something the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # test driver doing parallel upload with non-unique names
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # should worry about. The TD should always avoid this path.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sOrgName = sName;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for i in range(2, config.g_kcMaxUploads + 6):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName = '%s-%s' % (i, sName,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sName not in dFiles:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sName is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Failed to find unique name for %s.' % (sOrgName,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResultFiles(idTestResult, idStrFile, idStrDescription, idStrKind, idStrMime)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES (%s, %s, %s, %s, %s)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResult,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.strTabString(sName),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.strTabString(sDesc),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.strTabString(sKind),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.strTabString(sMime),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFile = oTestSet.createFile(sName, 'wb');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if utils.isString(oFile):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Error creating "%s": %s' % (sName, oFile));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.maybeCommit(fCommit);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oFile;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getGang(self, idTestSetGangLeader):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns an array of TestBoxData object representing the gang for the given testset.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT TestBoxes.*\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestBoxes, TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestSets.idTestSetGangLeader = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestSets.idGenTestBox = TestBoxes.idGenTestBox\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY iGangMemberNo ASC\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (idTestSetGangLeader,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aaoRows = self._oDb.fetchAll();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoTestBoxes = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in aaoRows:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoTestBoxes.append(TestBoxData().initFromDbRow(aoRow));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoTestBoxes;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getFile(self, idTestSet, idTestResultFile):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets the TestResultFileEx corresponding to idTestResultFile.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises an exception if the file wasn't found, doesn't belong to
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idTestSet, and on DB error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
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 ' TestResults\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestResultFiles.idTestResultFile = %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 ' AND TestResults.idTestResult = TestResultFiles.idTestResult\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestResults.idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestResultFile, idTestSet, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return TestResultFileDataEx().initFromDbRow(self._oDb.fetchOne());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getById(self, idTestSet):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Get TestSet table record by its id
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet=%s\n',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (idTestSet,))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aRows = self._oDb.fetchAll()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aRows) not in (0, 1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Found more than one test sets with the same credentials. Database structure is corrupted.')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return TestSetData().initFromDbRow(aRows[0])
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except IndexError:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def fetchOrphaned(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns a list of TestSetData objects of orphaned test sets.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync A test set is orphaned if tsDone is NULL and the testbox has created
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync one or more newer testsets.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT TestSets.*\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestSets,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' (SELECT idTestSet, idTestBox FROM TestSets WHERE tsDone is NULL) AS t\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestSets.idTestSet = t.idTestSet\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND EXISTS(SELECT 1 FROM TestSets st\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' WHERE st.idTestBox = t.idTestBox AND st.idTestSet > t.idTestSet)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND NOT EXISTS(SELECT 1 FROM TestBoxStatuses tbs\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' WHERE tbs.idTestBox = t.idTestBox AND tbs.idTestSet = t.idTestSet)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER by TestSets.idTestBox, TestSets.idTestSet'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRet.append(TestSetData().initFromDbRow(aoRow));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoRet;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Unit testing.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# pylint: disable=C0111
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestSetDataTestCase(ModelDataBaseTestCase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def setUp(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoSamples = [TestSetData(),];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncif __name__ == '__main__':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync unittest.main();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # not reached.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync