- Timestamp:
- May 26, 2020 6:50:43 PM (5 years ago)
- 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 2 2 # -*- coding: utf-8 -*- 3 3 # $Id$ 4 # pylint: disable=line-too-long5 4 6 5 """ … … 44 43 45 44 # Test Manager imports 46 from testmanager.core.db import TMDatabaseConnection; 47 from testmanager.core.vcsrevisions import VcsRevisionData, VcsRevisionLogic; 48 from common import utils; 45 from testmanager.config import g_kaBugTrackers; 46 from testmanager.core.db import TMDatabaseConnection; 47 from testmanager.core.vcsrevisions import VcsRevisionData, VcsRevisionLogic; 48 from testmanager.core.vcsbugreference import VcsBugReferenceData, VcsBugReferenceLogic; 49 from common import utils; 50 51 # Python 3 hacks: 52 if sys.version_info[0] >= 3: 53 long = int; # pylint: disable=redefined-builtin,invalid-name 54 49 55 50 56 class VcsImport(object): # pylint: disable=too-few-public-methods … … 52 58 Imports revision history from a VSC into the Test Manager database. 53 59 """ 60 61 class BugTracker(object): 62 def __init__(self, sDbName, sTag): 63 self.sDbName = sDbName; 64 self.sTag = sTag; 65 54 66 55 67 def __init__(self): … … 59 71 60 72 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', 62 76 help = 'Adds a extra option to the command retrieving the log.'); 63 77 oParser.add_option('-f', '--full', dest = 'fFull', action = 'store_true', … … 93 107 oDb = TMDatabaseConnection(); 94 108 oLogic = VcsRevisionLogic(oDb); 109 oBugLogic = VcsBugReferenceLogic(oDb); 95 110 96 111 # Where to start. 97 112 iStartRev = 0; 98 113 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); 100 118 if iStartRev == 0: 101 119 iStartRev = self.oConfig.iStartRevision; … … 118 136 # Parse the XML and add the entries to the database. 119 137 oParser = ET.XMLParser(target = ET.TreeBuilder(), encoding = 'utf-8'); 120 oParser.feed(sLogXml.encode('utf-8')); # does its own decoding andprocessOutputChecked 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. 121 139 oRoot = oParser.close(); 122 140 123 141 for oLogEntry in oRoot.findall('logentry'): 124 142 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. 126 144 sDate = oLogEntry.findtext('date').strip(); 127 sMessage = oLogEntry.findtext('msg', '').strip(); 145 sRawMsg = oLogEntry.findtext('msg', '').strip(); 146 sMessage = sRawMsg; 128 147 if sMessage == '': 129 148 sMessage = ' '; … … 133 152 utils.printOut(u'sDate=%s iRev=%u sAuthor=%s sMsg[%s]=%s' 134 153 % (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 137 189 oDb.commit(); 138 190 -
trunk/src/VBox/ValidationKit/testmanager/config.py
r83418 r84550 148 148 149 149 150 ## @name Bug Trackers and VCS reference tags. 151 ## @{ 152 class 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 162 g_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. 178 g_ksSmtpHost = 'internal-mail-router.oracle.com'; 179 ## SMTP server port number. 180 g_kcSmtpPort = 25; 181 ## Default email 'From' for email alert. 182 g_ksAlertFrom = '[email protected]'; 183 ## Subject for email alert. 184 g_ksAlertSubject = 'Virtual Test Sheriff Alert'; 185 ## List of users to send alerts. 186 g_asAlertList = ['lelik', 'werner']; 187 ## iLOM password. 188 g_ksLomPassword = 'password'; 189 190 ## @} 191 192 150 193 ## @name Partial Database Dump 151 194 ## @{ … … 207 250 ## @} 208 251 209 ## @name Virtual Sheriff email alerts210 ## @{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 3 3 4 4 """ 5 Test Manager - Vcs Revisions5 Test Manager - VcsBugReferences 6 6 """ 7 7 … … 37 37 38 38 39 class Vcs RevisionData(ModelDataBase):39 class VcsBugReferenceData(ModelDataBase): 40 40 """ 41 A version control system (VCS) revision.41 A version control system (VCS) bug tracker reference (commit message tag). 42 42 """ 43 43 44 #kasIdAttr = ['sRepository', iRevision];44 #kasIdAttr = ['sRepository','iRevision', 'sBugTracker', 'iBugNo']; 45 45 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'; 51 50 52 51 kasAllowNullAttributes = [ ]; 53 kfAllowUnicode_sMessage = True;54 kcchMax_sMessage = 8192;55 52 56 53 def __init__(self): … … 63 60 self.sRepository = None; 64 61 self.iRevision = None; 65 self.tsCreated = None; 66 self.sAuthor = None; 67 self.sMessage = None; 62 self.sBugTracker = None; 63 self.lBugNo = None; 68 64 69 65 def initFromDbRow(self, aoRow): 70 66 """ 71 Re-initializes the object from a SELECT * FROM Vcs Revisions row.67 Re-initializes the object from a SELECT * FROM VcsBugReferences row. 72 68 Returns self. Raises exception if aoRow is None. 73 69 """ 74 70 if aoRow is None: 75 raise TMExceptionBase('Vcs Revisionnot found.');71 raise TMExceptionBase('VcsBugReference not found.'); 76 72 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]; 82 77 return self; 83 78 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): 95 80 """ 96 81 Reinitializes form a set of values. … … 99 84 self.sRepository = sRepository; 100 85 self.iRevision = iRevision; 101 self.tsCreated = tsCreated; 102 self.sAuthor = sAuthor; 103 self.sMessage = sMessage; 86 self.sBugTracker = sBugTracker; 87 self.lBugNo = lBugNo; 104 88 return self; 105 89 106 90 107 class Vcs RevisionLogic(ModelLogicBase): # pylint: disable=too-few-public-methods91 class VcsBugReferenceLogic(ModelLogicBase): # pylint: disable=too-few-public-methods 108 92 """ 109 VCS revision s database logic.93 VCS revision <-> bug tracker references database logic. 110 94 """ 111 95 … … 118 102 Fetches VCS revisions for listing. 119 103 120 Returns an array (list) of Vcs RevisionData items, empty list if none.104 Returns an array (list) of VcsBugReferenceData items, empty list if none. 121 105 Raises exception on error. 122 106 """ 123 107 _ = 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(''' 109 SELECT * 110 FROM VcsBugReferences 111 ORDER BY sRepository, iRevision, sBugTracker, lBugNo 112 LIMIT %s OFFSET %s 113 ''', (cMaxRows, iStart,)); 129 114 130 115 aoRows = []; 131 116 for _ in range(self._oDb.getRowCount()): 132 aoRows.append(Vcs RevisionData().initFromDbRow(self._oDb.fetchOne()));117 aoRows.append(VcsBugReferenceData().initFromDbRow(self._oDb.fetchOne())); 133 118 return aoRows; 134 119 135 def tryFetch(self, sRepository, iRevision):120 def exists(self, oData): 136 121 """ 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. 139 124 Raises exception on input and database errors. 140 125 """ 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(''' 127 SELECT COUNT(*) 128 FROM VcsBugReferences 129 WHERE 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; 149 138 150 139 … … 153 142 # 154 143 155 def addVcs Revision(self, oData, fCommit = False):144 def addVcsBugReference(self, oData, fCommit = False): 156 145 """ 157 146 Adds (or updates) a tree revision record. … … 159 148 """ 160 149 161 # Check Vcs RevisionData before do anything150 # Check VcsBugReferenceData before do anything 162 151 dDataErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Add); 163 152 if dDataErrors: 164 raise TMExceptionBase('Invalid data passed to addVcs Revision(): %s' % (dDataErrors,));153 raise TMExceptionBase('Invalid data passed to addVcsBugReference(): %s' % (dDataErrors,)); 165 154 166 155 # Does it already exist? 167 oOldData = self.tryFetch(oData.sRepository, oData.iRevision); 168 if oOldData is None: 156 if not self.exists(oData): 169 157 # New row. 170 self._oDb.execute('INSERT INTO Vcs Revisions (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' 172 160 , ( oData.sRepository, 173 161 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, 191 164 )); 192 165 … … 199 172 if the repository is not known to us: 200 173 """ 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(''' 175 SELECT iRevision 176 FROM VcsBugReferences 177 WHERE sRepository = %s 178 ORDER BY iRevision DESC 179 LIMIT 1 180 ''', ( sRepository, )); 207 181 if self._oDb.getRowCount() == 0: 208 182 return 0; 209 183 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;230 184 231 185 … … 235 189 236 190 # pylint: disable=missing-docstring 237 class Vcs RevisionDataTestCase(ModelDataBaseTestCase):191 class VcsBugReferenceDataTestCase(ModelDataBaseTestCase): 238 192 def setUp(self): 239 self.aoSamples = [Vcs RevisionData(),];193 self.aoSamples = [VcsBugReferenceData(),]; 240 194 241 195 if __name__ == '__main__':
Note:
See TracChangeset
for help on using the changeset viewer.