VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testmanager/core/globalresource.py@ 65040

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

testmanager: More details in the system wide changelog.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.9 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: globalresource.py 65040 2016-12-31 02:29:50Z vboxsync $
3
4"""
5Test Manager - Global Resources.
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: 65040 $"
30
31
32# Standard python imports.
33import unittest;
34
35# Validation Kit imports.
36from testmanager.core.base import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMRowNotFound;
37
38
39class GlobalResourceData(ModelDataBase):
40 """
41 Global resource data
42 """
43
44 ksIdAttr = 'idGlobalRsrc';
45
46 ksParam_idGlobalRsrc = 'GlobalResource_idGlobalRsrc'
47 ksParam_tsEffective = 'GlobalResource_tsEffective'
48 ksParam_tsExpire = 'GlobalResource_tsExpire'
49 ksParam_uidAuthor = 'GlobalResource_uidAuthor'
50 ksParam_sName = 'GlobalResource_sName'
51 ksParam_sDescription = 'GlobalResource_sDescription'
52 ksParam_fEnabled = 'GlobalResource_fEnabled'
53
54 kasAllowNullAttributes = ['idGlobalRsrc', 'tsEffective', 'tsExpire', 'uidAuthor', 'sDescription' ];
55 kcchMin_sName = 2;
56 kcchMax_sName = 64;
57
58 def __init__(self):
59 ModelDataBase.__init__(self);
60
61 #
62 # Initialize with defaults.
63 # See the database for explanations of each of these fields.
64 #
65 self.idGlobalRsrc = None;
66 self.tsEffective = None;
67 self.tsExpire = None;
68 self.uidAuthor = None;
69 self.sName = None;
70 self.sDescription = None;
71 self.fEnabled = False
72
73 def initFromDbRow(self, aoRow):
74 """
75 Reinitialize from a SELECT * FROM GlobalResources row.
76 Returns self. Raises exception if no row.
77 """
78 if aoRow is None:
79 raise TMRowNotFound('Global resource not found.')
80
81 self.idGlobalRsrc = aoRow[0]
82 self.tsEffective = aoRow[1]
83 self.tsExpire = aoRow[2]
84 self.uidAuthor = aoRow[3]
85 self.sName = aoRow[4]
86 self.sDescription = aoRow[5]
87 self.fEnabled = aoRow[6]
88 return self
89
90 def initFromDbWithId(self, oDb, idGlobalRsrc, tsNow = None, sPeriodBack = None):
91 """
92 Initialize the object from the database.
93 """
94 oDb.execute(self.formatSimpleNowAndPeriodQuery(oDb,
95 'SELECT *\n'
96 'FROM GlobalResources\n'
97 'WHERE idGlobalRsrc = %s\n'
98 , ( idGlobalRsrc,), tsNow, sPeriodBack));
99 aoRow = oDb.fetchOne()
100 if aoRow is None:
101 raise TMRowNotFound('idGlobalRsrc=%s not found (tsNow=%s sPeriodBack=%s)' % (idGlobalRsrc, tsNow, sPeriodBack,));
102 return self.initFromDbRow(aoRow);
103
104 def isEqual(self, oOther):
105 """
106 Compares two instances.
107 """
108 return self.idGlobalRsrc == oOther.idGlobalRsrc \
109 and str(self.tsEffective) == str(oOther.tsEffective) \
110 and str(self.tsExpire) == str(oOther.tsExpire) \
111 and self.uidAuthor == oOther.uidAuthor \
112 and self.sName == oOther.sName \
113 and self.sDescription == oOther.sDescription \
114 and self.fEnabled == oOther.fEnabled
115
116
117class GlobalResourceLogic(ModelLogicBase):
118 """
119 Global resource logic.
120 """
121
122 def __init__(self, oDb):
123 ModelLogicBase.__init__(self, oDb)
124 self.dCache = None;
125
126 def fetchForListing(self, iStart, cMaxRows, tsNow):
127 """
128 Returns an array (list) of FailureReasonData items, empty list if none.
129 Raises exception on error.
130 """
131
132 if tsNow is None:
133 self._oDb.execute('SELECT *\n'
134 'FROM GlobalResources\n'
135 'WHERE tsExpire = \'infinity\'::TIMESTAMP\n'
136 'ORDER BY idGlobalRsrc DESC\n'
137 'LIMIT %s OFFSET %s\n'
138 , (cMaxRows, iStart,));
139 else:
140 self._oDb.execute('SELECT *\n'
141 'FROM GlobalResources\n'
142 'WHERE tsExpire > %s\n'
143 ' AND tsEffective <= %s\n'
144 'ORDER BY idGlobalRsrc DESC\n'
145 'LIMIT %s OFFSET %s\n'
146 , (tsNow, tsNow, cMaxRows, iStart,))
147
148 aoRows = []
149 for aoRow in self._oDb.fetchAll():
150 aoRows.append(GlobalResourceData().initFromDbRow(aoRow))
151 return aoRows
152
153
154 def cachedLookup(self, idGlobalRsrc):
155 """
156 Looks up the most recent GlobalResourceData object for idGlobalRsrc
157 via an object cache.
158
159 Returns a shared GlobalResourceData object. None if not found.
160 Raises exception on DB error.
161 """
162 if self.dCache is None:
163 self.dCache = self._oDb.getCache('GlobalResourceData');
164 oEntry = self.dCache.get(idGlobalRsrc, None);
165 if oEntry is None:
166 self._oDb.execute('SELECT *\n'
167 'FROM GlobalResources\n'
168 'WHERE idGlobalRsrc = %s\n'
169 ' AND tsExpire = \'infinity\'::TIMESTAMP\n'
170 , (idGlobalRsrc, ));
171 if self._oDb.getRowCount() == 0:
172 # Maybe it was deleted, try get the last entry.
173 self._oDb.execute('SELECT *\n'
174 'FROM GlobalResources\n'
175 'WHERE idGlobalRsrc = %s\n'
176 'ORDER BY tsExpire DESC\n'
177 'LIMIT 1\n'
178 , (idGlobalRsrc, ));
179 elif self._oDb.getRowCount() > 1:
180 raise self._oDb.integrityException('%s infinity rows for %s' % (self._oDb.getRowCount(), idGlobalRsrc));
181
182 if self._oDb.getRowCount() == 1:
183 aaoRow = self._oDb.fetchOne();
184 oEntry = GlobalResourceData();
185 oEntry.initFromDbRow(aaoRow);
186 self.dCache[idGlobalRsrc] = oEntry;
187 return oEntry;
188
189
190 def getAll(self, tsEffective = None):
191 """
192 Gets all global resources.
193
194 Returns an array of GlobalResourceData instances on success (can be
195 empty). Raises exception on database error.
196 """
197 if tsEffective is not None:
198 self._oDb.execute('SELECT *\n'
199 'FROM GlobalResources\n'
200 'WHERE tsExpire > %s\n'
201 ' AND tsEffective <= %s\n'
202 , (tsEffective, tsEffective));
203 else:
204 self._oDb.execute('SELECT *\n'
205 'FROM GlobalResources\n'
206 'WHERE tsExpire = \'infinity\'::TIMESTAMP\n');
207 aaoRows = self._oDb.fetchAll();
208 aoRet = [];
209 for aoRow in aaoRows:
210 aoRet.append(GlobalResourceData().initFromDbRow(aoRow));
211
212 return aoRet;
213
214 def addGlobalResource(self, uidAuthor, oData):
215 """Add Global Resource DB record"""
216 self._oDb.execute('SELECT * FROM add_globalresource(%s, %s, %s, %s);',
217 (uidAuthor,
218 oData.sName,
219 oData.sDescription,
220 oData.fEnabled))
221 self._oDb.commit()
222 return True
223
224 def editGlobalResource(self, uidAuthor, idGlobalRsrc, oData):
225 """Modify Global Resource DB record"""
226 # Check if anything has been changed
227 oGlobalResourcesDataOld = self.getById(idGlobalRsrc)
228 if oGlobalResourcesDataOld.isEqual(oData):
229 # Nothing has been changed, do nothing
230 return True
231
232 self._oDb.execute('SELECT * FROM update_globalresource(%s, %s, %s, %s, %s);',
233 (uidAuthor,
234 idGlobalRsrc,
235 oData.sName,
236 oData.sDescription,
237 oData.fEnabled))
238 self._oDb.commit()
239 return True
240
241 def remove(self, uidAuthor, idGlobalRsrc):
242 """Delete Global Resource DB record"""
243 self._oDb.execute('SELECT * FROM del_globalresource(%s, %s);',
244 (uidAuthor, idGlobalRsrc))
245 self._oDb.commit()
246 return True
247
248 def getById(self, idGlobalRsrc):
249 """
250 Get global resource record by its id
251 """
252 self._oDb.execute('SELECT *\n'
253 'FROM GlobalResources\n'
254 'WHERE tsExpire = \'infinity\'::timestamp\n'
255 ' AND idGlobalRsrc=%s;', (idGlobalRsrc,))
256
257 aRows = self._oDb.fetchAll()
258 if len(aRows) not in (0, 1):
259 raise self._oDb.integrityException('Duplicate global resource entry with ID %u (current)' % (idGlobalRsrc,));
260 try:
261 return GlobalResourceData().initFromDbRow(aRows[0])
262 except IndexError:
263 raise TMRowNotFound('Global resource not found.')
264
265 def allocateResources(self, idTestBox, aoGlobalRsrcs, fCommit = False):
266 """
267 Allocates the given global resource.
268
269 Returns True of successfully allocated the resources, False if not.
270 May raise exception on DB error.
271 """
272 # Quit quickly if there is nothing to alloocate.
273 if len(aoGlobalRsrcs) == 0:
274 return True;
275
276 #
277 # Note! Someone else might have allocated the resources since the
278 # scheduler check that they were available. In such case we
279 # need too quietly rollback and return FALSE.
280 #
281 self._oDb.execute('SAVEPOINT allocateResources');
282
283 for oGlobalRsrc in aoGlobalRsrcs:
284 try:
285 self._oDb.execute('INSERT INTO GlobalResourceStatuses (idGlobalRsrc, idTestBox)\n'
286 'VALUES (%s, %s)', (oGlobalRsrc.idGlobalRsrc, idTestBox, ) );
287 except self._oDb.oXcptError:
288 self._oDb.execute('ROLLBACK TO SAVEPOINT allocateResources');
289 return False;
290
291 self._oDb.execute('RELEASE SAVEPOINT allocateResources');
292 self._oDb.maybeCommit(fCommit);
293 return True;
294
295 def freeGlobalResourcesByTestBox(self, idTestBox, fCommit = False):
296 """
297 Frees all global resources own by the given testbox.
298 Returns True. May raise exception on DB error.
299 """
300 self._oDb.execute('DELETE FROM GlobalResourceStatuses\n'
301 'WHERE idTestBox = %s\n', (idTestBox, ) );
302 self._oDb.maybeCommit(fCommit);
303 return True;
304
305#
306# Unit testing.
307#
308
309# pylint: disable=C0111
310class GlobalResourceDataTestCase(ModelDataBaseTestCase):
311 def setUp(self):
312 self.aoSamples = [GlobalResourceData(),];
313
314if __name__ == '__main__':
315 unittest.main();
316 # not reached.
317
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