VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testmanager/core/testcaseargs.py@ 63694

Last change on this file since 63694 was 62484, checked in by vboxsync, 8 years ago

(C) 2016

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.6 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: testcaseargs.py 62484 2016-07-22 18:35:33Z vboxsync $
3
4"""
5Test Manager - Test Case Arguments Variations.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2012-2016 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.virtualbox.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Revision: 62484 $"
30
31
32# Standard python imports.
33import unittest;
34import sys;
35
36# Validation Kit imports.
37from common import utils;
38from testmanager.core.base import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMExceptionBase, \
39 TMRowNotFound;
40from testmanager.core.testcase import TestCaseData, TestCaseDependencyLogic, TestCaseGlobalRsrcDepLogic;
41
42# Python 3 hacks:
43if sys.version_info[0] >= 3:
44 long = int; # pylint: disable=W0622,C0103
45
46
47class TestCaseArgsData(ModelDataBase):
48 """
49 Test case argument variation.
50 """
51
52 ksIdAttr = 'idTestCaseArgs';
53 ksIdGenAttr = 'idGenTestCaseArgs';
54
55 ksParam_idTestCase = 'TestCaseArgs_idTestCase';
56 ksParam_idTestCaseArgs = 'TestCaseArgs_idTestCaseArgs';
57 ksParam_tsEffective = 'TestCaseArgs_tsEffective';
58 ksParam_tsExpire = 'TestCaseArgs_tsExpire';
59 ksParam_uidAuthor = 'TestCaseArgs_uidAuthor';
60 ksParam_idGenTestCaseArgs = 'TestCaseArgs_idGenTestCaseArgs';
61 ksParam_sArgs = 'TestCaseArgs_sArgs';
62 ksParam_cSecTimeout = 'TestCaseArgs_cSecTimeout';
63 ksParam_sTestBoxReqExpr = 'TestCaseArgs_sTestBoxReqExpr';
64 ksParam_sBuildReqExpr = 'TestCaseArgs_sBuildReqExpr';
65 ksParam_cGangMembers = 'TestCaseArgs_cGangMembers';
66 ksParam_sSubName = 'TestCaseArgs_sSubName';
67
68 kcDbColumns = 12;
69
70 kasAllowNullAttributes = [ 'idTestCase', 'idTestCaseArgs', 'tsEffective', 'tsExpire', 'uidAuthor', 'idGenTestCaseArgs',
71 'cSecTimeout', 'sTestBoxReqExpr', 'sBuildReqExpr', 'sSubName', ];
72
73 def __init__(self):
74 ModelDataBase.__init__(self);
75
76 #
77 # Initialize with defaults.
78 # See the database for explanations of each of these fields.
79 #
80 self.idTestCase = None;
81 self.idTestCaseArgs = None;
82 self.tsEffective = None;
83 self.tsExpire = None;
84 self.uidAuthor = None;
85 self.idGenTestCaseArgs = None;
86 self.sArgs = '';
87 self.cSecTimeout = None;
88 self.sTestBoxReqExpr = None;
89 self.sBuildReqExpr = None;
90 self.cGangMembers = 1;
91 self.sSubName = None;
92
93 def initFromDbRow(self, aoRow):
94 """
95 Re-initializes the object from a SELECT * FROM TestCaseArgs row.
96 Returns self. Raises exception if aoRow is None.
97 """
98 if aoRow is None:
99 raise TMRowNotFound('TestBoxStatus not found.');
100
101 self.idTestCase = aoRow[0];
102 self.idTestCaseArgs = aoRow[1];
103 self.tsEffective = aoRow[2];
104 self.tsExpire = aoRow[3];
105 self.uidAuthor = aoRow[4];
106 self.idGenTestCaseArgs = aoRow[5];
107 self.sArgs = aoRow[6];
108 self.cSecTimeout = aoRow[7];
109 self.sTestBoxReqExpr = aoRow[8];
110 self.sBuildReqExpr = aoRow[9];
111 self.cGangMembers = aoRow[10];
112 self.sSubName = aoRow[11];
113 return self;
114
115 def initFromDbWithId(self, oDb, idTestCaseArgs, tsNow = None, sPeriodBack = None):
116 """
117 Initialize from the database.
118 """
119 oDb.execute(self.formatSimpleNowAndPeriodQuery(oDb,
120 'SELECT *\n'
121 'FROM TestCaseArgs\n'
122 'WHERE idTestCaseArgs = %s\n'
123 , ( idTestCaseArgs,), tsNow, sPeriodBack));
124 aoRow = oDb.fetchOne()
125 if aoRow is None:
126 raise TMRowNotFound('idTestCaseArgs=%s not found (tsNow=%s sPeriodBack=%s)'
127 % (idTestCaseArgs, tsNow, sPeriodBack,));
128 return self.initFromDbRow(aoRow);
129
130 def initFromDbWithGenId(self, oDb, idGenTestCaseArgs):
131 """
132 Initialize from the database, given the generation ID of a row.
133 """
134 oDb.execute('SELECT * FROM TestCaseArgs WHERE idGenTestCaseArgs = %s', (idGenTestCaseArgs,));
135 return self.initFromDbRow(oDb.fetchOne());
136
137 def initFromValues(self, sArgs, cSecTimeout = None, sTestBoxReqExpr = None, sBuildReqExpr = None, # pylint: disable=R0913
138 cGangMembers = 1, idTestCase = None, idTestCaseArgs = None, tsEffective = None, tsExpire = None,
139 uidAuthor = None, idGenTestCaseArgs = None, sSubName = None):
140 """
141 Reinitialize from values.
142 Returns self.
143 """
144 self.idTestCase = idTestCase;
145 self.idTestCaseArgs = idTestCaseArgs;
146 self.tsEffective = tsEffective;
147 self.tsExpire = tsExpire;
148 self.uidAuthor = uidAuthor;
149 self.idGenTestCaseArgs = idGenTestCaseArgs;
150 self.sArgs = sArgs;
151 self.cSecTimeout = utils.parseIntervalSeconds(cSecTimeout);
152 self.sTestBoxReqExpr = sTestBoxReqExpr;
153 self.sBuildReqExpr = sBuildReqExpr;
154 self.cGangMembers = cGangMembers;
155 self.sSubName = sSubName;
156 return self;
157
158 def getAttributeParamNullValues(self, sAttr):
159 aoNilValues = ModelDataBase.getAttributeParamNullValues(self, sAttr);
160 if sAttr == 'cSecTimeout':
161 aoNilValues.insert(0, ''); # Prettier NULL value for cSecTimeout.
162 elif sAttr == 'sArgs':
163 aoNilValues = []; # No NULL value here, thank you.
164 return aoNilValues;
165
166 def _validateAndConvertAttribute(self, sAttr, sParam, oValue, aoNilValues, fAllowNull, oDb):
167 if sAttr == 'cSecTimeout' and oValue not in aoNilValues: # Allow human readable interval formats.
168 return utils.parseIntervalSeconds(oValue);
169
170 (oValue, sError) = ModelDataBase._validateAndConvertAttribute(self, sAttr, sParam, oValue, aoNilValues, fAllowNull, oDb);
171 if sError is None:
172 if sAttr == 'sTestBoxReqExpr':
173 sError = TestCaseData.validateTestBoxReqExpr(oValue);
174 elif sAttr == 'sBuildReqExpr':
175 sError = TestCaseData.validateBuildReqExpr(oValue);
176 return (oValue, sError);
177
178
179
180
181class TestCaseArgsDataEx(TestCaseArgsData):
182 """
183 Complete data set.
184 """
185
186 def __init__(self):
187 TestCaseArgsData.__init__(self);
188 self.oTestCase = None;
189 self.aoTestCasePreReqs = [];
190 self.aoGlobalRsrc = [];
191
192 def initFromDbRow(self, aoRow):
193 raise TMExceptionBase('Do not call me: %s' % (aoRow,))
194
195 def initFromDbRowEx(self, aoRow, oDb, tsConfigEff = None, tsRsrcEff = None):
196 """
197 Extended version of initFromDbRow that fills in the rest from the database.
198 """
199 TestCaseArgsData.initFromDbRow(self, aoRow);
200
201 if tsConfigEff is None: tsConfigEff = oDb.getCurrentTimestamp();
202 if tsRsrcEff is None: tsRsrcEff = oDb.getCurrentTimestamp();
203
204 self.oTestCase = TestCaseData().initFromDbWithId(oDb, self.idTestCase, tsConfigEff);
205 self.aoTestCasePreReqs = TestCaseDependencyLogic(oDb).getTestCaseDeps(self.idTestCase, tsConfigEff);
206 self.aoGlobalRsrc = TestCaseGlobalRsrcDepLogic(oDb).getTestCaseDeps(self.idTestCase, tsRsrcEff);
207
208 return self;
209
210 def initFromDbWithId(self, oDb, idTestCaseArgs, tsNow = None, sPeriodBack = None):
211 _ = oDb; _ = idTestCaseArgs; _ = tsNow; _ = sPeriodBack;
212 raise TMExceptionBase('Not supported.');
213
214 def initFromDbWithGenId(self, oDb, idGenTestCaseArgs):
215 _ = oDb; _ = idGenTestCaseArgs;
216 raise TMExceptionBase('Use initFromDbWithGenIdEx...');
217
218 def initFromDbWithGenIdEx(self, oDb, idGenTestCaseArgs, tsConfigEff = None, tsRsrcEff = None):
219 """
220 Initialize from the database, given the ID of a row.
221 """
222 oDb.execute('SELECT *, CURRENT_TIMESTAMP FROM TestCaseArgs WHERE idGenTestCaseArgs = %s', (idGenTestCaseArgs,));
223 aoRow = oDb.fetchOne();
224 return self.initFromDbRowEx(aoRow, oDb, tsConfigEff, tsRsrcEff);
225
226 def convertFromParamNull(self):
227 raise TMExceptionBase('Not implemented');
228
229 def convertToParamNull(self):
230 raise TMExceptionBase('Not implemented');
231
232 def isEqual(self, oOther):
233 raise TMExceptionBase('Not implemented');
234
235 def matchesTestBoxProps(self, oTestBoxData):
236 """
237 Checks if the all of the testbox related test requirements matches the
238 given testbox.
239
240 Returns True or False according to the expression, None on exception or
241 non-boolean expression result.
242 """
243 return TestCaseData.matchesTestBoxPropsEx(oTestBoxData, self.oTestCase.sTestBoxReqExpr) \
244 and TestCaseData.matchesTestBoxPropsEx(oTestBoxData, self.sTestBoxReqExpr);
245
246 def matchesBuildProps(self, oBuildDataEx):
247 """
248 Checks if the all of the build related test requirements matches the
249 given build.
250
251 Returns True or False according to the expression, None on exception or
252 non-boolean expression result.
253 """
254 return TestCaseData.matchesBuildPropsEx(oBuildDataEx, self.oTestCase.sBuildReqExpr) \
255 and TestCaseData.matchesBuildPropsEx(oBuildDataEx, self.sBuildReqExpr);
256
257
258class TestCaseArgsLogic(ModelLogicBase):
259 """
260 TestCaseArgs database logic.
261 """
262
263 def __init__(self, oDb):
264 ModelLogicBase.__init__(self, oDb);
265 self.dCache = None;
266
267
268 def areResourcesFree(self, oDataEx):
269 """
270 Checks if all global resources are currently still in existance and free.
271 Returns True/False. May raise exception on database error.
272 """
273
274 # Create a set of global resource IDs.
275 if len(oDataEx.aoGlobalRsrc) == 0:
276 return True;
277 asIdRsrcs = [str(oDep.idGlobalRsrc) for oDep, _ in oDataEx.aoGlobalRsrc];
278
279 # A record in the resource status table means it's allocated.
280 self._oDb.execute('SELECT COUNT(*)\n'
281 'FROM GlobalResourceStatuses\n'
282 'WHERE GlobalResourceStatuses.idGlobalRsrc IN (' + ', '.join(asIdRsrcs) + ')\n');
283 if self._oDb.fetchOne()[0] == 0:
284 # Check for disabled or deleted resources (we cannot allocate them).
285 self._oDb.execute('SELECT COUNT(*)\n'
286 'FROM GlobalResources\n'
287 'WHERE GlobalResources.idGlobalRsrc IN (' + ', '.join(asIdRsrcs) + ')\n'
288 ' AND GlobalResources.tsExpire = \'infinity\'::TIMESTAMP\n'
289 ' AND GlobalResources.fEnabled = TRUE\n');
290 if self._oDb.fetchOne()[0] == len(oDataEx.aoGlobalRsrc):
291 return True;
292 return False;
293
294 def getAll(self):
295 """Get list of objects of type TestCaseArgsData"""
296 self._oDb.execute('SELECT *\n'
297 'FROM TestCaseArgs\n'
298 'WHERE tsExpire = \'infinity\'::TIMESTAMP')
299 aaoRows = self._oDb.fetchAll()
300 aoRet = []
301 for aoRow in aaoRows:
302 aoRet.append(TestCaseArgsData().initFromDbRow(aoRow))
303
304 return aoRet
305
306 def getTestCaseArgs(self, idTestCase, tsNow = None, aiWhiteList = None):
307 """Get list of testcase's arguments variations"""
308 if aiWhiteList is None:
309 if tsNow is None:
310 self._oDb.execute('SELECT *\n'
311 'FROM TestCaseArgs\n'
312 'WHERE idTestCase = %s\n'
313 ' AND tsExpire = \'infinity\'::TIMESTAMP\n'
314 'ORDER BY TestCaseArgs.idTestCaseArgs\n'
315 , (idTestCase,));
316 else:
317 self._oDb.execute('SELECT *\n'
318 'FROM TestCaseArgs\n'
319 'WHERE idTestCase = %s\n'
320 ' AND tsExpire > %s\n'
321 ' AND tsEffective <= %s\n'
322 'ORDER BY TestCaseArgs.idTestCaseArgs\n'
323 , (idTestCase, tsNow, tsNow));
324 else:
325 sWhiteList = ','.join((str(x) for x in aiWhiteList));
326 if tsNow is None:
327 self._oDb.execute('SELECT *\n'
328 'FROM TestCaseArgs\n'
329 'WHERE idTestCase = %s\n'
330 ' AND tsExpire = \'infinity\'::TIMESTAMP\n'
331 ' AND idTestCaseArgs IN (' + sWhiteList + ')\n'
332 'ORDER BY TestCaseArgs.idTestCaseArgs\n'
333 , (idTestCase,));
334 else:
335 self._oDb.execute('SELECT *\n'
336 'FROM TestCaseArgs\n'
337 'WHERE idTestCase = %s\n'
338 ' AND tsExpire > %s\n'
339 ' AND tsEffective <= %s\n'
340 ' AND idTestCaseArgs IN (' + sWhiteList + ')\n'
341 'ORDER BY TestCaseArgs.idTestCaseArgs\n'
342 , (idTestCase, tsNow, tsNow));
343
344 aaoRows = self._oDb.fetchAll()
345 aoRet = []
346 for aoRow in aaoRows:
347 aoRet.append(TestCaseArgsData().initFromDbRow(aoRow))
348
349 return aoRet
350
351 def addTestCaseArgs(self, oTestCaseArgsData):
352 """Add Test Case Args record into DB"""
353 pass
354
355 def cachedLookup(self, idTestCaseArgs):
356 """
357 Looks up the most recent TestCaseArgsDataEx object for idTestCaseArg
358 via in an object cache.
359
360 Returns a shared TestCaseArgDataEx object. None if not found.
361 Raises exception on DB error.
362 """
363 if self.dCache is None:
364 self.dCache = self._oDb.getCache('TestCaseArgsDataEx');
365 oEntry = self.dCache.get(idTestCaseArgs, None);
366 if oEntry is None:
367 fNeedTsNow = False;
368 self._oDb.execute('SELECT *\n'
369 'FROM TestCaseArgs\n'
370 'WHERE idTestCaseArgs = %s\n'
371 ' AND tsExpire = \'infinity\'::TIMESTAMP\n'
372 , (idTestCaseArgs, ));
373 if self._oDb.getRowCount() == 0:
374 # Maybe it was deleted, try get the last entry.
375 self._oDb.execute('SELECT *\n'
376 'FROM TestCaseArgs\n'
377 'WHERE idTestCaseArgs = %s\n'
378 'ORDER BY tsExpire DESC\n'
379 'LIMIT 1\n'
380 , (idTestCaseArgs, ));
381 fNeedTsNow = True;
382 elif self._oDb.getRowCount() > 1:
383 raise self._oDb.integrityException('%s infinity rows for %s' % (self._oDb.getRowCount(), idTestCaseArgs));
384
385 if self._oDb.getRowCount() == 1:
386 aaoRow = self._oDb.fetchOne();
387 oEntry = TestCaseArgsDataEx();
388 tsNow = oEntry.initFromDbRow(aaoRow).tsEffective if fNeedTsNow else None;
389 oEntry.initFromDbRowEx(aaoRow, self._oDb, tsNow, tsNow);
390 self.dCache[idTestCaseArgs] = oEntry;
391 return oEntry;
392
393
394#
395# Unit testing.
396#
397
398# pylint: disable=C0111
399class TestCaseArgsDataTestCase(ModelDataBaseTestCase):
400 def setUp(self):
401 self.aoSamples = [TestCaseArgsData(),];
402
403if __name__ == '__main__':
404 unittest.main();
405 # not reached.
406
Note: See TracBrowser for help on using the repository browser.

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