VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testmanager/core/testboxstatus.py@ 61468

Last change on this file since 61468 was 61468, checked in by vboxsync, 9 years ago

testmanager: Adding sComment and fRawMode fields to TestBoxes and moves the strings into a separate shared string table.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.2 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: testboxstatus.py 61468 2016-06-05 02:55:32Z vboxsync $
3
4"""
5Test Manager - TestBoxStatus.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2012-2015 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: 61468 $"
30
31
32# Standard python imports.
33import unittest;
34
35# Validation Kit imports.
36from testmanager.core.base import ModelDataBase, ModelDataBaseTestCase, ModelLogicBase, TMTooManyRows, TMRowNotFound;
37from testmanager.core.testbox import TestBoxData;
38
39
40class TestBoxStatusData(ModelDataBase):
41 """
42 TestBoxStatus Data.
43 """
44
45 ## @name TestBoxState_T
46 # @{
47 ksTestBoxState_Idle = 'idle';
48 ksTestBoxState_Testing = 'testing';
49 ksTestBoxState_GangGathering = 'gang-gathering';
50 ksTestBoxState_GangGatheringTimedOut = 'gang-gathering-timedout';
51 ksTestBoxState_GangTesting = 'gang-testing';
52 ksTestBoxState_GangCleanup = 'gang-cleanup';
53 ksTestBoxState_Rebooting = 'rebooting';
54 ksTestBoxState_Upgrading = 'upgrading';
55 ksTestBoxState_UpgradingAndRebooting = 'upgrading-and-rebooting';
56 ksTestBoxState_DoingSpecialCmd = 'doing-special-cmd';
57 ## @}
58
59 ksParam_idTestBox = 'TestBoxStatus_idTestBox';
60 ksParam_idGenTestBox = 'TestBoxStatus_idGenTestBox'
61 ksParam_tsUpdated = 'TestBoxStatus_tsUpdated';
62 ksParam_enmState = 'TestBoxStatus_enmState';
63 ksParam_idTestSet = 'TestBoxStatus_idTestSet';
64
65 kasAllowNullAttributes = ['idTestSet', ];
66 kasValidValues_enmState = \
67 [
68 ksTestBoxState_Idle, ksTestBoxState_Testing, ksTestBoxState_GangGathering,
69 ksTestBoxState_GangGatheringTimedOut, ksTestBoxState_GangTesting, ksTestBoxState_GangCleanup,
70 ksTestBoxState_Rebooting, ksTestBoxState_Upgrading, ksTestBoxState_UpgradingAndRebooting,
71 ksTestBoxState_DoingSpecialCmd,
72 ];
73
74 def __init__(self):
75 ModelDataBase.__init__(self);
76
77 #
78 # Initialize with defaults.
79 # See the database for explanations of each of these fields.
80 #
81 self.idTestBox = None;
82 self.idGenTestBox = None;
83 self.tsUpdated = None;
84 self.enmState = self.ksTestBoxState_Idle;
85 self.idTestSet = None;
86
87 def initFromDbRow(self, aoRow):
88 """
89 Internal worker for initFromDbWithId and initFromDbWithGenId as well as
90 TestBoxStatusLogic.
91 """
92
93 if aoRow is None:
94 raise TMRowNotFound('TestBoxStatus not found.');
95
96 self.idTestBox = aoRow[0];
97 self.idGenTestBox = aoRow[1];
98 self.tsUpdated = aoRow[2];
99 self.enmState = aoRow[3];
100 self.idTestSet = aoRow[4];
101 return self;
102
103 def initFromDbWithId(self, oDb, idTestBox):
104 """
105 Initialize the object from the database.
106 """
107 oDb.execute('SELECT *\n'
108 'FROM TestBoxStatuses\n'
109 'WHERE idTestBox = %s\n'
110 , (idTestBox, ) );
111 return self.initFromDbRow(oDb.fetchOne());
112
113 def initFromDbWithGenId(self, oDb, idGenTestBox):
114 """
115 Initialize the object from the database.
116 """
117 oDb.execute('SELECT *\n'
118 'FROM TestBoxStatuses\n'
119 'WHERE idGenTestBox = %s\n'
120 , (idGenTestBox, ) );
121 return self.initFromDbRow(oDb.fetchOne());
122
123
124class TestBoxStatusLogic(ModelLogicBase):
125 """
126 TestBoxStatus logic.
127 """
128
129 ## The number of seconds between each time to call touchStatus() when
130 # returning CMD_IDLE.
131 kcSecIdleTouchStatus = 120;
132
133
134 def __init__(self, oDb):
135 ModelLogicBase.__init__(self, oDb);
136
137
138 def tryFetchStatus(self, idTestBox):
139 """
140 Attempts to fetch the status of the given testbox.
141
142 Returns a TestBoxStatusData object on success.
143 Returns None if no status was found.
144 Raises exception on other errors.
145 """
146 self._oDb.execute('SELECT *\n'
147 'FROM TestBoxStatuses\n'
148 'WHERE idTestBox = %s\n',
149 (idTestBox,));
150 if self._oDb.getRowCount() == 0:
151 return None;
152 oStatus = TestBoxStatusData();
153 return oStatus.initFromDbRow(self._oDb.fetchOne());
154
155 def tryFetchStatusAndConfig(self, idTestBox, sTestBoxUuid, sTestBoxAddr):
156 """
157 Tries to fetch the testbox status and current testbox config.
158
159 Returns (TestBoxStatusData, TestBoxData) on success, (None, None) if
160 not found. May throw an exception on database error.
161 """
162 self._oDb.execute('SELECT TestBoxStatuses.*,\n'
163 ' TestBoxes.*,\n'
164 ' Str1.sValue,\n'
165 ' Str2.sValue,\n'
166 ' Str3.sValue,\n'
167 ' Str4.sValue,\n'
168 ' Str5.sValue,\n'
169 ' Str6.sValue,\n'
170 ' Str7.sValue,\n'
171 ' Str8.sValue\n'
172 'FROM TestBoxStatuses,\n'
173 ' TestBoxes\n'
174 ' LEFT OUTER JOIN TestBoxStrTab Str1 ON idStrDescription = Str1.idStr\n'
175 ' LEFT OUTER JOIN TestBoxStrTab Str2 ON idStrComment = Str2.idStr\n'
176 ' LEFT OUTER JOIN TestBoxStrTab Str3 ON idStrOs = Str3.idStr\n'
177 ' LEFT OUTER JOIN TestBoxStrTab Str4 ON idStrOsVersion = Str4.idStr\n'
178 ' LEFT OUTER JOIN TestBoxStrTab Str5 ON idStrCpuVendor = Str5.idStr\n'
179 ' LEFT OUTER JOIN TestBoxStrTab Str6 ON idStrCpuArch = Str6.idStr\n'
180 ' LEFT OUTER JOIN TestBoxStrTab Str7 ON idStrCpuName = Str7.idStr\n'
181 ' LEFT OUTER JOIN TestBoxStrTab Str8 ON idStrReport = Str8.idStr\n'
182 'WHERE TestBoxStatuses.idTestBox = %s\n'
183 ' AND TestBoxes.idTestBox = %s\n'
184 ' AND TestBoxes.tsExpire = \'infinity\'::TIMESTAMP\n'
185 ' AND TestBoxes.uuidSystem = %s\n'
186 ' AND TestBoxes.ip = %s\n'
187 , (idTestBox,
188 idTestBox,
189 sTestBoxUuid,
190 sTestBoxAddr,
191 ));
192 cRows = self._oDb.getRowCount();
193 if cRows != 1:
194 if cRows != 0:
195 raise TMTooManyRows('tryFetchStatusForCommandReq got %s rows for idTestBox=%s' % (cRows, idTestBox));
196 return (None, None);
197 aoRow = self._oDb.fetchOne();
198 return (TestBoxStatusData().initFromDbRow(aoRow[0:5]), TestBoxData().initFromDbRow(aoRow[5:]));
199
200
201 def insertIdleStatus(self, idTestBox, idGenTestBox, fCommit = False):
202 """
203 Inserts an idle status for the specified testbox.
204 """
205 self._oDb.execute('INSERT INTO TestBoxStatuses (\n'
206 ' idTestBox,\n'
207 ' idGenTestBox,\n'
208 ' enmState,\n'
209 ' idTestSet)\n'
210 'VALUES ( %s,\n'
211 ' %s,\n'
212 ' \'idle\'::TestBoxState_T,\n'
213 ' NULL)\n',
214 (idTestBox, idGenTestBox) );
215 self._oDb.maybeCommit(fCommit);
216 return True;
217
218 def touchStatus(self, idTestBox, fCommit = False):
219 """
220 Touches the testbox status row, i.e. sets tsUpdated to the current time.
221 """
222 self._oDb.execute('UPDATE TestBoxStatuses\n'
223 'SET tsUpdated = CURRENT_TIMESTAMP\n'
224 'WHERE idTestBox = %s\n'
225 , (idTestBox,));
226 self._oDb.maybeCommit(fCommit);
227 return True;
228
229 def updateState(self, idTestBox, sNewState, idTestSet = None, fCommit = False):
230 """
231 Updates the testbox state.
232 """
233 self._oDb.execute('UPDATE TestBoxStatuses\n'
234 'SET enmState = %s,\n'
235 ' idTestSet = %s,\n'
236 ' tsUpdated = CURRENT_TIMESTAMP\n'
237 'WHERE idTestBox = %s\n',
238 (sNewState, idTestSet, idTestBox));
239 self._oDb.maybeCommit(fCommit);
240 return True;
241
242 def updateGangStatus(self, idTestSetGangLeader, sNewState, fCommit = False):
243 """
244 Update the state of all members of a gang.
245 """
246 self._oDb.execute('UPDATE TestBoxStatuses\n'
247 'SET enmState = %s,\n'
248 ' tsUpdated = CURRENT_TIMESTAMP\n'
249 'WHERE idTestBox IN (SELECT idTestBox\n'
250 ' FROM TestSets\n'
251 ' WHERE idTestSetGangLeader = %s)\n'
252 , (sNewState, idTestSetGangLeader,) );
253 self._oDb.maybeCommit(fCommit);
254 return True;
255
256 def isWholeGangDoneTesting(self, idTestSetGangLeader):
257 """
258 Checks if the whole gang is done testing.
259 """
260 self._oDb.execute('SELECT COUNT(*)\n'
261 'FROM TestBoxStatuses, TestSets\n'
262 'WHERE TestBoxStatuses.idTestSet = TestSets.idTestSet\n'
263 ' AND TestSets.idTestSetGangLeader = %s\n'
264 ' AND TestBoxStatuses.enmState IN (%s, %s)\n'
265 , ( idTestSetGangLeader,
266 TestBoxStatusData.ksTestBoxState_GangGathering,
267 TestBoxStatusData.ksTestBoxState_GangTesting));
268 return self._oDb.fetchOne()[0] == 0;
269
270 def isTheWholeGangThere(self, idTestSetGangLeader):
271 """
272 Checks if the whole gang is done testing.
273 """
274 self._oDb.execute('SELECT COUNT(*)\n'
275 'FROM TestBoxStatuses, TestSets\n'
276 'WHERE TestBoxStatuses.idTestSet = TestSets.idTestSet\n'
277 ' AND TestSets.idTestSetGangLeader = %s\n'
278 ' AND TestBoxStatuses.enmState IN (%s, %s)\n'
279 , ( idTestSetGangLeader,
280 TestBoxStatusData.ksTestBoxState_GangGathering,
281 TestBoxStatusData.ksTestBoxState_GangTesting));
282 return self._oDb.fetchOne()[0] == 0;
283
284 def timeSinceLastChangeInSecs(self, oStatusData):
285 """
286 Figures the time since the last status change.
287 """
288 tsNow = self._oDb.getCurrentTimestamp();
289 oDelta = tsNow - oStatusData.tsUpdated;
290 return oDelta.seconds + oDelta.days * 24 * 3600;
291
292
293#
294# Unit testing.
295#
296
297# pylint: disable=C0111
298class TestBoxStatusDataTestCase(ModelDataBaseTestCase):
299 def setUp(self):
300 self.aoSamples = [TestBoxStatusData(),];
301
302if __name__ == '__main__':
303 unittest.main();
304 # not reached.
305
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