VirtualBox

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

Last change on this file since 76553 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • 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 76553 2019-01-01 01:45:53Z vboxsync $
3
4"""
5Test Manager - Global Resources.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2012-2019 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: 76553 $"
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, aiSortColumns = None):
127 """
128 Returns an array (list) of FailureReasonData items, empty list if none.
129 Raises exception on error.
130 """
131 _ = aiSortColumns;
132
133 if tsNow is None:
134 self._oDb.execute('SELECT *\n'
135 'FROM GlobalResources\n'
136 'WHERE tsExpire = \'infinity\'::TIMESTAMP\n'
137 'ORDER BY idGlobalRsrc DESC\n'
138 'LIMIT %s OFFSET %s\n'
139 , (cMaxRows, iStart,));
140 else:
141 self._oDb.execute('SELECT *\n'
142 'FROM GlobalResources\n'
143 'WHERE tsExpire > %s\n'
144 ' AND tsEffective <= %s\n'
145 'ORDER BY idGlobalRsrc DESC\n'
146 'LIMIT %s OFFSET %s\n'
147 , (tsNow, tsNow, cMaxRows, iStart,))
148
149 aoRows = []
150 for aoRow in self._oDb.fetchAll():
151 aoRows.append(GlobalResourceData().initFromDbRow(aoRow))
152 return aoRows
153
154
155 def cachedLookup(self, idGlobalRsrc):
156 """
157 Looks up the most recent GlobalResourceData object for idGlobalRsrc
158 via an object cache.
159
160 Returns a shared GlobalResourceData object. None if not found.
161 Raises exception on DB error.
162 """
163 if self.dCache is None:
164 self.dCache = self._oDb.getCache('GlobalResourceData');
165 oEntry = self.dCache.get(idGlobalRsrc, None);
166 if oEntry is None:
167 self._oDb.execute('SELECT *\n'
168 'FROM GlobalResources\n'
169 'WHERE idGlobalRsrc = %s\n'
170 ' AND tsExpire = \'infinity\'::TIMESTAMP\n'
171 , (idGlobalRsrc, ));
172 if self._oDb.getRowCount() == 0:
173 # Maybe it was deleted, try get the last entry.
174 self._oDb.execute('SELECT *\n'
175 'FROM GlobalResources\n'
176 'WHERE idGlobalRsrc = %s\n'
177 'ORDER BY tsExpire DESC\n'
178 'LIMIT 1\n'
179 , (idGlobalRsrc, ));
180 elif self._oDb.getRowCount() > 1:
181 raise self._oDb.integrityException('%s infinity rows for %s' % (self._oDb.getRowCount(), idGlobalRsrc));
182
183 if self._oDb.getRowCount() == 1:
184 aaoRow = self._oDb.fetchOne();
185 oEntry = GlobalResourceData();
186 oEntry.initFromDbRow(aaoRow);
187 self.dCache[idGlobalRsrc] = oEntry;
188 return oEntry;
189
190
191 def getAll(self, tsEffective = None):
192 """
193 Gets all global resources.
194
195 Returns an array of GlobalResourceData instances on success (can be
196 empty). Raises exception on database error.
197 """
198 if tsEffective is not None:
199 self._oDb.execute('SELECT *\n'
200 'FROM GlobalResources\n'
201 'WHERE tsExpire > %s\n'
202 ' AND tsEffective <= %s\n'
203 , (tsEffective, tsEffective));
204 else:
205 self._oDb.execute('SELECT *\n'
206 'FROM GlobalResources\n'
207 'WHERE tsExpire = \'infinity\'::TIMESTAMP\n');
208 aaoRows = self._oDb.fetchAll();
209 aoRet = [];
210 for aoRow in aaoRows:
211 aoRet.append(GlobalResourceData().initFromDbRow(aoRow));
212
213 return aoRet;
214
215 def addGlobalResource(self, uidAuthor, oData):
216 """Add Global Resource DB record"""
217 self._oDb.execute('SELECT * FROM add_globalresource(%s, %s, %s, %s);',
218 (uidAuthor,
219 oData.sName,
220 oData.sDescription,
221 oData.fEnabled))
222 self._oDb.commit()
223 return True
224
225 def editGlobalResource(self, uidAuthor, idGlobalRsrc, oData):
226 """Modify Global Resource DB record"""
227 # Check if anything has been changed
228 oGlobalResourcesDataOld = self.getById(idGlobalRsrc)
229 if oGlobalResourcesDataOld.isEqual(oData):
230 # Nothing has been changed, do nothing
231 return True
232
233 self._oDb.execute('SELECT * FROM update_globalresource(%s, %s, %s, %s, %s);',
234 (uidAuthor,
235 idGlobalRsrc,
236 oData.sName,
237 oData.sDescription,
238 oData.fEnabled))
239 self._oDb.commit()
240 return True
241
242 def remove(self, uidAuthor, idGlobalRsrc):
243 """Delete Global Resource DB record"""
244 self._oDb.execute('SELECT * FROM del_globalresource(%s, %s);',
245 (uidAuthor, idGlobalRsrc))
246 self._oDb.commit()
247 return True
248
249 def getById(self, idGlobalRsrc):
250 """
251 Get global resource record by its id
252 """
253 self._oDb.execute('SELECT *\n'
254 'FROM GlobalResources\n'
255 'WHERE tsExpire = \'infinity\'::timestamp\n'
256 ' AND idGlobalRsrc=%s;', (idGlobalRsrc,))
257
258 aRows = self._oDb.fetchAll()
259 if len(aRows) not in (0, 1):
260 raise self._oDb.integrityException('Duplicate global resource entry with ID %u (current)' % (idGlobalRsrc,));
261 try:
262 return GlobalResourceData().initFromDbRow(aRows[0])
263 except IndexError:
264 raise TMRowNotFound('Global resource not found.')
265
266 def allocateResources(self, idTestBox, aoGlobalRsrcs, fCommit = False):
267 """
268 Allocates the given global resource.
269
270 Returns True of successfully allocated the resources, False if not.
271 May raise exception on DB error.
272 """
273 # Quit quickly if there is nothing to alloocate.
274 if not aoGlobalRsrcs:
275 return True;
276
277 #
278 # Note! Someone else might have allocated the resources since the
279 # scheduler check that they were available. In such case we
280 # need too quietly rollback and return FALSE.
281 #
282 self._oDb.execute('SAVEPOINT allocateResources');
283
284 for oGlobalRsrc in aoGlobalRsrcs:
285 try:
286 self._oDb.execute('INSERT INTO GlobalResourceStatuses (idGlobalRsrc, idTestBox)\n'
287 'VALUES (%s, %s)', (oGlobalRsrc.idGlobalRsrc, idTestBox, ) );
288 except self._oDb.oXcptError:
289 self._oDb.execute('ROLLBACK TO SAVEPOINT allocateResources');
290 return False;
291
292 self._oDb.execute('RELEASE SAVEPOINT allocateResources');
293 self._oDb.maybeCommit(fCommit);
294 return True;
295
296 def freeGlobalResourcesByTestBox(self, idTestBox, fCommit = False):
297 """
298 Frees all global resources own by the given testbox.
299 Returns True. May raise exception on DB error.
300 """
301 self._oDb.execute('DELETE FROM GlobalResourceStatuses\n'
302 'WHERE idTestBox = %s\n', (idTestBox, ) );
303 self._oDb.maybeCommit(fCommit);
304 return True;
305
306#
307# Unit testing.
308#
309
310# pylint: disable=C0111
311class GlobalResourceDataTestCase(ModelDataBaseTestCase):
312 def setUp(self):
313 self.aoSamples = [GlobalResourceData(),];
314
315if __name__ == '__main__':
316 unittest.main();
317 # not reached.
318
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