VirtualBox

Changeset 61220 in vbox for trunk/src/VBox/ValidationKit


Ignore:
Timestamp:
May 27, 2016 1:16:02 AM (9 years ago)
Author:
vboxsync
Message:

testmanager: failiure reason fixes, some exception throwing cleanups, delinting with pylint 1.5.5.

Location:
trunk/src/VBox/ValidationKit/testmanager
Files:
35 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/testmanager/core/base.py

    r61149 r61220  
    5353    pass;
    5454
     55
    5556class TMTooManyRows(TMExceptionBase):
    5657    """
    5758    Too many rows in the result.
     59    Used by ModelLogicBase decendants.
     60    """
     61    pass;
     62
     63
     64class TMRowNotFound(TMExceptionBase):
     65    """
     66    Database row not found.
     67    Used by ModelLogicBase decendants.
     68    """
     69    pass;
     70
     71
     72class TMRowAlreadyExists(TMExceptionBase):
     73    """
     74    Database row already exists (typically raised by addEntry).
     75    Used by ModelLogicBase decendants.
     76    """
     77    pass;
     78
     79
     80class TMInvalidData(TMExceptionBase):
     81    """
     82    Data validation failed.
     83    Used by ModelLogicBase decendants.
     84    """
     85    pass;
     86
     87
     88class TMRowInUse(TMExceptionBase):
     89    """
     90    Database row is in use and cannot be deleted.
    5891    Used by ModelLogicBase decendants.
    5992    """
     
    81114    # an empty array ([]) instead of None as database NULL value.
    82115    kasAltArrayNull = [];
     116
     117    ## validate
     118    ## @{
     119    ksValidateFor_Add           = 'add';
     120    ksValidateFor_AddForeignId  = 'add-foreign-id';
     121    ksValidateFor_Edit          = 'edit';
     122    ksValidateFor_Other         = 'other';
     123    ## @}
    83124
    84125
     
    125166        Returns the hungarian prefix of the given name.
    126167        """
    127         for i in range(len(sName)):
     168        for i, _ in enumerate(sName):
    128169            if sName[i] not in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    129170                                'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']:
     
    179220        elif isinstance(oValue, list) and len(oValue) > 0 and isinstance(oValue[0], ModelDataBase):
    180221            oValue = copy.copy(oValue);
    181             for i in range(len(oValue)):
     222            for i, _ in enumerate(oValue):
    182223                assert isinstance(oValue[i], ModelDataBase);
    183224                oValue[i] = copy.copy(oValue[i]);
     
    215256        elif isinstance(oValue, list) and len(oValue) > 0 and isinstance(oValue[0], ModelDataBase):
    216257            oValue = copy.copy(oValue);
    217             for i in range(len(oValue)):
     258            for i, _ in enumerate(oValue):
    218259                assert isinstance(oValue[i], ModelDataBase);
    219260                oValue[i] = copy.copy(oValue[i]);
     
    295336        return (oNewValue, sError);
    296337
    297     def _validateAndConvertWorker(self, asAllowNullAttributes, oDb):
     338    def _validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor = ksValidateFor_Other):
    298339        """
    299340        Worker for implementing validateAndConvert().
     
    312353            if sError is not None:
    313354                dErrors[sParam] = sError;
     355
     356        # Check the NULL requirements of the primary ID(s) for the 'add' and 'edit' actions.
     357        if   enmValidateFor == ModelDataBase.ksValidateFor_Add \
     358          or enmValidateFor == ModelDataBase.ksValidateFor_AddForeignId \
     359          or enmValidateFor == ModelDataBase.ksValidateFor_Edit:
     360            fMustBeNull = enmValidateFor == ModelDataBase.ksValidateFor_Add;
     361            sAttr = getattr(self, 'ksIdAttr', None);
     362            if sAttr is not None:
     363                oValue = getattr(self, sAttr);
     364                if (oValue is None) != fMustBeNull:
     365                    sParam = getattr(self, 'ksParam_' + sAttr);
     366                    sErrMsg = 'Must be NULL!' if fMustBeNull else 'Must not be NULL!'
     367                    if sParam in dErrors:
     368                        dErrors[sParam] += ' ' + sErrMsg;
     369                    else:
     370                        dErrors[sParam]  = sErrMsg;
     371
    314372        return dErrors;
    315373
    316     def validateAndConvert(self, oDb):
     374    def validateAndConvert(self, oDb, enmValidateFor = ksValidateFor_Other):
    317375        """
    318376        Validates the input and converts valid fields to their right type.
     
    328386            kasValidValues_enmAttr, and kasAllowNullAttributes.
    329387        """
    330         return self._validateAndConvertWorker(getattr(self, 'kasAllowNullAttributes', list()), oDb);
     388        return self._validateAndConvertWorker(getattr(self, 'kasAllowNullAttributes', list()), oDb,
     389                                              enmValidateFor = enmValidateFor);
    331390
    332391    def convertParamToAttribute(self, sAttr, sParam, oValue, oDisp, fStrict):
     
    402461        if isinstance(oValue1, list) and isinstance(oValue2, list):
    403462            if len(oValue1) == len(oValue2):
    404                 for i in range(len(oValue1)):
     463                for i, _ in enumerate(oValue1):
    405464                    if   not isinstance(oValue1[i], ModelDataBase) \
    406                       or type(oValue1) != type(oValue2):
     465                      or type(oValue1) is not type(oValue2):
    407466                        return False;
    408467                    if not oValue1[i].isEqual(oValue2[i]):
     
    411470
    412471        elif  isinstance(oValue1, ModelDataBase) \
    413           and type(oValue1) == type(oValue2):
     472          and type(oValue1) is type(oValue2):
    414473            return oValue1[i].isEqual(oValue2[i]);
    415474
     
    678737            oType = type(asValues[0]);
    679738            for i in range(1, len(asValues)):
    680                 if type(asValues[i]) is not oType:
     739                if type(asValues[i]) is not oType: # pylint: disable=C0123
    681740                    return (asValues, 'Invalid entry data type ([0]=%s vs [%d]=%s).' % (oType, i, type(asValues[i])) );
    682741
     
    719778
    720779        if sError is None  and asValues not in aoNilValues  and  len(asValues) > 0:
    721             for i in range(len(asValues)):
     780            for i, _ in enumerate(asValues):
    722781                sValue = asValues[i];
    723782
     
    10771136            self.assertIsNotNone(oSample.toString());
    10781137
    1079 # pylint: enable=E1101,C0111,R0903
    1080 
    10811138
    10821139class ModelLogicBase(ModelBase): # pylint: disable=R0903
  • trunk/src/VBox/ValidationKit/testmanager/core/build.py

    r56295 r61220  
    3737from testmanager                        import config;
    3838from testmanager.core                   import coreconsts;
    39 from testmanager.core.base              import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase;
     39from testmanager.core.base              import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase, \
     40                                               TMTooManyRows, TMInvalidData, TMRowNotFound, TMRowInUse;
    4041
    4142
     
    7677        """
    7778        if aoRow is None:
    78             raise TMExceptionBase('BuildCategory not found.');
     79            raise TMRowNotFound('BuildCategory not found.');
    7980
    8081        self.idBuildCategory     = aoRow[0];
     
    9495        aoRow = oDb.fetchOne()
    9596        if aoRow is None:
    96             raise TMExceptionBase('idBuildCategory=%s not found' % (idBuildCategory, ));
     97            raise TMRowNotFound('idBuildCategory=%s not found' % (idBuildCategory, ));
    9798        return self.initFromDbRow(aoRow);
    9899
     
    220221        cBuilds = self._oDb.fetchOne()[0];
    221222        if cBuilds > 0:
    222             raise TMExceptionBase('Build category #%d is used by %d builds and can therefore not be deleted.'
    223                                   % (idBuildCategory, cBuilds,));
     223            raise TMRowInUse('Build category #%d is used by %d builds and can therefore not be deleted.'
     224                             % (idBuildCategory, cBuilds,));
    224225
    225226        #
     
    294295
    295296        # Check BuildCategoryData before do anything
    296         dDataErrors = oData.validateAndConvert(self._oDb);
     297        dDataErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add);
    297298        if len(dDataErrors) > 0:
    298             raise TMExceptionBase('Invalid data passed to addBuildCategory(): %s' % (dDataErrors,));
     299            raise TMInvalidData('Invalid data passed to addBuildCategory(): %s' % (dDataErrors,));
    299300
    300301        # Does it already exist?
     
    363364        """
    364365        if aoRow is None:
    365             raise TMExceptionBase('Build not found.');
     366            raise TMRowNotFound('Build not found.');
    366367
    367368        self.idBuild            = aoRow[0];
     
    389390        aoRow = oDb.fetchOne()
    390391        if aoRow is None:
    391             raise TMExceptionBase('idBuild=%s not found (tsNow=%s sPeriodBack=%s)' % (idBuild, tsNow, sPeriodBack,));
     392            raise TMRowNotFound('idBuild=%s not found (tsNow=%s sPeriodBack=%s)' % (idBuild, tsNow, sPeriodBack,));
    392393        return self.initFromDbRow(aoRow);
    393394
     
    443444        """
    444445        if aoRow is None:
    445             raise TMExceptionBase('Build not found.');
     446            raise TMRowNotFound('Build not found.');
    446447        BuildData.initFromDbRow(self, aoRow);
    447448        self.oCat = BuildCategoryData().initFromDbRow(aoRow[11:]);
     
    461462        aoRow = oDb.fetchOne()
    462463        if aoRow is None:
    463             raise TMExceptionBase('idBuild=%s not found (tsNow=%s sPeriodBack=%s)' % (idBuild, tsNow, sPeriodBack,));
     464            raise TMRowNotFound('idBuild=%s not found (tsNow=%s sPeriodBack=%s)' % (idBuild, tsNow, sPeriodBack,));
    464465        return self.initFromDbRow(aoRow);
    465466
     
    556557        # Validate input and get current data.
    557558        #
    558         dErrors = oData.validateAndConvert(self._oDb);
     559        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
    559560        if len(dErrors) > 0:
    560             raise TMExceptionBase('editEntry invalid input: %s' % (dErrors,));
     561            raise TMInvalidData('editEntry invalid input: %s' % (dErrors,));
    561562        oOldData = BuildData().initFromDbWithId(self._oDb, oData.idBuild);
    562563
     
    714715        aRows = self._oDb.fetchAll()
    715716        if len(aRows) not in (0, 1):
    716             raise TMExceptionBase('Found more than one build with the same credentials. Database structure is corrupted.')
     717            raise TMTooManyRows('Found more than one build with the same credentials. Database structure is corrupted.')
    717718        try:
    718719            return BuildDataEx().initFromDbRow(aRows[0])
  • trunk/src/VBox/ValidationKit/testmanager/core/buildblacklist.py

    r56295 r61220  
    3131
    3232# Validation Kit imports.
    33 from testmanager.core.base          import ModelDataBase, ModelLogicBase, TMExceptionBase
     33from testmanager.core.base          import ModelDataBase, ModelLogicBase, TMInvalidData, TMRowNotFound;
    3434
    3535
     
    8787
    8888        if aoRow is None:
    89             raise TMExceptionBase('Build Blacklist item not found.')
     89            raise TMRowNotFound('Build Blacklist item not found.')
    9090
    9191        self.idBlacklisting  = aoRow[0]
     
    114114        aoRow = oDb.fetchOne()
    115115        if aoRow is None:
    116             raise TMExceptionBase('idBlacklisting=%s not found (tsNow=%s sPeriodBack=%s)'
    117                                   % (idBlacklisting, tsNow, sPeriodBack,));
     116            raise TMRowNotFound('idBlacklisting=%s not found (tsNow=%s sPeriodBack=%s)'
     117                                % (idBlacklisting, tsNow, sPeriodBack,));
    118118        return self.initFromDbRow(aoRow);
    119119
     
    187187        #
    188188        assert isinstance(oData, BuildBlacklistData);
    189         dErrors = oData.validateAndConvert(self._oDb);
     189        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
    190190        if len(dErrors) > 0:
    191             raise TMExceptionBase('editEntry invalid input: %s' % (dErrors,));
     191            raise TMInvalidData('editEntry invalid input: %s' % (dErrors,));
    192192
    193193        oOldData = BuildBlacklistData().initFromDbWithId(self._oDb, oData.idBlacklisting);
  • trunk/src/VBox/ValidationKit/testmanager/core/buildsource.py

    r56295 r61220  
    3535# Validation Kit imports.
    3636from common                             import utils;
    37 from testmanager.core.base              import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase;
     37from testmanager.core.base              import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMRowAlreadyExists, \
     38                                               TMRowInUse, TMInvalidData, TMRowNotFound;
    3839from testmanager.core                   import coreconsts;
    3940
     
    9091        """
    9192        if aoRow is None:
    92             raise TMExceptionBase('Build source not found.');
     93            raise TMRowNotFound('Build source not found.');
    9394
    9495        self.idBuildSrc         = aoRow[0];
     
    118119        aoRow = oDb.fetchOne()
    119120        if aoRow is None:
    120             raise TMExceptionBase('idBuildSrc=%s not found (tsNow=%s sPeriodBack=%s)' % (idBuildSrc, tsNow, sPeriodBack,));
     121            raise TMRowNotFound('idBuildSrc=%s not found (tsNow=%s sPeriodBack=%s)' % (idBuildSrc, tsNow, sPeriodBack,));
    121122        return self.initFromDbRow(aoRow);
    122123
     
    205206        # Validate the input.
    206207        #
    207         dErrors = oData.validateAndConvert(self._oDb);
     208        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add);
    208209        if len(dErrors) > 0:
    209             raise TMExceptionBase('addEntry invalid input: %s' % (dErrors,));
     210            raise TMInvalidData('addEntry invalid input: %s' % (dErrors,));
    210211        self._assertUnique(oData, None);
    211212
     
    247248        # Validate the input and read the old entry.
    248249        #
    249         dErrors = oData.validateAndConvert(self._oDb);
     250        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
    250251        if len(dErrors) > 0:
    251             raise TMExceptionBase('addEntry invalid input: %s' % (dErrors,));
     252            raise TMInvalidData('addEntry invalid input: %s' % (dErrors,));
    252253        self._assertUnique(oData, oData.idBuildSrc);
    253254        oOldData = BuildSourceData().initFromDbWithId(self._oDb, oData.idBuildSrc);
     
    303304                for aoRow in self._oDb.fetchAll():
    304305                    asGroups.append('%s (#%d)' % (aoRow[1], aoRow[0]));
    305                 raise TMExceptionBase('Build source #%d is used by one or more scheduling groups: %s'
    306                                       % (idBuildSrc, ', '.join(asGroups),));
     306                raise TMRowInUse('Build source #%d is used by one or more scheduling groups: %s'
     307                                 % (idBuildSrc, ', '.join(asGroups),));
    307308        else:
    308309            self._oDb.execute('UPDATE   SchedGroups\n'
     
    435436                          , ( oData.sName, ))
    436437        if self._oDb.getRowCount() > 0:
    437             raise TMExceptionBase('A build source with name "%s" already exist.' % (oData.sName,));
     438            raise TMRowAlreadyExists('A build source with name "%s" already exist.' % (oData.sName,));
    438439        return True;
    439440
  • trunk/src/VBox/ValidationKit/testmanager/core/dbobjcache.py

    r56295 r61220  
    7676    def _handleDbException(self):
    7777        """ Deals with database exceptions. """
    78         raise;
    7978        #self._oDb.rollback();
    80         #return False;
     79        return False;
    8180
    8281    def getTestResultString(self, idStrName):
     
    9897            oRet = BuildCategoryData();
    9998            try:    oRet.initFromDbWithId(self._oDb, idBuildCategory);
    100             except: self._handleDbException();
     99            except: self._handleDbException(); raise;
    101100            self._adCache[self.ksObjType_BuildCategory_idBuildCategory][idBuildCategory] = oRet;
    102101        return oRet;
     
    110109            oRet = TestBoxData();
    111110            try:    oRet.initFromDbWithId(self._oDb, idTestBox, self.tsNow, self.sPeriodBack);
    112             except: self._handleDbException();
     111            except: self._handleDbException(); raise;
    113112            else:   self._adCache[self.ksObjType_TestBox_idGenTestBox][oRet.idGenTestBox] = oRet;
    114113            self._adCache[self.ksObjType_TestBox_idTestBox][idTestBox] = oRet;
     
    123122            oRet = TestCaseData();
    124123            try:    oRet.initFromDbWithId(self._oDb, idTestCase, self.tsNow, self.sPeriodBack);
    125             except: self._handleDbException();
     124            except: self._handleDbException(); raise;
    126125            else:   self._adCache[self.ksObjType_TestCase_idGenTestCase][oRet.idGenTestCase] = oRet;
    127126            self._adCache[self.ksObjType_TestCase_idTestCase][idTestCase] = oRet;
     
    136135            oRet = TestCaseArgsData();
    137136            try:    oRet.initFromDbWithId(self._oDb, idTestCaseArgs, self.tsNow, self.sPeriodBack);
    138             except: self._handleDbException();
     137            except: self._handleDbException(); raise;
    139138            else:   self._adCache[self.ksObjType_TestCaseArgs_idGenTestCaseArgs][oRet.idGenTestCaseArgs] = oRet;
    140139            self._adCache[self.ksObjType_TestCaseArgs_idTestCaseArgs][idTestCaseArgs] = oRet;
  • trunk/src/VBox/ValidationKit/testmanager/core/failurecategory.py

    r61217 r61220  
    3131
    3232# Validation Kit imports.
    33 from testmanager.core.base          import ModelDataBase, ModelLogicBase, TMExceptionBase
    34 from testmanager.core.failurereason import FailureReasonLogic
     33from testmanager.core.base          import ModelDataBase, ModelLogicBase, TMRowInUse, TMInvalidData, TMRowNotFound;
     34
    3535
    3636class FailureCategoryData(ModelDataBase):
     
    3838    Failure Category Data.
    3939    """
     40
     41    ksIdAttr = 'idFailureCategory';
    4042
    4143    ksParam_idFailureCategory = 'FailureCategory_idFailureCategory'
     
    7173
    7274        if aoRow is None:
    73             raise TMExceptionBase('Failure Category not found.');
     75            raise TMRowNotFound('Failure Category not found.');
    7476
    7577        self.idFailureCategory = aoRow[0]
     
    8183
    8284        return self
     85
     86    def initFromDbWithId(self, oDb, idFailureCategory, tsNow = None, sPeriodBack = None):
     87        """
     88        Initialize from the database, given the ID of a row.
     89        """
     90        oDb.execute(self.formatSimpleNowAndPeriodQuery(oDb,
     91                                                       'SELECT *\n'
     92                                                       'FROM   FailureCategories\n'
     93                                                       'WHERE  idFailureCategory = %s\n'
     94                                                       , ( idFailureCategory,), tsNow, sPeriodBack));
     95        aoRow = oDb.fetchOne()
     96        if aoRow is None:
     97            raise TMRowNotFound('idFailureCategory=%s not found (tsNow=%s sPeriodBack=%s)'
     98                                % (idFailureCategory, tsNow, sPeriodBack,));
     99        return self.initFromDbRow(aoRow);
    83100
    84101
     
    158175            return None
    159176
    160     def addEntry(self, oFailureCategoryData, uidAuthor, fCommit=True):
    161         """
    162         Add Failure Category record
    163         """
    164 
    165         # Check if record with the same sShort fiels is already exists
    166         self._oDb.execute('SELECT *\n'
    167                           'FROM   FailureCategories\n'
    168                           'WHERE  tsExpire   = \'infinity\'::TIMESTAMP\n'
    169                           '   AND sShort = %s\n',
    170                           (oFailureCategoryData.sShort,))
    171         if len(self._oDb.fetchAll()) != 0:
    172             raise Exception('Record already exist')
    173 
    174         # Add record
    175         self._oDb.execute('INSERT INTO FailureCategories (\n'
    176                           '  uidAuthor, sShort, sFull'
    177                           ')\n'
    178                           'VALUES (%s, %s, %s)',
    179                           (uidAuthor,
    180                            oFailureCategoryData.sShort,
    181                            oFailureCategoryData.sFull))
    182         if fCommit:
    183             self._oDb.commit()
    184 
    185         return True
    186 
    187     def remove(self, uidAuthor, idFailureCategory, fNeedCommit=True):
    188         """
    189         Historize record
    190         """
    191 
    192         # Historize Failure Reasons records first
    193         self._oDb.execute('SELECT idFailureReason\n'
    194                           'FROM   FailureReasons\n'
    195                           'WHERE  idFailureCategory = %s\n'
    196                           '   AND tsExpire    = \'infinity\'::TIMESTAMP\n',
    197                           (idFailureCategory,))
    198         for iFailureReasonId in self._oDb.fetchAll():
    199             FailureReasonLogic(self._oDb).remove(uidAuthor, iFailureReasonId, fNeedCommit = False)
    200 
    201         self._oDb.execute('UPDATE FailureCategories\n'
    202                           'SET    tsExpire    = CURRENT_TIMESTAMP,\n'
    203                           '       uidAuthor   = %s\n'
    204                           'WHERE  idFailureCategory = %s\n'
    205                           '   AND tsExpire    = \'infinity\'::TIMESTAMP\n',
    206                           (uidAuthor, idFailureCategory))
    207 
    208         if fNeedCommit:
    209             self._oDb.commit()
    210 
    211         return True
    212 
    213     def editEntry(self, oFailureCategoryData, uidAuthor, fCommit=True):
    214         """Modify database record"""
    215 
    216         # Check if record exists
    217         oFailureCategoryDataOld = self.getById(oFailureCategoryData.idFailureCategory)
    218         if oFailureCategoryDataOld is None:
    219             raise TMExceptionBase(
    220                 'Failure Category (id: %d) does not exist'
    221                 % oFailureCategoryData.idFailureCategory)
    222 
    223         # Check if anything has been changed
    224         if oFailureCategoryData.isEqual(oFailureCategoryDataOld):
    225             return True
    226 
    227         # Historize record
    228         self.remove(
    229             uidAuthor, oFailureCategoryData.idFailureCategory, fNeedCommit=False)
    230 
    231         self._oDb.execute('INSERT INTO FailureCategories (\n'
    232                           '  idFailureCategory, uidAuthor, sShort, sFull'
    233                           ')\n'
    234                           'VALUES (%s, %s, %s, %s)',
    235                           (oFailureCategoryData.idFailureCategory,
    236                            uidAuthor,
    237                            oFailureCategoryData.sShort,
    238                            oFailureCategoryData.sFull))
    239         if fCommit:
    240             self._oDb.commit()
    241 
    242         return True
     177
     178    def addEntry(self, oData, uidAuthor, fCommit = False):
     179        """
     180        Add a failure reason category.
     181        """
     182        #
     183        # Validate inputs and read in the old(/current) data.
     184        #
     185        assert isinstance(oData, FailureCategoryData);
     186        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add);
     187        if len(dErrors) > 0:
     188            raise TMInvalidData('editEntry invalid input: %s' % (dErrors,));
     189
     190        #
     191        # Add the record.
     192        #
     193        self._readdEntry(uidAuthor, oData);
     194        self._oDb.maybeCommit(fCommit);
     195        return True;
     196
     197
     198    def editEntry(self, oData, uidAuthor, fCommit = False):
     199        """
     200        Modifies a failure reason category.
     201        """
     202
     203        #
     204        # Validate inputs and read in the old(/current) data.
     205        #
     206        assert isinstance(oData, FailureCategoryData);
     207        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
     208        if len(dErrors) > 0:
     209            raise TMInvalidData('editEntry invalid input: %s' % (dErrors,));
     210
     211        oOldData = FailureCategoryData().initFromDbWithId(self._oDb, oData.idFailureCategory);
     212
     213        #
     214        # Update the data that needs updating.
     215        #
     216        if not oData.isEqualEx(oOldData, [ 'tsEffective', 'tsExpire', 'uidAuthor', ]):
     217            self._historizeEntry(oData.idFailureCategory);
     218            self._readdEntry(uidAuthor, oData);
     219        self._oDb.maybeCommit(fCommit);
     220        return True;
     221
     222
     223    def removeEntry(self, uidAuthor, idFailureCategory, fCascade = False, fCommit = False):
     224        """
     225        Deletes a failure reason category.
     226        """
     227        _ = fCascade; # too complicated for now.
     228
     229        #
     230        # Check whether it's being used by other tables and bitch if it is .
     231        # We currently do not implement cascading.
     232        #
     233        self._oDb.execute('SELECT   CONCAT(idFailureReason, \' - \', sShort)\n'
     234                          'FROM     FailureReasons\n'
     235                          'WHERE    idFailureCategory = %s\n'
     236                          '    AND  tsExpire = \'infinity\'::TIMESTAMP\n'
     237                          , (idFailureCategory,));
     238        aaoRows = self._oDb.fetchAll();
     239        if len(aaoRows) > 0:
     240            raise TMRowInUse('Cannot remove failure reason category %u because its being used by: %s'
     241                             % (idFailureCategory, ', '.join(aoRow[0] for aoRow in aaoRows),));
     242
     243        #
     244        # Do the job.
     245        #
     246        oData = FailureCategoryData().initFromDbWithId(self._oDb, idFailureCategory);
     247        (tsCur, tsCurMinusOne) = self._oDb.getCurrentTimestamps();
     248        if oData.tsEffective != tsCur and oData.tsEffective != tsCurMinusOne:
     249            self._historizeEntry(idFailureCategory, tsCurMinusOne);
     250            self._readdEntry(uidAuthor, oData, tsCurMinusOne);
     251        self._historizeEntry(idFailureCategory);
     252        self._oDb.maybeCommit(fCommit);
     253        return True;
     254
    243255
    244256    def cachedLookup(self, idFailureCategory):
     
    276288        return oEntry;
    277289
     290
     291    #
     292    # Helpers.
     293    #
     294
     295    def _readdEntry(self, uidAuthor, oData, tsEffective = None):
     296        """
     297        Re-adds the FailureCategories entry. Used by addEntry, editEntry and removeEntry.
     298        """
     299        if tsEffective is None:
     300            tsEffective = self._oDb.getCurrentTimestamp();
     301        self._oDb.execute('INSERT INTO FailureCategories (\n'
     302                          '         uidAuthor,\n'
     303                          '         tsEffective,\n'
     304                          '         idFailureCategory,\n'
     305                          '         sShort,\n'
     306                          '         sFull)\n'
     307                          'VALUES (%s, %s, '
     308                          + ('DEFAULT' if oData.idFailureCategory is None else str(oData.idFailureCategory))
     309                          + ', %s, %s)\n'
     310                          , ( uidAuthor,
     311                              tsEffective,
     312                              oData.sShort,
     313                              oData.sFull,) );
     314        return True;
     315
     316
     317    def _historizeEntry(self, idFailureCategory, tsExpire = None):
     318        """ Historizes the current entry. """
     319        if tsExpire is None:
     320            tsExpire = self._oDb.getCurrentTimestamp();
     321        self._oDb.execute('UPDATE FailureCategories\n'
     322                          'SET    tsExpire   = %s\n'
     323                          'WHERE  idFailureCategory = %s\n'
     324                          '   AND tsExpire          = \'infinity\'::TIMESTAMP\n'
     325                          , (tsExpire, idFailureCategory,));
     326        return True;
     327
     328
  • trunk/src/VBox/ValidationKit/testmanager/core/failurereason.py

    r61217 r61220  
    3131
    3232# Validation Kit imports.
    33 from testmanager.core.base              import ModelDataBase, ModelLogicBase, TMExceptionBase
     33from testmanager.core.base              import ModelDataBase, ModelLogicBase, TMRowNotFound, TMInvalidData, TMRowInUse;
    3434from testmanager.core.useraccount       import UserAccountLogic;
    3535
     
    8282
    8383        if aoRow is None:
    84             raise TMExceptionBase('Failure Reason not found.');
     84            raise TMRowNotFound('Failure Reason not found.');
    8585
    8686        self.idFailureReason   = aoRow[0]
     
    9595
    9696        return self;
     97
     98    def initFromDbWithId(self, oDb, idFailureReason, tsNow = None, sPeriodBack = None):
     99        """
     100        Initialize from the database, given the ID of a row.
     101        """
     102        oDb.execute(self.formatSimpleNowAndPeriodQuery(oDb,
     103                                                       'SELECT *\n'
     104                                                       'FROM   FailureReasons\n'
     105                                                       'WHERE  idFailureReason = %s\n'
     106                                                       , ( idFailureReason,), tsNow, sPeriodBack));
     107        aoRow = oDb.fetchOne()
     108        if aoRow is None:
     109            raise TMRowNotFound('idFailureReason=%s not found (tsNow=%s sPeriodBack=%s)'
     110                                % (idFailureReason, tsNow, sPeriodBack,));
     111        return self.initFromDbRow(aoRow);
    97112
    98113
     
    205220            return None
    206221
    207     def getIdsByCategory(self, idFailureCategory, tsEffective=None):
    208         """
    209         Gets the list of Failure Ressons IDs,
    210         all the items belong to @param idFailureCategory
    211         """
    212         if tsEffective is None:
    213             self._oDb.execute('SELECT   idFailureReason\n'
    214                               'FROM     FailureReasons\n'
    215                               'WHERE    tsExpire = \'infinity\'::TIMESTAMP\n'
    216                               '     AND idFailureCategory = %s\n'
    217                               'ORDER BY idFailureReason DESC'
    218                               , (idFailureCategory,))
    219         else:
    220             self._oDb.execute('SELECT   idFailureReason\n'
    221                               'FROM     FailureReasons\n'
    222                               'WHERE    tsExpire     > %s\n'
    223                               '     AND tsEffective <= %s\n'
    224                               '     AND idFailureCategory = %s\n'
    225                               'ORDER BY idFailureReason DESC'
    226                               , (tsEffective, tsEffective, idFailureCategory))
    227         return self._oDb.fetchAll()
    228 
    229     def getAll(self, tsEffective=None):
    230         """
    231         Gets the list of all Failure Reasons.
    232         Returns an array of FailureReasonData instances.
    233         """
    234         if tsEffective is None:
    235             self._oDb.execute('SELECT   *\n'
    236                               'FROM     FailureReasons\n'
    237                               'WHERE    tsExpire = \'infinity\'::TIMESTAMP\n'
    238                               'ORDER BY idFailureReason DESC')
    239         else:
    240             self._oDb.execute('SELECT   *\n'
    241                               'FROM     FailureReasons\n'
    242                               'WHERE    tsExpire     > %s\n'
    243                               '     AND tsEffective <= %s\n'
    244                               'ORDER BY idFailureReason DESC'
    245                               , (tsEffective, tsEffective))
    246         aoRet = []
    247         for aoRow in self._oDb.fetchAll():
    248             aoRet.append(FailureReasonData().initFromDbRow(aoRow))
    249         return aoRet
    250 
    251     def addEntry(self, oFailureReasonData, uidAuthor, fCommit=True):
    252         """Add record to database"""
    253 
    254         # Check if record with the same sShort fiels is already exists
    255         self._oDb.execute('SELECT *\n'
    256                           'FROM   FailureReasons\n'
    257                           'WHERE  tsExpire   = \'infinity\'::TIMESTAMP\n'
    258                           '   AND sShort = %s\n',
    259                           (oFailureReasonData.sShort,))
    260         if len(self._oDb.fetchAll()) != 0:
    261             raise Exception('Record already exist')
    262 
    263         # Add record
    264         self._oDb.execute('INSERT INTO FailureReasons (\n'
    265                           '  uidAuthor, idFailureCategory,'
    266                           '  sShort, sFull, iTicket, asUrls'
    267                           ')\n'
    268                           'VALUES (%s, %s, %s, %s, %s, %s)',
    269                           (uidAuthor,
    270                            oFailureReasonData.idFailureCategory,
    271                            oFailureReasonData.sShort,
    272                            oFailureReasonData.sFull,
    273                            oFailureReasonData.iTicket,
    274                            oFailureReasonData.asUrls))
    275         if fCommit:
    276             self._oDb.commit()
    277 
    278         return True
    279 
    280     def remove(self, uidAuthor, idFailureReason, fNeedCommit=True):
    281         """
    282         Historize record
    283         """
    284         self._oDb.execute('UPDATE FailureReasons\n'
    285                           'SET    tsExpire    = CURRENT_TIMESTAMP,\n'
    286                           '       uidAuthor   = %s\n'
    287                           'WHERE  idFailureReason = %s\n'
    288                           '   AND tsExpire    = \'infinity\'::TIMESTAMP\n',
    289                           (uidAuthor, idFailureReason))
    290 
    291         # Also historize Black List records
    292         self._oDb.execute('UPDATE BuildBlackList\n'
    293                           'SET    tsExpire    = CURRENT_TIMESTAMP,\n'
    294                           '       uidAuthor   = %s\n'
    295                           'WHERE  idFailureReason = %s\n'
    296                           '   AND tsExpire    = \'infinity\'::TIMESTAMP\n',
    297                           (uidAuthor, idFailureReason))
    298 
    299         if fNeedCommit:
    300             self._oDb.commit()
    301 
    302         return True
    303 
    304     def editEntry(self, oFailureReasonData, uidAuthor, fCommit=True):
    305         """Modify database record"""
    306 
    307         # Check if record exists
    308         oFailureReasonDataOld = self.getById(oFailureReasonData.idFailureReason)
    309         if oFailureReasonDataOld is None:
    310             raise TMExceptionBase(
    311                 'Failure Reason (id: %d) does not exist'
    312                 % oFailureReasonData.idFailureReason)
    313 
    314         # Check if anything has been changed
    315         if oFailureReasonData.isEqual(oFailureReasonDataOld):
    316             return True
    317 
    318         # Historize record
    319         self.remove(
    320             uidAuthor, oFailureReasonData.idFailureReason, fNeedCommit=False)
    321 
    322 
    323         # Add new record (keeping its ID)
    324         self._oDb.execute('INSERT INTO FailureReasons (\n'
    325                           '  idFailureReason,'
    326                           '  uidAuthor,'
    327                           '  idFailureCategory,'
    328                           '  sShort,'
    329                           '  sFull,'
    330                           '  iTicket,'
    331                           '  asUrls'
    332                           ')\n'
    333                           'VALUES (%s, %s, %s, %s, %s, %s, %s)',
    334                           (oFailureReasonData.idFailureReason,
    335                            uidAuthor,
    336                            oFailureReasonData.idFailureCategory,
    337                            oFailureReasonData.sShort,
    338                            oFailureReasonData.sFull,
    339                            oFailureReasonData.iTicket,
    340                            oFailureReasonData.asUrls
    341                            ))
    342 
    343         if fCommit:
    344             self._oDb.commit()
    345 
    346         return True
     222
     223    def addEntry(self, oData, uidAuthor, fCommit = False):
     224        """
     225        Add a failure reason.
     226        """
     227        #
     228        # Validate.
     229        #
     230        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add);
     231        if len(dErrors) > 0:
     232            raise TMInvalidData('addEntry invalid input: %s' % (dErrors,));
     233
     234        #
     235        # Add the record.
     236        #
     237        self._readdEntry(uidAuthor, oData);
     238        self._oDb.maybeCommit(fCommit);
     239        return True;
     240
     241
     242    def editEntry(self, oData, uidAuthor, fCommit = False):
     243        """
     244        Modifies a failure reason.
     245        """
     246
     247        #
     248        # Validate inputs and read in the old(/current) data.
     249        #
     250        assert isinstance(oData, FailureReasonData);
     251        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
     252        if len(dErrors) > 0:
     253            raise TMInvalidData('editEntry invalid input: %s' % (dErrors,));
     254
     255        oOldData = FailureReasonData().initFromDbWithId(self._oDb, oData.idFailureReason);
     256
     257        #
     258        # Update the data that needs updating.
     259        #
     260        if not oData.isEqualEx(oOldData, [ 'tsEffective', 'tsExpire', 'uidAuthor', ]):
     261            self._historizeEntry(oData.idFailureReason);
     262            self._readdEntry(uidAuthor, oData);
     263        self._oDb.maybeCommit(fCommit);
     264        return True;
     265
     266
     267    def removeEntry(self, uidAuthor, idFailureReason, fCascade = False, fCommit = False):
     268        """
     269        Deletes a failure reason.
     270        """
     271        _ = fCascade; # too complicated for now.
     272
     273        #
     274        # Check whether it's being used by other tables and bitch if it is .
     275        # We currently do not implement cascading.
     276        #
     277        self._oDb.execute('SELECT   CONCAT(idBlacklisting, \' - blacklisting\')\n'
     278                          'FROM     BuildBlacklist\n'
     279                          'WHERE    idFailureReason = %s\n'
     280                          '    AND  tsExpire = \'infinity\'::TIMESTAMP\n'
     281                          'UNION\n'
     282                          'SELECT   CONCAT(idTestResult, \' - test result failure reason\')\n'
     283                          'FROM     TestResultFailures\n'
     284                          'WHERE    idFailureReason = %s\n'
     285                          '    AND  tsExpire = \'infinity\'::TIMESTAMP\n'
     286                          , (idFailureReason, idFailureReason,));
     287        aaoRows = self._oDb.fetchAll();
     288        if len(aaoRows) > 0:
     289            raise TMRowInUse('Cannot remove failure reason %u because its being used by: %s'
     290                             % (idFailureReason, ', '.join(aoRow[0] for aoRow in aaoRows),));
     291
     292        #
     293        # Do the job.
     294        #
     295        oData = FailureReasonData().initFromDbWithId(self._oDb, idFailureReason);
     296        assert oData.idFailureReason == idFailureReason;
     297        (tsCur, tsCurMinusOne) = self._oDb.getCurrentTimestamps();
     298        if oData.tsEffective != tsCur and oData.tsEffective != tsCurMinusOne:
     299            self._historizeEntry(idFailureReason, tsCurMinusOne);
     300            self._readdEntry(uidAuthor, oData, tsCurMinusOne);
     301        self._historizeEntry(idFailureReason);
     302        self._oDb.maybeCommit(fCommit);
     303        return True;
     304
    347305
    348306    def cachedLookup(self, idFailureReason):
     
    385343        return oEntry;
    386344
     345    #
     346    # Helpers.
     347    #
     348
     349    def _readdEntry(self, uidAuthor, oData, tsEffective = None):
     350        """
     351        Re-adds the FailureReasons entry. Used by addEntry, editEntry and removeEntry.
     352        """
     353        if tsEffective is None:
     354            tsEffective = self._oDb.getCurrentTimestamp();
     355        self._oDb.execute('INSERT INTO FailureReasons (\n'
     356                          '         uidAuthor,\n'
     357                          '         tsEffective,\n'
     358                          '         idFailureReason,\n'
     359                          '         idFailureCategory,\n'
     360                          '         sShort,\n'
     361                          '         sFull,\n'
     362                          '         iTicket,\n'
     363                          '         asUrls)\n'
     364                          'VALUES (%s, %s, '
     365                          + ( 'DEFAULT' if oData.idFailureReason is None else str(oData.idFailureReason) )
     366                          + ', %s, %s, %s, %s, %s)\n'
     367                          , ( uidAuthor,
     368                              tsEffective,
     369                              oData.idFailureCategory,
     370                              oData.sShort,
     371                              oData.sFull,
     372                              oData.iTicket,
     373                              oData.asUrls,) );
     374        return True;
     375
     376
     377    def _historizeEntry(self, idFailureReason, tsExpire = None):
     378        """ Historizes the current entry. """
     379        if tsExpire is None:
     380            tsExpire = self._oDb.getCurrentTimestamp();
     381        self._oDb.execute('UPDATE FailureReasons\n'
     382                          'SET    tsExpire   = %s\n'
     383                          'WHERE  idFailureReason = %s\n'
     384                          '   AND tsExpire        = \'infinity\'::TIMESTAMP\n'
     385                          , (tsExpire, idFailureReason,));
     386        return True;
     387
  • trunk/src/VBox/ValidationKit/testmanager/core/globalresource.py

    r56295 r61220  
    3434
    3535# Validation Kit imports.
    36 from testmanager.core.base import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase;
     36from testmanager.core.base import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMRowNotFound;
    3737
    3838
     
    7777        """
    7878        if aoRow is None:
    79             raise TMExceptionBase('Global resource not found.')
     79            raise TMRowNotFound('Global resource not found.')
    8080
    8181        self.idGlobalRsrc       = aoRow[0]
     
    9999        aoRow = oDb.fetchOne()
    100100        if aoRow is None:
    101             raise TMExceptionBase('idGlobalRsrc=%s not found (tsNow=%s sPeriodBack=%s)' % (idGlobalRsrc, tsNow, sPeriodBack,));
     101            raise TMRowNotFound('idGlobalRsrc=%s not found (tsNow=%s sPeriodBack=%s)' % (idGlobalRsrc, tsNow, sPeriodBack,));
    102102        return self.initFromDbRow(aoRow);
    103103
     
    220220            return GlobalResourceData().initFromDbRow(aRows[0])
    221221        except IndexError:
    222             raise TMExceptionBase('Global resource not found.')
     222            raise TMRowNotFound('Global resource not found.')
    223223
    224224    def allocateResources(self, idTestBox, aoGlobalRsrcs, fCommit = False):
  • trunk/src/VBox/ValidationKit/testmanager/core/schedgroup.py

    r56295 r61220  
    3434
    3535# Validation Kit imports.
    36 from testmanager.core.base          import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase;
     36from testmanager.core.base          import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase, \
     37                                           TMRowInUse, TMInvalidData, TMRowAlreadyExists, TMRowNotFound;
    3738from testmanager.core.buildsource   import BuildSourceData;
    3839from testmanager.core.testcase      import TestCaseData;
     
    8990
    9091        if aoRow is None:
    91             raise TMExceptionBase('SchedGroupMember not found.');
     92            raise TMRowNotFound('SchedGroupMember not found.');
    9293
    9394        self.idSchedGroup        = aoRow[0];
     
    132133        return asAttributes;
    133134
    134     def _validateAndConvertWorker(self, asAllowNullAttributes, oDb):
    135         dErrors = SchedGroupMemberData._validateAndConvertWorker(self, asAllowNullAttributes, oDb);
     135    def _validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor = ModelDataBase.ksValidateFor_Other):
     136        dErrors = SchedGroupMemberData._validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor);
    136137        if self.ksParam_idTestGroup not in dErrors:
    137138            self.oTestGroup = TestGroupData();
     
    206207
    207208        if aoRow is None:
    208             raise TMExceptionBase('SchedGroup not found.');
     209            raise TMRowNotFound('SchedGroup not found.');
    209210
    210211        self.idSchedGroup            = aoRow[0];
     
    231232        aoRow = oDb.fetchOne()
    232233        if aoRow is None:
    233             raise TMExceptionBase('idSchedGroup=%s not found (tsNow=%s, sPeriodBack=%s)' % (idSchedGroup, tsNow, sPeriodBack));
     234            raise TMRowNotFound('idSchedGroup=%s not found (tsNow=%s, sPeriodBack=%s)' % (idSchedGroup, tsNow, sPeriodBack));
    234235        return self.initFromDbRow(aoRow);
    235236
     
    389390            aoNewMembers.append(oNewMember);
    390391
    391             dErrors = oNewMember.validateAndConvert(oDb);
     392            dErrors = oNewMember.validateAndConvert(oDb, ModelDataBase.ksValidateFor_Other);
    392393            if len(dErrors) > 0:
    393394                asErrors.append(str(dErrors));
    394395
    395396        if len(asErrors) == 0:
    396             for i in range(len(aoNewMembers)):
     397            for i, _ in enumerate(aoNewMembers):
    397398                idTestGroup = aoNewMembers[i];
    398399                for j in range(i + 1, len(aoNewMembers)):
     
    403404        return (aoNewMembers, None if len(asErrors) == 0 else '<br>\n'.join(asErrors));
    404405
    405     def _validateAndConvertWorker(self, asAllowNullAttributes, oDb):
    406         dErrors = SchedGroupData._validateAndConvertWorker(self, asAllowNullAttributes, oDb);
     406    def _validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor = ModelDataBase.ksValidateFor_Other):
     407        dErrors = SchedGroupData._validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor);
    407408
    408409        #
     
    479480        # Validate.
    480481        #
    481         dDataErrors = oData.validateAndConvert(self._oDb);
     482        dDataErrors = oData.validateAndConvert(self._oDb, idPrimaryMustBeNullOrNot = True);
    482483        if len(dDataErrors) > 0:
    483             raise TMExceptionBase('Invalid data passed to addEntry: %s' % (dDataErrors,));
     484            raise TMInvalidData('Invalid data passed to addEntry: %s' % (dDataErrors,));
    484485        if self.exists(oData.sName):
    485             raise TMExceptionBase('Scheduling group "%s" already exists.' % (oData.sName,));
     486            raise TMRowAlreadyExists('Scheduling group "%s" already exists.' % (oData.sName,));
    486487
    487488        #
     
    521522        # Validate input and retrieve the old data.
    522523        #
    523         dErrors = oData.validateAndConvert(self._oDb);
     524        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
    524525        if len(dErrors) > 0:
    525             raise TMExceptionBase('editEntry got invalid data: %s' % (dErrors,));
     526            raise TMInvalidData('editEntry got invalid data: %s' % (dErrors,));
    526527        self._assertUnique(oData.sName, oData.idSchedGroup);
    527528        oOldData = SchedGroupDataEx().initFromDbWithId(self._oDb, oData.idSchedGroup);
     
    572573        #
    573574        if idSchedGroup == 1:
    574             raise TMExceptionBase('Cannot remove the default scheduling group (id 1).');
     575            raise TMRowInUse('Cannot remove the default scheduling group (id 1).');
    575576        oData = SchedGroupDataEx().initFromDbWithId(self._oDb, idSchedGroup);
    576577
     
    583584                # Complain about there being associated testboxes.
    584585                asTestBoxes = ['%s (#%d)' % (oTestBox.sName, oTestBox.idTestBox) for oTestBox in oData.aoTestBoxes];
    585                 raise TMExceptionBase('Scheduling group #%d is associated with one or more test boxes: %s'
    586                                       % (idSchedGroup, ', '.join(asTestBoxes),));
     586                raise TMRowInUse('Scheduling group #%d is associated with one or more test boxes: %s'
     587                                 % (idSchedGroup, ', '.join(asTestBoxes),));
    587588            else:
    588589                # Reassign testboxes to scheduling group #1 (the default group).
     
    595596                oData = SchedGroupDataEx().initFromDbWithId(self._oDb, idSchedGroup);
    596597                if len(oData.aoTestBoxes) != 0:
    597                     raise TMExceptionBase('More testboxes was added to the scheduling group as we were trying to delete it.');
     598                    raise TMRowInUse('More testboxes was added to the scheduling group as we were trying to delete it.');
    598599
    599600        #
     
    859860                              , ( sName, idSchedGroupIgnore, ) );
    860861        if self._oDb.getRowCount() > 0:
    861             raise TMExceptionBase('Scheduling group name (%s) is already in use.' % (sName,));
     862            raise TMRowInUse('Scheduling group name (%s) is already in use.' % (sName,));
    862863        return True;
    863864
  • trunk/src/VBox/ValidationKit/testmanager/core/schedulerbase.py

    r56802 r61220  
    725725
    726726        sArgs = ' --gang-member-no %s --gang-members %s' % (oTestSet.iGangMemberNo, len(aoGangMembers));
    727         for i in range(len(aoGangMembers)):
     727        for i, _ in enumerate(aoGangMembers):
    728728            sArgs = ' --gang-ipv4-%s %s' % (i, aoGangMembers[i].ip); ## @todo IPv6
    729729
  • trunk/src/VBox/ValidationKit/testmanager/core/testbox.py

    r56295 r61220  
    3535# Validation Kit imports.
    3636from testmanager.core.base  import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase, \
    37                                    ChangeLogEntry, AttributeChangeEntry;
     37                                   TMInvalidData, TMTooManyRows, TMRowNotFound, ChangeLogEntry, AttributeChangeEntry;
    3838
    3939
     
    171171
    172172        if aoRow is None:
    173             raise TMExceptionBase('TestBox not found.');
     173            raise TMRowNotFound('TestBox not found.');
    174174
    175175        self.idTestBox           = aoRow[0];
     
    217217        aoRow = oDb.fetchOne()
    218218        if aoRow is None:
    219             raise TMExceptionBase('idTestBox=%s not found (tsNow=%s sPeriodBack=%s)' % (idTestBox, tsNow, sPeriodBack,));
     219            raise TMRowNotFound('idTestBox=%s not found (tsNow=%s sPeriodBack=%s)' % (idTestBox, tsNow, sPeriodBack,));
    220220        return self.initFromDbRow(aoRow);
    221221
     
    230230        return self.initFromDbRow(oDb.fetchOne());
    231231
    232     def _validateAndConvertWorker(self, asAllowNullAttributes, oDb):
     232    def _validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor = ModelDataBase.ksValidateFor_Other):
    233233        # Override to do extra ipLom checks.
    234         dErrors = ModelDataBase._validateAndConvertWorker(self, asAllowNullAttributes, oDb);
     234        dErrors = ModelDataBase._validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor);
    235235        if    self.ksParam_ipLom      not in dErrors \
    236236          and self.ksParam_enmLomKind not in dErrors \
     
    293293            return None;
    294294        if self._oDb.getRowCount() != 1:
    295             raise TMExceptionBase('Database integrity error: %u hits' % (self._oDb.getRowCount(),));
     295            raise TMTooManyRows('Database integrity error: %u hits' % (self._oDb.getRowCount(),));
    296296        oData = TestBoxData();
    297297        oData.initFromDbRow(self._oDb.fetchOne());
     
    397397        of the created testbox on success.  Throws error on failure.
    398398        """
    399         dDataErrors = oData.validateAndConvert(self._oDb);
     399        dDataErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add);
    400400        if len(dDataErrors) > 0:
    401             raise TMExceptionBase('Invalid data passed to create(): %s' % (dDataErrors,));
     401            raise TMInvalidData('Invalid data passed to create(): %s' % (dDataErrors,));
    402402
    403403        self._oDb.execute('INSERT INTO TestBoxes (\n'
     
    507507        """
    508508
    509         dDataErrors = oData.validateAndConvert(self._oDb);
     509        dDataErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
    510510        if len(dDataErrors) > 0:
    511             raise TMExceptionBase('Invalid data passed to create(): %s' % (dDataErrors,));
     511            raise TMInvalidData('Invalid data passed to create(): %s' % (dDataErrors,));
    512512
    513513        ## @todo check if the data changed.
  • trunk/src/VBox/ValidationKit/testmanager/core/testboxcontroller.py

    r57679 r61220  
    395395        # Update the row in TestBoxes if something changed.
    396396        #
     397        # pylint: disable=R0916
    397398        if   self._sTestBoxAddr != oTestBox.ip \
    398399          or sOs                != oTestBox.sOs \
  • trunk/src/VBox/ValidationKit/testmanager/core/testboxstatus.py

    r56295 r61220  
    3434
    3535# Validation Kit imports.
    36 from testmanager.core.base      import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase;
     36from testmanager.core.base      import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMTooManyRows, TMRowNotFound;
    3737from testmanager.core.testbox   import TestBoxData;
    3838
     
    9292
    9393        if aoRow is None:
    94             raise TMExceptionBase('TestBoxStatus not found.');
     94            raise TMRowNotFound('TestBoxStatus not found.');
    9595
    9696        self.idTestBox           = aoRow[0];
     
    175175        if cRows != 1:
    176176            if cRows != 0:
    177                 raise TMExceptionBase('tryFetchStatusForCommandReq got %s rows for idTestBox=%s' % (cRows, idTestBox));
     177                raise TMTooManyRows('tryFetchStatusForCommandReq got %s rows for idTestBox=%s' % (cRows, idTestBox));
    178178            return (None, None);
    179179        aoRow = self._oDb.fetchOne();
  • trunk/src/VBox/ValidationKit/testmanager/core/testcase.py

    r56295 r61220  
    3838from common                             import utils;
    3939from testmanager.core.base              import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase, \
    40                                                ChangeLogEntry, AttributeChangeEntry;
     40                                               TMInvalidData, TMRowNotFound, ChangeLogEntry, AttributeChangeEntry;
    4141from testmanager.core.globalresource    import GlobalResourceData;
    4242from testmanager.core.useraccount       import UserAccountLogic;
     
    7575        """
    7676        if aoRow is None:
    77             raise TMExceptionBase('Test case not found.');
     77            raise TMRowNotFound('Test case not found.');
    7878
    7979        self.idTestCase         = aoRow[0];
     
    214214        """
    215215        if aoRow is None:
    216             raise TMExceptionBase('Test case not found.');
     216            raise TMRowNotFound('Test case not found.');
    217217
    218218        self.idTestCase         = aoRow[0];
     
    242242        return True
    243243
    244     def validateAndConvert(self, oDb = None):
     244    def validateAndConvert(self, oDb = None, enmValidateFor = ModelDataBase.ksValidateFor_Other):
    245245        """
    246246        Validates the input and converts valid fields to their right type.
     
    259259
    260260        _ = oDb;
     261        _ = enmValidateFor;
    261262        return dErrors
    262263
     
    469470        """
    470471        if aoRow is None:
    471             raise TMExceptionBase('Test case not found.');
     472            raise TMRowNotFound('Test case not found.');
    472473
    473474        self.idTestCase         = aoRow[0];
     
    497498        aoRow = oDb.fetchOne()
    498499        if aoRow is None:
    499             raise TMExceptionBase('idTestCase=%s not found (tsNow=%s sPeriodBack=%s)' % (idTestCase, tsNow, sPeriodBack,));
     500            raise TMRowNotFound('idTestCase=%s not found (tsNow=%s sPeriodBack=%s)' % (idTestCase, tsNow, sPeriodBack,));
    500501        return self.initFromDbRow(aoRow);
    501502
     
    810811        """
    811812        TestCaseData.initFromDbWithGenId(self, oDb, idGenTestCase);
    812         if tsNow == None and not oDb.isTsInfinity(self.tsExpire):
     813        if tsNow is None and not oDb.isTsInfinity(self.tsExpire):
    813814            tsNow = self.tsEffective;
    814815        return self._initExtraMembersFromDb(oDb, tsNow);
     
    890891                oVar = copy.copy(self.aoTestCaseArgs[iVar]);
    891892                oVar.idTestCase = self.idTestCase;
    892                 dCurErrors = oVar.validateAndConvert(oDb);
     893                dCurErrors = oVar.validateAndConvert(oDb, ModelDataBase.ksValidateFor_Other);
    893894                if len(dCurErrors) == 0:
    894895                    pass; ## @todo figure out the ID?
     
    915916        return (aoNewValues, None if len(asErrors) == 0 else ' <br>'.join(asErrors));
    916917
    917     def _validateAndConvertWorker(self, asAllowNullAttributes, oDb):
    918         dErrors = TestCaseData._validateAndConvertWorker(self, asAllowNullAttributes, oDb);
     918    def _validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor = ModelDataBase.ksValidateFor_Other):
     919        dErrors = TestCaseData._validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor);
    919920
    920921        # Validate dependencies a wee bit for paranoid reasons. The scheduler
     
    11271128        #
    11281129        assert isinstance(oData, TestCaseDataEx);
    1129         dErrors = oData.validateAndConvert(self._oDb);
     1130        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add);
    11301131        if len(dErrors) > 0:
    1131             raise TMExceptionBase('Invalid input data: %s' % (dErrors,));
     1132            raise TMInvalidData('Invalid input data: %s' % (dErrors,));
    11321133
    11331134        #
     
    11711172        #
    11721173        assert isinstance(oData, TestCaseDataEx);
    1173         dErrors = oData.validateAndConvert(self._oDb);
     1174        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
    11741175        if len(dErrors) > 0:
    1175             raise TMExceptionBase('Invalid input data: %s' % (dErrors,));
     1176            raise TMInvalidData('Invalid input data: %s' % (dErrors,));
    11761177
    11771178        #
  • trunk/src/VBox/ValidationKit/testmanager/core/testcaseargs.py

    r56295 r61220  
    3636# Validation Kit imports.
    3737from common                             import utils;
    38 from testmanager.core.base              import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase;
     38from testmanager.core.base              import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase, \
     39                                               TMRowNotFound;
    3940from testmanager.core.testcase          import TestCaseData, TestCaseDependencyLogic, TestCaseGlobalRsrcDepLogic;
    4041
     
    9293        """
    9394        if aoRow is None:
    94             raise TMExceptionBase('TestBoxStatus not found.');
     95            raise TMRowNotFound('TestBoxStatus not found.');
    9596
    9697        self.idTestCase         = aoRow[0];
     
    118119        aoRow = oDb.fetchOne()
    119120        if aoRow is None:
    120             raise TMExceptionBase('idTestCaseArgs=%s not found (tsNow=%s sPeriodBack=%s)'
    121                                   % (idTestCaseArgs, tsNow, sPeriodBack,));
     121            raise TMRowNotFound('idTestCaseArgs=%s not found (tsNow=%s sPeriodBack=%s)'
     122                                % (idTestCaseArgs, tsNow, sPeriodBack,));
    122123        return self.initFromDbRow(aoRow);
    123124
     
    188189    def initFromDbWithId(self, oDb, idTestCaseArgs, tsNow = None, sPeriodBack = None):
    189190        _ = oDb; _ = idTestCaseArgs; _ = tsNow; _ = sPeriodBack;
    190         raise Exception('Not supported.');
     191        raise TMExceptionBase('Not supported.');
    191192
    192193    def initFromDbWithGenId(self, oDb, idGenTestCaseArgs):
    193194        _ = oDb; _ = idGenTestCaseArgs;
    194         raise Exception('Use initFromDbWithGenIdEx...');
     195        raise TMExceptionBase('Use initFromDbWithGenIdEx...');
    195196
    196197    def initFromDbWithGenIdEx(self, oDb, idGenTestCaseArgs, tsConfigEff = None, tsRsrcEff = None):
  • trunk/src/VBox/ValidationKit/testmanager/core/testgroup.py

    r56295 r61220  
    3434
    3535# Validation Kit imports.
    36 from testmanager.core.base              import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase
     36from testmanager.core.base              import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMRowInUse, \
     37                                               TMTooManyRows, TMInvalidData, TMRowNotFound, TMRowAlreadyExists;
    3738from testmanager.core.testcase          import TestCaseData, TestCaseDataEx;
    3839
     
    7576        """
    7677        if aoRow is None:
    77             raise TMExceptionBase('Test group member not found.')
     78            raise TMRowNotFound('Test group member not found.')
    7879
    7980        self.idTestGroup     = aoRow[0];
     
    144145        return asAttributes;
    145146
    146     def _validateAndConvertWorker(self, asAllowNullAttributes, oDb):
    147         dErrors = TestGroupMemberData._validateAndConvertWorker(self, asAllowNullAttributes, oDb);
     147    def _validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor = ModelDataBase.ksValidateFor_Other):
     148        dErrors = TestGroupMemberData._validateAndConvertWorker(self, asAllowNullAttributes, oDb, enmValidateFor);
    148149        if self.ksParam_idTestCase not in dErrors:
    149150            self.oTestCase = TestCaseDataEx()
     
    230231        """
    231232        if aoRow is None:
    232             raise TMExceptionBase('Test group not found.')
     233            raise TMRowNotFound('Test group not found.')
    233234
    234235        self.idTestGroup     = aoRow[0]
     
    251252        aoRow = oDb.fetchOne()
    252253        if aoRow is None:
    253             raise TMExceptionBase('idTestGroup=%s not found (tsNow=%s sPeriodBack=%s)' % (idTestGroup, tsNow, sPeriodBack,));
     254            raise TMRowNotFound('idTestGroup=%s not found (tsNow=%s sPeriodBack=%s)' % (idTestGroup, tsNow, sPeriodBack,));
    254255        return self.initFromDbRow(aoRow);
    255256
     
    355356            aoNewMembers.append(oNewMember);
    356357
    357             dErrors = oNewMember.validateAndConvert(oDb);
     358            dErrors = oNewMember.validateAndConvert(oDb, ModelDataBase.ksValidateFor_Other);
    358359            if len(dErrors) > 0:
    359360                asErrors.append(str(dErrors));
    360361
    361362        if len(asErrors) == 0:
    362             for i in range(len(aoNewMembers)):
     363            for i, _ in enumerate(aoNewMembers):
    363364                idTestCase = aoNewMembers[i];
    364365                for j in range(i + 1, len(aoNewMembers)):
     
    416417        #
    417418        assert isinstance(oData, TestGroupDataEx);
    418         dErrors = oData.validateAndConvert(self._oDb);
     419        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add);
    419420        if len(dErrors) > 0:
    420             raise TMExceptionBase('addEntry invalid input: %s' % (dErrors,));
     421            raise TMInvalidData('addEntry invalid input: %s' % (dErrors,));
    421422        self._assertUniq(oData, None);
    422423
     
    449450        #
    450451        assert isinstance(oData, TestGroupDataEx);
    451         dErrors = oData.validateAndConvert(self._oDb);
     452        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
    452453        if len(dErrors) > 0:
    453             raise TMExceptionBase('editEntry invalid input: %s' % (dErrors,));
     454            raise TMInvalidData('editEntry invalid input: %s' % (dErrors,));
    454455        self._assertUniq(oData, oData.idTestGroup);
    455456
     
    481482            oNewMember.idTestGroup = oData.idTestGroup;
    482483            if oNewMember.idTestCase in dNew:
    483                 raise TMExceptionBase('Duplicate test group member: idTestCase=%d (%s / %s)'
    484                                       % (oNewMember.idTestCase, oNewMember, dNew[oNewMember.idTestCase],));
     484                raise TMRowAlreadyExists('Duplicate test group member: idTestCase=%d (%s / %s)'
     485                                         % (oNewMember.idTestCase, oNewMember, dNew[oNewMember.idTestCase],));
    485486            dNew[oNewMember.idTestCase] = oNewMember;
    486487
     
    525526            if len(aoGroups) > 0:
    526527                asGroups = ['%s (#%d)' % (sName, idSchedGroup) for idSchedGroup, sName in aoGroups];
    527                 raise TMExceptionBase('Test group #%d is member of one ore more scheduling groups: %s'
    528                                       % (idTestGroup, ', '.join(asGroups),));
     528                raise TMRowInUse('Test group #%d is member of one or more scheduling groups: %s'
     529                                 % (idTestGroup, ', '.join(asGroups),));
    529530        else:
    530531            self._oDb.execute('UPDATE   SchedGroupMembers\n'
     
    645646        aRows = self._oDb.fetchAll()
    646647        if len(aRows) not in (0, 1):
    647             raise TMExceptionBase('Found more than one test groups with the same credentials. Database structure is corrupted.')
     648            raise TMTooManyRows('Found more than one test groups with the same credentials. Database structure is corrupted.')
    648649        try:
    649650            return TestGroupData().initFromDbRow(aRows[0])
     
    664665                          , ( oData.sName, ))
    665666        if self._oDb.getRowCount() > 0:
    666             raise TMExceptionBase('A Test group with name "%s" already exist.' % (oData.sName,));
     667            raise TMRowAlreadyExists('A Test group with name "%s" already exist.' % (oData.sName,));
    667668        return True;
    668669
  • trunk/src/VBox/ValidationKit/testmanager/core/testresults.py

    r61218 r61220  
    3737from common                         import constants;
    3838from testmanager                    import config;
    39 from testmanager.core.base          import ModelDataBase, ModelLogicBase, ModelDataBaseTestCase, TMExceptionBase, TMTooManyRows;
     39from testmanager.core.base          import ModelDataBase, ModelLogicBase, ModelDataBaseTestCase, TMExceptionBase, \
     40                                           TMTooManyRows, TMInvalidData, TMRowNotFound, TMRowAlreadyExists;
    4041from testmanager.core.testgroup     import TestGroupData;
    4142from testmanager.core.build         import BuildDataEx;
     
    112113        """
    113114        if aoRow is None:
    114             raise TMExceptionBase('Test result record not found.')
     115            raise TMRowNotFound('Test result record not found.')
    115116
    116117        self.idTestResult       = aoRow[0]
     
    205206        """
    206207        if aoRow is None:
    207             raise TMExceptionBase('Test result value record not found.')
     208            raise TMRowNotFound('Test result value record not found.')
    208209
    209210        self.idTestResultValue  = aoRow[0];
     
    271272        """
    272273        if aoRow is None:
    273             raise TMExceptionBase('Test result value record not found.')
     274            raise TMRowNotFound('Test result value record not found.')
    274275
    275276        self.idTestResultMsg    = aoRow[0];
     
    333334        """
    334335        if aoRow is None:
    335             raise TMExceptionBase('Test result file record not found.')
     336            raise TMRowNotFound('Test result file record not found.')
    336337
    337338        self.idTestResultFile   = aoRow[0];
     
    418419
    419420    ksIdAttr                    = 'idTestResult';
     421    kfIdAttrIsForForeign        = True; # Modifies the 'add' validation.
    420422
    421423    ksParam_idTestResult        = 'TestResultFailure_idTestResult';
     
    443445        """
    444446        if aoRow is None:
    445             raise TMExceptionBase('Test result file record not found.')
     447            raise TMRowNotFound('Test result file record not found.')
    446448
    447449        self.idTestResult       = aoRow[0];
     
    464466        aoRow = oDb.fetchOne()
    465467        if aoRow is None:
    466             raise TMExceptionBase('idTestResult=%s not found (tsNow=%s, sPeriodBack=%s)' % (idTestResult, tsNow, sPeriodBack));
     468            raise TMRowNotFound('idTestResult=%s not found (tsNow=%s, sPeriodBack=%s)' % (idTestResult, tsNow, sPeriodBack));
    467469        return self.initFromDbRow(aoRow);
    468470
     
    552554        """
    553555        if aoRow is None:
    554             raise TMExceptionBase('Test result record not found.')
     556            raise TMRowNotFound('Test result record not found.')
    555557
    556558        self.idTestSet               = aoRow[0];
     
    11151117        aRows = self._oDb.fetchAll()
    11161118        if len(aRows) not in (0, 1):
    1117             raise TMExceptionBase('Found more than one test result with the same credentials. Database structure is corrupted.')
     1119            raise TMTooManyRows('Found more than one test result with the same credentials. Database structure is corrupted.')
    11181120        try:
    11191121            return TestResultData().initFromDbRow(aRows[0])
     
    11651167        aaoRows = self._oDb.fetchAll();
    11661168        if len(aaoRows) == 0:
    1167             raise TMExceptionBase('No test results for idTestSet=%d.' % (idTestSet,));
     1169            raise TMRowNotFound('No test results for idTestSet=%d.' % (idTestSet,));
    11681170
    11691171        # Set up the root node first.
     
    19411943        """
    19421944
     1945        #
     1946        # Validate inputs and read in the old(/current) data.
     1947        #
     1948        assert isinstance(oData, TestResultFailureData);
     1949        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_AddForeignId);
     1950        if len(dErrors) > 0:
     1951            raise TMInvalidData('editEntry invalid input: %s' % (dErrors,));
     1952
    19431953        # Check if it exist first (we're adding, not editing, collisions not allowed).
    19441954        oOldData = self.getById(oData.idTestResult);
    19451955        if oOldData is not None:
    1946             raise TMExceptionBase('TestResult %d already have a failure reason associated with it:'
    1947                                   '%s\n'
    1948                                   'Perhaps someone else beat you to it? Or did you try resubmit?'
    1949                                   % (oData.idTestResult, oOldData));
     1956            raise TMRowAlreadyExists('TestResult %d already have a failure reason associated with it:'
     1957                                     '%s\n'
     1958                                     'Perhaps someone else beat you to it? Or did you try resubmit?'
     1959                                     % (oData.idTestResult, oOldData));
    19501960
    19511961        #
     
    19651975        #
    19661976        assert isinstance(oData, TestResultFailureData);
    1967         dErrors = oData.validateAndConvert(self._oDb);
     1977        dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit);
    19681978        if len(dErrors) > 0:
    1969             raise TMExceptionBase('editEntry invalid input: %s' % (dErrors,));
     1979            raise TMInvalidData('editEntry invalid input: %s' % (dErrors,));
    19701980
    19711981        oOldData = self.getById(oData.idTestResult)
     
    19932003            self._readdEntry(uidAuthor, oData, tsCurMinusOne);
    19942004            self._historizeEntry(idTestResult);
    1995         self._oDb.execute('UPDATE   TestResultFaillures\n'
     2005        self._oDb.execute('UPDATE   TestResultFailures\n'
    19962006                          'SET      tsExpire       = CURRENT_TIMESTAMP\n'
    19972007                          'WHERE    idTestResult   = %s\n'
  • trunk/src/VBox/ValidationKit/testmanager/core/testset.py

    r56295 r61220  
    3838from common                         import utils;
    3939from testmanager                    import config;
    40 from testmanager.core.base          import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase;
     40from testmanager.core.base          import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase,  \
     41                                           TMExceptionBase, TMTooManyRows, TMRowNotFound;
    4142from testmanager.core.testbox       import TestBoxData;
    4243from testmanager.core.testresults   import TestResultFileDataEx;
     
    136137
    137138        if aoRow is None:
    138             raise TMExceptionBase('TestSet not found.');
     139            raise TMRowNotFound('TestSet not found.');
    139140
    140141        self.idTestSet              = aoRow[0];
     
    170171        aoRow = oDb.fetchOne()
    171172        if aoRow is None:
    172             raise TMExceptionBase('idTestSet=%s not found' % (idTestSet,));
     173            raise TMRowNotFound('idTestSet=%s not found' % (idTestSet,));
    173174        return self.initFromDbRow(aoRow);
    174175
     
    605606        aRows = self._oDb.fetchAll()
    606607        if len(aRows) not in (0, 1):
    607             raise TMExceptionBase('Found more than one test sets with the same credentials. Database structure is corrupted.')
     608            raise TMTooManyRows('Found more than one test sets with the same credentials. Database structure is corrupted.')
    608609        try:
    609610            return TestSetData().initFromDbRow(aRows[0])
  • trunk/src/VBox/ValidationKit/testmanager/core/useraccount.py

    r61217 r61220  
    3535# Validation Kit imports.
    3636from testmanager            import config;
    37 from testmanager.core.base  import ModelDataBase, ModelLogicBase, ModelDataBaseTestCase, TMExceptionBase;
     37from testmanager.core.base  import ModelDataBase, ModelLogicBase, ModelDataBaseTestCase, TMTooManyRows, TMRowNotFound;
    3838
    3939
     
    7575        """
    7676        if aoRow is None:
    77             raise TMExceptionBase('User not found.');
     77            raise TMRowNotFound('User not found.');
    7878
    7979        self.uid            = aoRow[0];
     
    9898        aoRow = oDb.fetchOne()
    9999        if aoRow is None:
    100             raise TMExceptionBase('uid=%s not found (tsNow=%s sPeriodBack=%s)' % (uid, tsNow, sPeriodBack,));
     100            raise TMRowNotFound('uid=%s not found (tsNow=%s sPeriodBack=%s)' % (uid, tsNow, sPeriodBack,));
    101101        return self.initFromDbRow(aoRow);
    102102
     
    190190        aRows = self._oDb.fetchAll()
    191191        if len(aRows) not in (0, 1):
    192             raise TMExceptionBase('Found more than one user account with the same credentials. Database structure is corrupted.')
     192            raise TMTooManyRows('Found more than one user account with the same credentials. Database structure is corrupted.')
    193193
    194194        try:
  • trunk/src/VBox/ValidationKit/testmanager/core/vcsrevisions.py

    r61149 r61220  
    159159
    160160        # Check VcsRevisionData before do anything
    161         dDataErrors = oData.validateAndConvert(self._oDb);
     161        dDataErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add);
    162162        if len(dDataErrors) > 0:
    163163            raise TMExceptionBase('Invalid data passed to addVcsRevision(): %s' % (dDataErrors,));
  • trunk/src/VBox/ValidationKit/testmanager/core/webservergluebase.py

    r56295 r61220  
    499499            fnWrite('<h2>%s</h2>\n'
    500500                    '<table border="1"><tr><th>index</th><th>value</th></tr>\n' % (sName,));
    501             for i in range(len(aoStuff)):
     501            for i, _ in enumerate(aoStuff):
    502502                fnWrite('  <tr><td>' + str(i) + '</td><td>' + webutils.escapeElem(str(aoStuff[i])) + '</td></tr>\n');
    503503            fnWrite('</table>\n');
    504504        else:
    505             for i in range(len(sName) - 1):
    506                 fnWrite('%s ' % (sName[i],));
     505            for ch in sName[:-1]:
     506                fnWrite('%s ' % (ch,));
    507507            fnWrite('%s\n\n' % (sName[-1],));
    508508
    509509            fnWrite('Index  Value\n');
    510510            fnWrite('------------------------------------------------------------------------\n');
    511             for i in range(len(aoStuff)):
    512                 fnWrite('%5u  %s\n' % (i, str(aoStuff[i])));
     511            for i, oStuff in enumerate(aoStuff):
     512                fnWrite('%5u  %s\n' % (i, str(oStuff)));
    513513            fnWrite('\n');
    514514
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmin.py

    r61217 r61220  
    130130    ksActionBuildBlacklistEditPost  = 'BuildBlacklistEditPost';
    131131
    132     ksActionFailureCategoryList     = 'FailureCategoryList'
    133     ksActionFailureCategoryShowAdd  = 'FailureCategoryShowAdd'
    134     ksActionFailureCategoryShowEdit = 'FailureCategoryShowEdit'
    135     ksActionFailureCategoryAdd      = 'FailureCategoryAdd'
    136     ksActionFailureCategoryEdit     = 'FailureCategoryEdit'
    137     ksActionFailureCategoryDel      = 'FailureCategoryDel'
     132    ksActionFailureCategoryList     = 'FailureCategoryList';
     133    ksActionFailureCategoryAdd      = 'FailureCategoryAdd';
     134    ksActionFailureCategoryAddPost  = 'FailureCategoryAddPost';
     135    ksActionFailureCategoryDetails  = 'FailureCategoryDetails';
     136    ksActionFailureCategoryDoRemove = 'FailureCategoryDoRemove';
     137    ksActionFailureCategoryEdit     = 'FailureCategoryEdit';
     138    ksActionFailureCategoryEditPost = 'FailureCategoryEditPost';
    138139
    139140    ksActionFailureReasonList       = 'FailureReasonList'
     141    ksActionFailureReasonAdd        = 'FailureReasonAdd'
     142    ksActionFailureReasonAddPost    = 'FailureReasonAddPost'
    140143    ksActionFailureReasonDetails    = 'FailureReasonDetails'
    141     ksActionFailureReasonShowAdd    = 'FailureReasonShowAdd'
    142     ksActionFailureReasonShowEdit   = 'FailureReasonShowEdit'
    143     ksActionFailureReasonAdd        = 'FailureReasonAdd'
     144    ksActionFailureReasonDoRemove   = 'FailureReasonDoRemove'
    144145    ksActionFailureReasonEdit       = 'FailureReasonEdit'
    145     ksActionFailureReasonDel        = 'FailureReasonDel'
     146    ksActionFailureReasonEditPost   = 'FailureReasonEditPost'
    146147
    147148    ksActionBuildSrcList            = 'BuildSrcList'
     
    329330        # Failure Category actions
    330331        #
    331         d[self.ksActionFailureCategoryList]     = lambda: self._actionGenericListing(
    332                                                                 FailureCategoryLogic,
    333                                                                 WuiFailureCategoryList)
    334 
    335         d[self.ksActionFailureCategoryShowAdd]  = lambda: self._actionGenericFormAdd(
    336                                                                 FailureCategoryData,
    337                                                                 WuiFailureCategory)
    338 
    339         d[self.ksActionFailureCategoryShowEdit] = lambda: self._actionGenericFormEditL(
    340                                                                 FailureCategoryLogic,
    341                                                                 FailureCategoryData.ksParam_idFailureCategory,
    342                                                                 WuiFailureCategory)
    343 
    344         d[self.ksActionFailureCategoryAdd]      = lambda: self._actionGenericFormAddPost(
    345                                                                 FailureCategoryData,
    346                                                                 FailureCategoryLogic,
    347                                                                 WuiFailureCategory,
    348                                                                 self.ksActionFailureCategoryList)
    349 
    350         d[self.ksActionFailureCategoryEdit]     = lambda: self._actionGenericFormEditPost(
    351                                                                 FailureCategoryData,
    352                                                                 FailureCategoryLogic,
    353                                                                 WuiFailureCategory,
    354                                                                 self.ksActionFailureCategoryList)
    355 
    356         d[self.ksActionFailureCategoryDel]      = lambda: self._actionGenericDoDelOld(
    357                                                                 FailureCategoryLogic,
    358                                                                 FailureCategoryData.ksParam_idFailureCategory,
    359                                                                 self.ksActionFailureCategoryList)
     332        d[self.ksActionFailureCategoryList] = \
     333            lambda: self._actionGenericListing(FailureCategoryLogic, WuiFailureCategoryList);
     334        d[self.ksActionFailureCategoryAdd] = \
     335            lambda: self._actionGenericFormAdd(FailureCategoryData, WuiFailureCategory);
     336        d[self.ksActionFailureCategoryAddPost] = \
     337            lambda: self._actionGenericFormAddPost(FailureCategoryData, FailureCategoryLogic, WuiFailureCategory,
     338                                                   self.ksActionFailureCategoryList)
     339        d[self.ksActionFailureCategoryDetails] = \
     340            lambda: self._actionGenericFormDetails(FailureCategoryData, FailureCategoryLogic, WuiFailureCategory);
     341
     342        d[self.ksActionFailureCategoryDoRemove] = \
     343            lambda: self._actionGenericDoRemove(FailureCategoryLogic, FailureCategoryData.ksParam_idFailureCategory,
     344                                                self.ksActionFailureCategoryList);
     345        d[self.ksActionFailureCategoryEdit] = \
     346            lambda: self._actionGenericFormEdit(FailureCategoryData, WuiFailureCategory,
     347                                                FailureCategoryData.ksParam_idFailureCategory);
     348        d[self.ksActionFailureCategoryEditPost] = \
     349            lambda: self._actionGenericFormEditPost(FailureCategoryData, FailureCategoryLogic, WuiFailureCategory,
     350                                                    self.ksActionFailureCategoryList);
    360351
    361352        #
    362353        # Failure Reason actions
    363354        #
    364         d[self.ksActionFailureReasonList]       = lambda: self._actionGenericListing(
    365                                                                 FailureReasonLogic,
    366                                                                 WuiAdminFailureReasonList)
    367 
    368         d[self.ksActionFailureReasonDetails]    = lambda: self._actionGenericFormDetails(FailureReasonData,
    369                                                                                          FailureReasonLogic,
    370                                                                                          WuiAdminFailureReason,
    371                                                                                          'idFailureReason');
    372         d[self.ksActionFailureReasonShowEdit]   = lambda: self._actionGenericFormEditL(
    373                                                                 FailureReasonLogic,
    374                                                                 FailureReasonData.ksParam_idFailureReason,
    375                                                                 WuiAdminFailureReason)
    376 
    377         d[self.ksActionFailureReasonAdd]        = lambda: self._actionGenericFormAddPost(
    378                                                                 FailureReasonData,
    379                                                                 FailureReasonLogic,
    380                                                                 WuiAdminFailureReason,
    381                                                                 self.ksActionFailureReasonList)
    382 
    383         d[self.ksActionFailureReasonEdit]       = lambda: self._actionGenericFormEditPost(
    384                                                                 FailureReasonData,
    385                                                                 FailureReasonLogic,
    386                                                                 WuiAdminFailureReason,
    387                                                                 self.ksActionFailureReasonList)
    388 
    389         d[self.ksActionFailureReasonDel]        = lambda: self._actionGenericDoDelOld(FailureReasonLogic,
    390                                                                                       FailureReasonData.ksParam_idFailureReason,
    391                                                                                       self.ksActionFailureReasonList)
     355        d[self.ksActionFailureReasonList] = \
     356            lambda: self._actionGenericListing(FailureReasonLogic, WuiAdminFailureReasonList)
     357
     358        d[self.ksActionFailureReasonAdd] = \
     359            lambda: self._actionGenericFormAdd(FailureReasonData, WuiAdminFailureReason);
     360        d[self.ksActionFailureReasonAddPost] = \
     361            lambda: self._actionGenericFormAddPost(FailureReasonData, FailureReasonLogic, WuiAdminFailureReason,
     362                                                   self.ksActionFailureReasonList);
     363        d[self.ksActionFailureReasonDetails] = \
     364            lambda: self._actionGenericFormDetails(FailureReasonData, FailureReasonLogic, WuiAdminFailureReason);
     365        d[self.ksActionFailureReasonDoRemove] = \
     366            lambda: self._actionGenericDoRemove(FailureReasonLogic, FailureReasonData.ksParam_idFailureReason,
     367                                                self.ksActionFailureReasonList);
     368        d[self.ksActionFailureReasonEdit] = \
     369            lambda: self._actionGenericFormEdit(FailureReasonData, WuiAdminFailureReason);
     370
     371        d[self.ksActionFailureReasonEditPost] = \
     372            lambda: self._actionGenericFormEditPost(FailureReasonData, FailureReasonLogic, WuiAdminFailureReason,\
     373                                                    self.ksActionFailureReasonList)
    392374
    393375        #
     
    466448                    [ 'Failure Categories',     self._sActionUrlBase + self.ksActionFailureCategoryList ],
    467449                    [ 'Failure Reasons',        self._sActionUrlBase + self.ksActionFailureReasonList ],
    468                     [ 'New Failure Category',   self._sActionUrlBase + self.ksActionFailureCategoryShowAdd ],
    469                     [ 'New Failure Reason',     self._sActionUrlBase + self.ksActionFailureReasonShowAdd ],
     450                    [ 'New Failure Category',   self._sActionUrlBase + self.ksActionFailureCategoryAdd ],
     451                    [ 'New Failure Reason',     self._sActionUrlBase + self.ksActionFailureReasonAdd ],
    470452                ]
    471453            ],
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminbuildblacklist.py

    r56295 r61220  
    7373            from testmanager.webui.wuiadmin import WuiAdmin
    7474            raise WuiException('Please <a href="%s?%s=%s">add</a> some Failure Reasons first.'
    75                                % (WuiAdmin.ksScriptName, WuiAdmin.ksParamAction, WuiAdmin.ksActionFailureReasonShowAdd));
     75                               % (WuiAdmin.ksScriptName, WuiAdmin.ksParamAction, WuiAdmin.ksActionFailureReasonAdd));
    7676
    7777        asTypes    = self.getListOfItems(self.asTypes,    oData.asTypes)
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminfailurereason.py

    r56295 r61220  
    4848        """
    4949
     50        sTitle = 'Failure Reason';
    5051        if sMode == WuiFormContentBase.ksMode_Add:
    51             sTitle = 'Add Failure Reason'
    52             sSubmitAction = oDisp.ksActionFailureReasonAdd
     52            sTitle = 'Add' + sTitle;
    5353        elif sMode == WuiFormContentBase.ksMode_Edit:
    54             sTitle = 'Edit Failure Reason'
    55             sSubmitAction = oDisp.ksActionFailureReasonEdit
     54            sTitle = 'Edit' + sTitle;
    5655        else:
    57             raise WuiException('Unknown parameter')
     56            assert sMode == WuiFormContentBase.ksMode_Show;
    5857
    59         WuiFormContentBase.__init__(self, oFailureReasonData, sMode, 'FailureReason', oDisp, sTitle,
    60                                     sSubmitAction = sSubmitAction, fEditable = False); ## @todo non-standard action names.
     58        WuiFormContentBase.__init__(self, oFailureReasonData, sMode, 'FailureReason', oDisp, sTitle);
    6159
    6260    def _populateForm(self, oForm, oData):
     
    6967            from testmanager.webui.wuiadmin import WuiAdmin
    7068            sExceptionMsg = 'Please <a href="%s?%s=%s">add</a> Failure Category first.' % \
    71                 (WuiAdmin.ksScriptName, WuiAdmin.ksParamAction, WuiAdmin.ksActionFailureCategoryShowAdd)
     69                (WuiAdmin.ksScriptName, WuiAdmin.ksParamAction, WuiAdmin.ksActionFailureCategoryAdd)
    7270
    7371            raise WuiException(sExceptionMsg)
     
    9088
    9189        return True
     90
    9291
    9392class WuiAdminFailureReasonList(WuiListContentBase):
     
    117116                 oEntry.iTicket,
    118117                 oEntry.asUrls,
    119                  [ WuiTmLink('Modify', WuiAdmin.ksScriptName,
    120                              { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonShowEdit,
     118                 [ WuiTmLink('Details', WuiAdmin.ksScriptName,
     119                             { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonDetails,
     120                               FailureReasonData.ksParam_idFailureReason: oEntry.idFailureReason } ),
     121                   WuiTmLink('Modify', WuiAdmin.ksScriptName,
     122                             { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonEdit,
    121123                               FailureReasonData.ksParam_idFailureReason: oEntry.idFailureReason } ),
    122124                   WuiTmLink('Remove', WuiAdmin.ksScriptName,
    123                              { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonDel,
     125                             { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonDoRemove,
    124126                               FailureReasonData.ksParam_idFailureReason: oEntry.idFailureReason },
    125127                             sConfirm = 'Are you sure you want to remove failure reason #%d?' % (oEntry.idFailureReason,)),
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminsystemlog.py

    r56295 r61220  
    5252        oEntry  = self._aoEntries[iEntry];
    5353
    54         oAction = '';
    5554        if    oEntry.sEvent == SystemLogData.ksEvent_TestBoxUnknown \
    5655          and oEntry.sLogText.find('addr=') >= 0 \
     
    6968                                { WuiAdmin.ksParamAction: WuiAdmin.ksActionUserAdd,
    7069                                  UserAccountData.ksParam_sLoginName: sUserName });
     70        else:
     71            oAction = ''; # pylint: disable=R0204
    7172
    7273        return [oEntry.tsCreated, oEntry.sEvent, oEntry.sLogText, oAction];
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmintestbox.py

    r56295 r61220  
    3434
    3535# Validation Kit imports.
     36from common                             import utils;
    3637from testmanager.webui.wuicontentbase   import WuiListContentWithActionBase, WuiFormContentBase, WuiLinkBase, WuiSvnLink, \
    3738                                               WuiTmLink, WuiSpanText, WuiRawHtml;
     
    4041from testmanager.core.testbox           import TestBoxData;
    4142from testmanager.core.testset           import TestSetData;
    42 from common                             import utils;
    4343from testmanager.core.db                import isDbTimestampInfinity;
    4444
     
    215215            else:
    216216                from testmanager.webui.wuimain import WuiMain;
    217                 oState = WuiTmLink(oEntry.oStatus.enmState, WuiMain.ksScriptName,
     217                oState = WuiTmLink(oEntry.oStatus.enmState, WuiMain.ksScriptName,                       # pylint: disable=R0204
    218218                                   { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails,
    219219                                     TestSetData.ksParam_idTestSet: oEntry.oStatus.idTestSet, },
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuibase.py

    r61217 r61220  
    3636from common                       import webutils, utils;
    3737from testmanager                  import config;
    38 from testmanager.core.base        import ModelDataBase, TMExceptionBase;
     38from testmanager.core.base        import ModelDataBase, ModelLogicBase, TMExceptionBase;
    3939from testmanager.core.db          import TMDatabaseConnection;
    4040from testmanager.core.systemlog   import SystemLogLogic, SystemLogData;
     
    733733        oFormType is a WuiFormContentBase child class.
    734734        """
     735        assert issubclass(oDataType, ModelDataBase);
     736        from testmanager.webui.wuicontentbase import WuiFormContentBase;
     737        assert issubclass(oFormType, WuiFormContentBase);
     738
    735739        oData = oDataType().initFromParams(oDisp = self, fStrict = False);
    736740        sRedirectTo = self.getRedirectToParameter(sRedirectTo);
     
    742746        return True
    743747
    744     def _actionGenericFormDetails(self, oDataType, oLogicType, oFormType, sIdAttr, sGenIdAttr = None): # pylint: disable=R0914
     748    def _actionGenericFormDetails(self, oDataType, oLogicType, oFormType, sIdAttr = None, sGenIdAttr = None): # pylint: disable=R0914
    745749        """
    746750        Generic handler for showing a details form/page.
     
    751755        sIdParamName is the name of the ID parameter (not idGen!).
    752756        """
     757        # Input.
     758        assert issubclass(oDataType, ModelDataBase);
     759        assert issubclass(oLogicType, ModelLogicBase);
     760        from testmanager.webui.wuicontentbase import WuiFormContentBase;
     761        assert issubclass(oFormType, WuiFormContentBase);
     762
     763        if sIdAttr is None:
     764            sIdAttr = oDataType.ksIdAttr;
     765        if sGenIdAttr is None:
     766            sGenIdAttr = getattr(oDataType, 'ksGenIdAttr', None);
     767
    753768        # Parameters.
    754769        idGenObject = -1;
     
    784799
    785800
    786     def _actionGenericFormEdit(self, oDataType, oFormType, sIdParamName, sRedirectTo = None):
     801    def _actionGenericFormEdit(self, oDataType, oFormType, sIdParamName = None, sRedirectTo = None):
    787802        """
    788803        Generic edit something form display request handler.
     
    792807        sIdParamName is the name of the ID parameter (not idGen!).
    793808        """
     809        assert issubclass(oDataType, ModelDataBase);
     810        from testmanager.webui.wuicontentbase import WuiFormContentBase;
     811        assert issubclass(oFormType, WuiFormContentBase);
     812
     813        if sIdParamName is None:
     814            sIdParamName = getattr(oDataType, 'ksParam_' + oDataType.ksIdAttr);
     815        assert len(sIdParamName) > 1;
    794816
    795817        tsNow    = self.getEffectiveDateParam();
     
    839861        sGenIdParamName is the name of the generation ID parameter, None if not applicable.
    840862        """
     863        # Input.
     864        assert issubclass(oDataType, ModelDataBase);
     865        from testmanager.webui.wuicontentbase import WuiFormContentBase;
     866        assert issubclass(oFormType, WuiFormContentBase);
     867
    841868        # Parameters.
    842869        idGenObject = -1;
     
    876903        fnLogicAction is a method taking a oDataType instance and uidAuthor as arguments.
    877904        """
     905        assert issubclass(oDataType, ModelDataBase);
     906        from testmanager.webui.wuicontentbase import WuiFormContentBase;
     907        assert issubclass(oFormType, WuiFormContentBase);
     908
    878909        #
    879910        # Read and validate parameters.
     
    883914        self._checkForUnknownParameters();
    884915        self._assertPostRequest();
    885         dErrors = oData.validateAndConvert(self._oDb);
     916        if sMode == WuiFormContentBase.ksMode_Add and  getattr(oData, 'kfIdAttrIsForForeign', False):
     917            enmValidateFor = oData.ksValidateFor_AddForeignId;
     918        elif sMode == WuiFormContentBase.ksMode_Add:
     919            enmValidateFor = oData.ksValidateFor_Add;
     920        else:
     921            enmValidateFor = oData.ksValidateFor_Edit;
     922        dErrors = oData.validateAndConvert(self._oDb, enmValidateFor);
    886923        if len(dErrors) == 0:
    887924            oData.convertFromParamNull();
     
    907944        else:
    908945            oForm = oFormType(oData, sMode, oDisp = self);
     946            oForm.setRedirectTo(sRedirectTo);
    909947            (self._sPageTitle, self._sPageBody) = oForm.showForm(dErrors = dErrors);
    910948        return True;
     
    919957        sRedirAction is what action to redirect to on success.
    920958        """
     959        assert issubclass(oDataType, ModelDataBase);
     960        assert issubclass(oLogicType, ModelLogicBase);
     961        from testmanager.webui.wuicontentbase import WuiFormContentBase;
     962        assert issubclass(oFormType, WuiFormContentBase);
     963
    921964        oLogic = oLogicType(self._oDb);
    922         from testmanager.webui.wuicontentbase import WuiFormContentBase;
    923965        return self._actionGenericFormPost(WuiFormContentBase.ksMode_Add, oLogic.addEntry, oDataType, oFormType,
    924966                                           '?' + webutils.encodeUrlParams({self.ksParamAction: sRedirAction}), fStrict=fStrict)
     
    932974        sRedirAction is what action to redirect to on success.
    933975        """
     976        assert issubclass(oDataType, ModelDataBase);
     977        assert issubclass(oLogicType, ModelLogicBase);
     978        from testmanager.webui.wuicontentbase import WuiFormContentBase;
     979        assert issubclass(oFormType, WuiFormContentBase);
     980
    934981        oLogic = oLogicType(self._oDb);
    935         from testmanager.webui.wuicontentbase import WuiFormContentBase;
    936982        return self._actionGenericFormPost(WuiFormContentBase.ksMode_Edit, oLogic.editEntry, oDataType, oFormType,
    937983                                           '?' + webutils.encodeUrlParams({self.ksParamAction: sRedirAction}),
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuifailurecategory.py

    r56295 r61220  
    3333from testmanager.webui.wuicontentbase  import WuiFormContentBase, WuiListContentBase, WuiTmLink
    3434from testmanager.core.failurecategory  import FailureCategoryData
    35 from testmanager.webui.wuibase         import WuiException
    3635
    3736
     
    4140    """
    4241
    43     def __init__(self, oFailureCategoryData, sMode, oDisp):
     42    def __init__(self, oData, sMode, oDisp):
    4443        """
    4544        Prepare & initialize parent
    4645        """
    4746
     47        sTitle = 'Failure Category';
    4848        if sMode == WuiFormContentBase.ksMode_Add:
    49             sTitle = 'Add Failure Category'
    50             sSubmitAction = oDisp.ksActionFailureCategoryAdd
     49            sTitle = 'Add ' + sTitle;
    5150        elif sMode == WuiFormContentBase.ksMode_Edit:
    52             sTitle = 'Edit Failure Category'
    53             sSubmitAction = oDisp.ksActionFailureCategoryEdit
     51            sTitle = 'Edit ' + sTitle;
    5452        else:
    55             raise WuiException('Unknown parameter')
     53            assert sMode == WuiFormContentBase.ksMode_Show;
    5654
    57         WuiFormContentBase.__init__(self, oFailureCategoryData, sMode, 'FailureCategory', oDisp, sTitle,
    58                                     sSubmitAction = sSubmitAction, fEditable = False); ## @todo non-standard action names.
     55        WuiFormContentBase.__init__(self, oData, sMode, 'FailureCategory', oDisp, sTitle);
    5956
    6057    def _populateForm(self, oForm, oData):
     
    7370
    7471        return True
     72
    7573
    7674class WuiFailureCategoryList(WuiListContentBase):
     
    9492                 oEntry.sShort,
    9593                 oEntry.sFull,
    96                  [ WuiTmLink('Modify', WuiAdmin.ksScriptName,
    97                              { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureCategoryShowEdit,
     94                 [ WuiTmLink('Details', WuiAdmin.ksScriptName,
     95                             { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureCategoryDetails,
     96                               FailureCategoryData.ksParam_idFailureCategory: oEntry.idFailureCategory }),
     97                   WuiTmLink('Modify', WuiAdmin.ksScriptName,
     98                             { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureCategoryEdit,
    9899                               FailureCategoryData.ksParam_idFailureCategory: oEntry.idFailureCategory }),
    99100                   WuiTmLink('Remove', WuiAdmin.ksScriptName,
    100                              { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureCategoryDel,
     101                             { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureCategoryDoRemove,
    101102                               FailureCategoryData.ksParam_idFailureCategory: oEntry.idFailureCategory },
    102103                             sConfirm = 'Do you really want to remove failure cateogry #%d?' % (oEntry.idFailureCategory,)),
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuihlpform.py

    r61217 r61220  
    5656
    5757        if sOnSubmit == self.ksOnSubmit_AddReturnToFieldWithCurrentUrl:
    58             sOnSubmit = 'return addRedirectToInputFieldWithCurrentUrl(this)';
     58            sOnSubmit = u'return addRedirectToInputFieldWithCurrentUrl(this)';
    5959        if sOnSubmit is None:   sOnSubmit = u'';
    6060        else:                   sOnSubmit = u' onsubmit=\"%s\"' % (escapeAttr(sOnSubmit),);
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuihlpgraph.py

    r56295 r61220  
    100100# Dynamically choose implementation.
    101101#
    102 if True:
     102if True: # pylint: disable=W0125
    103103    from testmanager.webui import wuihlpgraphgooglechart        as GraphImplementation;
    104104else:
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphgooglechart.py

    r56295 r61220  
    3030
    3131# Validation Kit imports.
     32from common                             import webutils;
    3233from testmanager.webui.wuihlpgraphbase  import WuiHlpGraphBase;
    33 from common                             import webutils;
     34from testmanager.webui                  import wuihlpgraphsimple;
    3435
    3536
     
    4546
    4647## @todo bar graphs later.
    47 from testmanager.webui import wuihlpgraphsimple;
    4848WuiHlpBarGraph = wuihlpgraphsimple.WuiHlpBarGraph;
    4949
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphmatplotlib.py

    r56295 r61220  
    3636matplotlib.use('Agg'); # Force backend.
    3737import matplotlib.pyplot;                   # pylint: disable=F0401
    38 from numpy import arange as numpy_arange;   # pylint: disable=E0611
     38from numpy import arange as numpy_arange;   # pylint: disable=E0611,E0401
    3939
    4040# Validation Kit imports.
     
    9494        WuiHlpGraphMatplotlibBase.__init__(self, sId, oData, oDisp);
    9595        self.fpMax      = None;
    96         self.fpMin      = 0;
     96        self.fpMin      = 0.0;
    9797        self.cxBarWidth = None;
    9898
     
    138138
    139139        aoBars = list();
    140         for i in range(len(aoSeries)):
     140        for i, _ in enumerate(aoSeries):
    141141            sColor = self.calcSeriesColor(i);
    142142            aoBars.append(oSubPlot.bar(oXRange + self.cxBarWidth * i,
     
    157157        oSubPlot.grid(True);
    158158        fpPadding = (fpMax - fpMin) * 0.02;
    159         for i in range(len(aoBars)):
     159        for i, _ in enumerate(aoBars):
    160160            aoRects = aoBars[i]
    161             for j in range(len(aoRects)):
     161            for j, _ in enumerate(aoRects):
    162162                oRect = aoRects[j];
    163163                fpValue = float(aoTable[j + 1].aoValues[i]);
     
    242242            oSubPlot.grid(True, 'both', axis = 'x');
    243243
    244         if True:
     244        if True: # pylint: disable=W0125
    245245            #    oSubPlot.axis('off');
    246246            #oSubPlot.grid(True, 'major', axis = 'none');
     
    284284
    285285        oFigure = self._createFigure();
    286         from mpl_toolkits.axes_grid.axislines import SubplotZero;
     286        from mpl_toolkits.axes_grid.axislines import SubplotZero; # pylint: disable=E0401
    287287        oAxis = SubplotZero(oFigure, 111);
    288288        oFigure.add_subplot(oAxis);
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuihlpgraphsimple.py

    r56295 r61220  
    4444        self.cxMaxBar = 480;
    4545        self.fpMax = None;
    46         self.fpMin = 0;
     46        self.fpMin = 0.0;
    4747
    4848    def setRangeMax(self, fpMax):
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuireport.py

    r56295 r61220  
    9494
    9595        #for i in range(len(adPeriods) - 1, -1, -1):
    96         for i in range(len(adPeriods)):
    97             dStatuses = adPeriods[i];
     96        for i, dStatuses in enumerate(adPeriods):
    9897            cSuccess  = dStatuses[ReportModelBase.ksTestStatus_Success] + dStatuses[ReportModelBase.ksTestStatus_Skipped];
    9998            cTotal    = cSuccess + dStatuses[ReportModelBase.ksTestStatus_Failure];
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuitestresult.py

    r61217 r61220  
    182182                       sDisplayName,
    183183                       ' id="failure-%u"' % (iFailure,) if oTestResult.isFailure() else '',
    184                        webutils.escapeElem(oTestResult.enmStatus), webutils.escapeElem(sErrCnt), sChangeReason,
     184                       webutils.escapeElem(oTestResult.enmStatus), webutils.escapeElem(sErrCnt),
     185                       sChangeReason if oTestResult.oReason is None else '',
    185186                       sResultGraph );
    186187            iRow += 1;
     
    208209                sHtml += sChildHtml;
    209210                cErrorsBelow += oChild.cErrors;
    210 
    211             if cErrorsBelow >= oTestResult.cErrors:
    212                 sChangeReason = '';
    213211
    214212            # Messages.
     
    299297                         '  <td>%s</td>\n' \
    300298                         '  <td>%s</td>\n' \
    301                          '  <td colspan="2"%s>%s%s</td>\n' \
     299                         '  <td colspan="2"%s>%s%s%s</td>\n' \
    302300                         '  <td>%s</td>\n' \
    303301                         ' </tr>\n' \
     
    309307                           ' id="failure-%u"' % (iFailure,) if oTestResult.isFailure() else '',
    310308                           webutils.escapeElem(oTestResult.enmStatus), webutils.escapeElem(sErrCnt),
     309                           sChangeReason if cErrorsBelow < oTestResult.cErrors and oTestResult.oReason is None else '',
    311310                           sResultGraph);
    312311                iRow += 1;
     
    314313        # Failure reason.
    315314        if oTestResult.oReason is not None:
    316             sReasonText = '%s / %s' % (     oTestResult.oReason.oFailureReason.oCategory.sShort,
    317                                             oTestResult.oReason.oFailureReason.sShort, );
     315            sReasonText = '%s / %s' % ( oTestResult.oReason.oFailureReason.oCategory.sShort,
     316                                        oTestResult.oReason.oFailureReason.sShort, );
    318317            sCommentHtml = '';
    319318            if oTestResult.oReason.sComment is not None and len(oTestResult.oReason.sComment.strip()) > 0:
     
    327326                                                           oTestResult.idTestResult,}),
    328327                                WuiContentBase.ksShortDetailsLinkHtml,);
    329 
    330328
    331329            sHtml += ' <tr class="%s tmtbl-events-reason tmtbl-events-lvl%s">\n' \
     
    365363
    366364            # We need the failure reasons for the combobox.
    367             aoFailureReasons = FailureReasonLogic(self._oDisp.getDb()).fetchForCombo('Todo: Figure out why');
     365            aoFailureReasons = FailureReasonLogic(self._oDisp.getDb()).fetchForCombo('Test Sheriff, you figure out why!');
    368366            assert len(aoFailureReasons) > 0;
    369367
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette