VirtualBox

Changeset 84550 in vbox for trunk/src


Ignore:
Timestamp:
May 26, 2020 6:50:43 PM (5 years ago)
Author:
vboxsync
Message:

TestManager: Adding new table for correlating commits and bugs (for xTracker).

Location:
trunk/src/VBox/ValidationKit/testmanager
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/testmanager/batch/vcs_import.py

    r82968 r84550  
    22# -*- coding: utf-8 -*-
    33# $Id$
    4 # pylint: disable=line-too-long
    54
    65"""
     
    4443
    4544# Test Manager imports
    46 from testmanager.core.db            import TMDatabaseConnection;
    47 from testmanager.core.vcsrevisions  import VcsRevisionData, VcsRevisionLogic;
    48 from common                         import utils;
     45from testmanager.config                 import g_kaBugTrackers;
     46from testmanager.core.db                import TMDatabaseConnection;
     47from testmanager.core.vcsrevisions      import VcsRevisionData, VcsRevisionLogic;
     48from testmanager.core.vcsbugreference   import VcsBugReferenceData, VcsBugReferenceLogic;
     49from common                             import utils;
     50
     51# Python 3 hacks:
     52if sys.version_info[0] >= 3:
     53    long = int;     # pylint: disable=redefined-builtin,invalid-name
     54
    4955
    5056class VcsImport(object): # pylint: disable=too-few-public-methods
     
    5258    Imports revision history from a VSC into the Test Manager database.
    5359    """
     60
     61    class BugTracker(object):
     62        def __init__(self, sDbName, sTag):
     63            self.sDbName = sDbName;
     64            self.sTag    = sTag;
     65
    5466
    5567    def __init__(self):
     
    5971
    6072        oParser = OptionParser()
    61         oParser.add_option('-e', '--extra-option', dest = 'asExtraOptions', action = 'append',
     73        oParser.add_option('-b', '--only-bug-refs', dest = 'fBugRefsOnly', action = 'store_true',
     74                           help = 'Only do bug references, not revisions.');
     75        oParser.add_option('-e', '--extra-option', dest = 'asExtraOptions', metavar = 'vcsoption', action = 'append',
    6276                           help = 'Adds a extra option to the command retrieving the log.');
    6377        oParser.add_option('-f', '--full', dest = 'fFull', action = 'store_true',
     
    93107        oDb = TMDatabaseConnection();
    94108        oLogic = VcsRevisionLogic(oDb);
     109        oBugLogic = VcsBugReferenceLogic(oDb);
    95110
    96111        # Where to start.
    97112        iStartRev = 0;
    98113        if not self.oConfig.fFull:
    99             iStartRev = oLogic.getLastRevision(self.oConfig.sRepository);
     114            if not self.oConfig.fBugRefsOnly:
     115                iStartRev = oLogic.getLastRevision(self.oConfig.sRepository);
     116            else:
     117                iStartRev = oBugLogic.getLastRevision(self.oConfig.sRepository);
    100118        if iStartRev == 0:
    101119            iStartRev = self.oConfig.iStartRevision;
     
    118136        # Parse the XML and add the entries to the database.
    119137        oParser = ET.XMLParser(target = ET.TreeBuilder(), encoding = 'utf-8');
    120         oParser.feed(sLogXml.encode('utf-8')); # does its own decoding and processOutputChecked always gives us decoded utf-8 now.
     138        oParser.feed(sLogXml.encode('utf-8')); # Does its own decoding; processOutputChecked always gives us decoded utf-8 now.
    121139        oRoot = oParser.close();
    122140
    123141        for oLogEntry in oRoot.findall('logentry'):
    124142            iRevision = int(oLogEntry.get('revision'));
    125             sAuthor  = oLogEntry.findtext('author').strip();
     143            sAuthor  = oLogEntry.findtext('author', 'unspecified').strip(); # cvs2svn entries doesn't have an author.
    126144            sDate    = oLogEntry.findtext('date').strip();
    127             sMessage = oLogEntry.findtext('msg', '').strip();
     145            sRawMsg  = oLogEntry.findtext('msg', '').strip();
     146            sMessage = sRawMsg;
    128147            if sMessage == '':
    129148                sMessage = ' ';
     
    133152                utils.printOut(u'sDate=%s iRev=%u sAuthor=%s sMsg[%s]=%s'
    134153                               % (sDate, iRevision, sAuthor, type(sMessage).__name__, sMessage));
    135             oData = VcsRevisionData().initFromValues(self.oConfig.sRepository, iRevision, sDate, sAuthor, sMessage);
    136             oLogic.addVcsRevision(oData);
     154
     155            if not self.oConfig.fBugRefsOnly:
     156                oData = VcsRevisionData().initFromValues(self.oConfig.sRepository, iRevision, sDate, sAuthor, sMessage);
     157                oLogic.addVcsRevision(oData);
     158
     159            # Analyze the raw message looking for bug tracker references.
     160            for sBugTrackerKey in g_kaBugTrackers:
     161                oBugTracker = g_kaBugTrackers[sBugTrackerKey];
     162                for sTag in oBugTracker.asCommitTags:
     163                    off = sRawMsg.find(sTag);
     164                    while off >= 0:
     165                        off += len(sTag);
     166                        while off < len(sRawMsg) and sRawMsg[off].isspace():
     167                            off += 1;
     168
     169                        if off < len(sRawMsg) and sRawMsg[off].isdigit():
     170                            offNum = off;
     171                            while off < len(sRawMsg) and sRawMsg[off].isdigit():
     172                                off += 1;
     173                            try:
     174                                iBugNo = long(sRawMsg[offNum:off]);
     175                            except Exception as oXcpt:
     176                                utils.printErr(u'error! exception(r%s,"%s"): -> %s' % (iRevision, sRawMsg[offNum:off], oXcpt,));
     177                            else:
     178                                if not self.oConfig.fQuiet:
     179                                    utils.printOut(u' r%u -> sBugTracker=%s iBugNo=%s'
     180                                                   % (iRevision, oBugTracker.sDbId, iBugNo,));
     181
     182                                oBugData = VcsBugReferenceData().initFromValues(self.oConfig.sRepository, iRevision,
     183                                                                                oBugTracker.sDbId, iBugNo);
     184                                oBugLogic.addVcsBugReference(oBugData);
     185
     186                        # next
     187                        off = sRawMsg.find(sTag, off);
     188
    137189        oDb.commit();
    138190
  • trunk/src/VBox/ValidationKit/testmanager/config.py

    r83418 r84550  
    148148
    149149
     150## @name Bug Trackers and VCS reference tags.
     151## @{
     152class BugTrackerConfig(object):
     153    """ Bug tracker config """
     154    def __init__(self, sDbId, sName, sBugUrl, asCommitTags):
     155        assert len(sDbId) == 4;
     156        self.sDbId        = sDbId;
     157        self.sName        = sName;
     158        self.sBugUrl      = sBugUrl;
     159        self.asCommitTags = asCommitTags;
     160
     161## The key is the database table
     162g_kaBugTrackers = {
     163    'xtrk': BugTrackerConfig('xtrk', 'xTracker',        'https://linserv.de.oracle.com/vbox/xTracker/index.php?bug=',
     164                             ['bugref:',    '@bugref{',    'bugef:', 'bugrf:', ], ),
     165    'bgdb': BugTrackerConfig('bgdb', 'BugDB',           'https://bug.oraclecorp.com/pls/bug/webbug_edit.edit_info_top?rptno=',
     166                             ['bugdbref:',  '@bugdbref{',  'bugdb:', ], ),
     167    'vorg': BugTrackerConfig('vorg', 'External Trac',   'https://www.virtualbox.org/ticket/',
     168                             ['ticketref:', '@ticketref{', 'ticket:', ], ),
     169};
     170## @}
     171
     172
     173
     174## @name Virtual Sheriff email alerts
     175## @{
     176
     177## SMTP server host name.
     178g_ksSmtpHost            = 'internal-mail-router.oracle.com';
     179## SMTP server port number.
     180g_kcSmtpPort            = 25;
     181## Default email 'From' for email alert.
     182g_ksAlertFrom           = '[email protected]';
     183## Subject for email alert.
     184g_ksAlertSubject        = 'Virtual Test Sheriff Alert';
     185## List of users to send alerts.
     186g_asAlertList           = ['lelik', 'werner'];
     187## iLOM password.
     188g_ksLomPassword         = 'password';
     189
     190## @}
     191
     192
    150193## @name Partial Database Dump
    151194## @{
     
    207250## @}
    208251
    209 ## @name Virtual Sheriff email alerts
    210 ## @{
    211 
    212 ## SMTP server host name.
    213 g_ksSmtpHost            = 'internal-mail-router.oracle.com';
    214 ## SMTP server port number.
    215 g_kcSmtpPort            = 25;
    216 ## Default email 'From' for email alert.
    217 g_ksAlertFrom           = '[email protected]';
    218 ## Subject for email alert.
    219 g_ksAlertSubject        = 'Virtual Test Sheriff Alert';
    220 ## List of users to send alerts.
    221 g_asAlertList           = ['lelik', 'werner'];
    222 ## iLOM password.
    223 g_ksLomPassword         = 'password';
    224 
    225 ## @}
  • trunk/src/VBox/ValidationKit/testmanager/core/vcsbugreference.py

    r84537 r84550  
    33
    44"""
    5 Test Manager - VcsRevisions
     5Test Manager - VcsBugReferences
    66"""
    77
     
    3737
    3838
    39 class VcsRevisionData(ModelDataBase):
     39class VcsBugReferenceData(ModelDataBase):
    4040    """
    41     A version control system (VCS) revision.
     41    A version control system (VCS) bug tracker reference (commit message tag).
    4242    """
    4343
    44     #kasIdAttr = ['sRepository',iRevision];
     44    #kasIdAttr = ['sRepository','iRevision', 'sBugTracker', 'iBugNo'];
    4545
    46     ksParam_sRepository         = 'VcsRevision_sRepository';
    47     ksParam_iRevision           = 'VcsRevision_iRevision';
    48     ksParam_tsCreated           = 'VcsRevision_tsCreated';
    49     ksParam_sAuthor             = 'VcsRevision_sAuthor';
    50     ksParam_sMessage            = 'VcsRevision_sMessage';
     46    ksParam_sRepository         = 'VcsBugReference_sRepository';
     47    ksParam_iRevision           = 'VcsBugReference_iRevision';
     48    ksParam_sBugTracker         = 'VcsBugReference_sBugTracker';
     49    ksParam_lBugNo              = 'VcsBugReference_lBugNo';
    5150
    5251    kasAllowNullAttributes      = [ ];
    53     kfAllowUnicode_sMessage     = True;
    54     kcchMax_sMessage            = 8192;
    5552
    5653    def __init__(self):
     
    6360        self.sRepository        = None;
    6461        self.iRevision          = None;
    65         self.tsCreated          = None;
    66         self.sAuthor            = None;
    67         self.sMessage           = None;
     62        self.sBugTracker        = None;
     63        self.lBugNo             = None;
    6864
    6965    def initFromDbRow(self, aoRow):
    7066        """
    71         Re-initializes the object from a SELECT * FROM VcsRevisions row.
     67        Re-initializes the object from a SELECT * FROM VcsBugReferences row.
    7268        Returns self.  Raises exception if aoRow is None.
    7369        """
    7470        if aoRow is None:
    75             raise TMExceptionBase('VcsRevision not found.');
     71            raise TMExceptionBase('VcsBugReference not found.');
    7672
    77         self.sRepository         = aoRow[0];
    78         self.iRevision           = aoRow[1];
    79         self.tsCreated           = aoRow[2];
    80         self.sAuthor             = aoRow[3];
    81         self.sMessage            = aoRow[4];
     73        self.sRepository        = aoRow[0];
     74        self.iRevision          = aoRow[1];
     75        self.sBugTracker        = aoRow[2];
     76        self.lBugNo             = aoRow[3];
    8277        return self;
    8378
    84     def initFromDbWithRepoAndRev(self, oDb, sRepository, iRevision):
    85         """
    86         Initialize from the database, given the tree and revision of a row.
    87         """
    88         oDb.execute('SELECT * FROM VcsRevisions WHERE sRepository = %s AND iRevision = %u', (sRepository, iRevision,));
    89         aoRow = oDb.fetchOne()
    90         if aoRow is None:
    91             raise TMExceptionBase('sRepository = %s iRevision = %u not found' % (sRepository, iRevision, ));
    92         return self.initFromDbRow(aoRow);
    93 
    94     def initFromValues(self, sRepository, iRevision, tsCreated, sAuthor, sMessage):
     79    def initFromValues(self, sRepository, iRevision, sBugTracker, lBugNo):
    9580        """
    9681        Reinitializes form a set of values.
     
    9984        self.sRepository        = sRepository;
    10085        self.iRevision          = iRevision;
    101         self.tsCreated          = tsCreated;
    102         self.sAuthor            = sAuthor;
    103         self.sMessage           = sMessage;
     86        self.sBugTracker        = sBugTracker;
     87        self.lBugNo             = lBugNo;
    10488        return self;
    10589
    10690
    107 class VcsRevisionLogic(ModelLogicBase): # pylint: disable=too-few-public-methods
     91class VcsBugReferenceLogic(ModelLogicBase): # pylint: disable=too-few-public-methods
    10892    """
    109     VCS revisions database logic.
     93    VCS revision <-> bug tracker references database logic.
    11094    """
    11195
     
    118102        Fetches VCS revisions for listing.
    119103
    120         Returns an array (list) of VcsRevisionData items, empty list if none.
     104        Returns an array (list) of VcsBugReferenceData items, empty list if none.
    121105        Raises exception on error.
    122106        """
    123107        _ = tsNow; _ = aiSortColumns;
    124         self._oDb.execute('SELECT   *\n'
    125                           'FROM     VcsRevisions\n'
    126                           'ORDER BY tsCreated, sRepository, iRevision\n'
    127                           'LIMIT %s OFFSET %s\n'
    128                           , (cMaxRows, iStart,));
     108        self._oDb.execute('''
     109SELECT  *
     110FROM    VcsBugReferences
     111ORDER BY sRepository, iRevision, sBugTracker, lBugNo
     112LIMIT %s OFFSET %s
     113''', (cMaxRows, iStart,));
    129114
    130115        aoRows = [];
    131116        for _ in range(self._oDb.getRowCount()):
    132             aoRows.append(VcsRevisionData().initFromDbRow(self._oDb.fetchOne()));
     117            aoRows.append(VcsBugReferenceData().initFromDbRow(self._oDb.fetchOne()));
    133118        return aoRows;
    134119
    135     def tryFetch(self, sRepository, iRevision):
     120    def exists(self, oData):
    136121        """
    137         Tries to fetch the specified tree revision record.
    138         Returns VcsRevisionData instance if found, None if not found.
     122        Checks if the data is already present in the DB.
     123        Returns True / False.
    139124        Raises exception on input and database errors.
    140125        """
    141         self._oDb.execute('SELECT * FROM VcsRevisions WHERE sRepository = %s AND iRevision = %s',
    142                           ( sRepository, iRevision, ));
    143         aaoRows = self._oDb.fetchAll();
    144         if len(aaoRows) == 1:
    145             return VcsRevisionData().initFromDbRow(aaoRows[0]);
    146         if aaoRows:
    147             raise TMExceptionBase('VcsRevisions has a primary key problem: %u duplicates' % (len(aaoRows),));
    148         return None
     126        self._oDb.execute('''
     127SELECT  COUNT(*)
     128FROM    VcsBugReferences
     129WHERE   sRepository = %s
     130    AND iRevision   = %s
     131    AND sBugTracker = %s
     132    AND lBugNo      = %s
     133''', ( oData.sRepository, oData.iRevision, oData.sBugTracker, oData.lBugNo));
     134        cRows = self._oDb.fetchOne()[0];
     135        if cRows < 0 or cRows > 1:
     136            raise TMExceptionBase('VcsBugReferences has a primary key problem: %u duplicates' % (cRows,));
     137        return cRows != 0;
    149138
    150139
     
    153142    #
    154143
    155     def addVcsRevision(self, oData, fCommit = False):
     144    def addVcsBugReference(self, oData, fCommit = False):
    156145        """
    157146        Adds (or updates) a tree revision record.
     
    159148        """
    160149
    161         # Check VcsRevisionData before do anything
     150        # Check VcsBugReferenceData before do anything
    162151        dDataErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add);
    163152        if dDataErrors:
    164             raise TMExceptionBase('Invalid data passed to addVcsRevision(): %s' % (dDataErrors,));
     153            raise TMExceptionBase('Invalid data passed to addVcsBugReference(): %s' % (dDataErrors,));
    165154
    166155        # Does it already exist?
    167         oOldData = self.tryFetch(oData.sRepository, oData.iRevision);
    168         if oOldData is None:
     156        if not self.exists(oData):
    169157            # New row.
    170             self._oDb.execute('INSERT INTO VcsRevisions (sRepository, iRevision, tsCreated, sAuthor, sMessage)\n'
    171                               'VALUES (%s, %s, %s, %s, %s)\n'
     158            self._oDb.execute('INSERT INTO VcsBugReferences (sRepository, iRevision, sBugTracker, lBugNo)\n'
     159                              'VALUES (%s, %s, %s, %s)\n'
    172160                              , ( oData.sRepository,
    173161                                  oData.iRevision,
    174                                   oData.tsCreated,
    175                                   oData.sAuthor,
    176                                   oData.sMessage,
    177                               ));
    178         elif not oOldData.isEqual(oData):
    179             # Update old row.
    180             self._oDb.execute('UPDATE VcsRevisions\n'
    181                               '   SET tsCreated   = %s,\n'
    182                               '       sAuthor     = %s,\n'
    183                               '       sMessage    = %s\n'
    184                               'WHERE  sRepository = %s\n'
    185                               '   AND iRevision   = %s'
    186                               , ( oData.tsCreated,
    187                                   oData.sAuthor,
    188                                   oData.sMessage,
    189                                   oData.sRepository,
    190                                   oData.iRevision,
     162                                  oData.sBugTracker,
     163                                  oData.lBugNo,
    191164                              ));
    192165
     
    199172        if the repository is not known to us:
    200173        """
    201         self._oDb.execute('SELECT iRevision\n'
    202                           'FROM   VcsRevisions\n'
    203                           'WHERE  sRepository = %s\n'
    204                           'ORDER BY iRevision DESC\n'
    205                           'LIMIT 1\n'
    206                           , ( sRepository, ));
     174        self._oDb.execute('''
     175SELECT iRevision
     176FROM   VcsBugReferences
     177WHERE  sRepository = %s
     178ORDER BY iRevision DESC
     179LIMIT 1
     180''', ( sRepository, ));
    207181        if self._oDb.getRowCount() == 0:
    208182            return 0;
    209183        return self._oDb.fetchOne()[0];
    210 
    211     def fetchTimeline(self, sRepository, iRevision, cEntriesBack):
    212         """
    213         Fetches a VCS timeline portion for a repository.
    214 
    215         Returns an array (list) of VcsRevisionData items, empty list if none.
    216         Raises exception on error.
    217         """
    218         self._oDb.execute('SELECT   *\n'
    219                           'FROM     VcsRevisions\n'
    220                           'WHERE    sRepository = %s\n'
    221                           '   AND   iRevision  >  %s\n'
    222                           '   AND   iRevision  <= %s\n'
    223                           'ORDER BY iRevision DESC\n'
    224                           'LIMIT    %s\n'
    225                           , ( sRepository, iRevision - cEntriesBack*2 + 1, iRevision, cEntriesBack));
    226         aoRows = [];
    227         for _ in range(self._oDb.getRowCount()):
    228             aoRows.append(VcsRevisionData().initFromDbRow(self._oDb.fetchOne()));
    229         return aoRows;
    230184
    231185
     
    235189
    236190# pylint: disable=missing-docstring
    237 class VcsRevisionDataTestCase(ModelDataBaseTestCase):
     191class VcsBugReferenceDataTestCase(ModelDataBaseTestCase):
    238192    def setUp(self):
    239         self.aoSamples = [VcsRevisionData(),];
     193        self.aoSamples = [VcsBugReferenceData(),];
    240194
    241195if __name__ == '__main__':
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