1 | # -*- coding: utf-8 -*-
|
---|
2 | # $Id: systemchangelog.py 83383 2020-03-24 14:44:25Z vboxsync $
|
---|
3 |
|
---|
4 | """
|
---|
5 | Test Manager - System changelog compilation.
|
---|
6 | """
|
---|
7 |
|
---|
8 | __copyright__ = \
|
---|
9 | """
|
---|
10 | Copyright (C) 2012-2020 Oracle Corporation
|
---|
11 |
|
---|
12 | This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
13 | available from http://www.virtualbox.org. This file is free software;
|
---|
14 | you can redistribute it and/or modify it under the terms of the GNU
|
---|
15 | General Public License (GPL) as published by the Free Software
|
---|
16 | Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
17 | VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
18 | hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
19 |
|
---|
20 | The contents of this file may alternatively be used under the terms
|
---|
21 | of the Common Development and Distribution License Version 1.0
|
---|
22 | (CDDL) only, as it comes in the "COPYING.CDDL" file of the
|
---|
23 | VirtualBox OSE distribution, in which case the provisions of the
|
---|
24 | CDDL are applicable instead of those of the GPL.
|
---|
25 |
|
---|
26 | You may elect to license modified versions of this file under the
|
---|
27 | terms and conditions of either the GPL or the CDDL or both.
|
---|
28 | """
|
---|
29 | __version__ = "$Revision: 83383 $"
|
---|
30 |
|
---|
31 |
|
---|
32 | # Validation Kit imports.
|
---|
33 | from testmanager.core.base import ModelLogicBase;
|
---|
34 | from testmanager.core.useraccount import UserAccountLogic;
|
---|
35 | from testmanager.core.systemlog import SystemLogData;
|
---|
36 |
|
---|
37 |
|
---|
38 | class SystemChangelogEntry(object): # pylint: disable=too-many-instance-attributes
|
---|
39 | """
|
---|
40 | System changelog entry.
|
---|
41 | """
|
---|
42 |
|
---|
43 | def __init__(self, tsEffective, oAuthor, sEvent, idWhat, sDesc):
|
---|
44 | self.tsEffective = tsEffective;
|
---|
45 | self.oAuthor = oAuthor;
|
---|
46 | self.sEvent = sEvent;
|
---|
47 | self.idWhat = idWhat;
|
---|
48 | self.sDesc = sDesc;
|
---|
49 |
|
---|
50 |
|
---|
51 | class SystemChangelogLogic(ModelLogicBase):
|
---|
52 | """
|
---|
53 | System changelog compilation logic.
|
---|
54 | """
|
---|
55 |
|
---|
56 | ## @name What kind of change.
|
---|
57 | ## @{
|
---|
58 | ksWhat_TestBox = 'chlog::TestBox';
|
---|
59 | ksWhat_TestCase = 'chlog::TestCase';
|
---|
60 | ksWhat_Blacklisting = 'chlog::Blacklisting';
|
---|
61 | ksWhat_Build = 'chlog::Build';
|
---|
62 | ksWhat_BuildSource = 'chlog::BuildSource';
|
---|
63 | ksWhat_FailureCategory = 'chlog::FailureCategory';
|
---|
64 | ksWhat_FailureReason = 'chlog::FailureReason';
|
---|
65 | ksWhat_GlobalRsrc = 'chlog::GlobalRsrc';
|
---|
66 | ksWhat_SchedGroup = 'chlog::SchedGroup';
|
---|
67 | ksWhat_TestGroup = 'chlog::TestGroup';
|
---|
68 | ksWhat_User = 'chlog::User';
|
---|
69 | ksWhat_TestResult = 'chlog::TestResult';
|
---|
70 | ## @}
|
---|
71 |
|
---|
72 | ## Mapping a changelog entry kind to a table, key and clue.
|
---|
73 | kdWhatToTable = dict({ # pylint: disable=star-args
|
---|
74 | ksWhat_TestBox: ( 'TestBoxes', 'idTestBox', None, ),
|
---|
75 | ksWhat_TestCase: ( 'TestCasees', 'idTestCase', None, ),
|
---|
76 | ksWhat_Blacklisting: ( 'Blacklist', 'idBlacklisting', None, ),
|
---|
77 | ksWhat_Build: ( 'Builds', 'idBuild', None, ),
|
---|
78 | ksWhat_BuildSource: ( 'BuildSources', 'idBuildSrc', None, ),
|
---|
79 | ksWhat_FailureCategory: ( 'FailureCategories', 'idFailureCategory', None, ),
|
---|
80 | ksWhat_FailureReason: ( 'FailureReasons', 'idFailureReason', None, ),
|
---|
81 | ksWhat_GlobalRsrc: ( 'GlobalResources', 'idGlobalRsrc', None, ),
|
---|
82 | ksWhat_SchedGroup: ( 'SchedGroups', 'idSchedGroup', None, ),
|
---|
83 | ksWhat_TestGroup: ( 'TestGroups', 'idTestGroup', None, ),
|
---|
84 | ksWhat_User: ( 'Users', 'idUser', None, ),
|
---|
85 | ksWhat_TestResult: ( 'TestResults', 'idTestResult', None, ),
|
---|
86 | }, **{sEvent: ( 'SystemLog', 'tsCreated', 'TimestampId', ) for sEvent in SystemLogData.kasEvents});
|
---|
87 |
|
---|
88 | ## The table key is the effective timestamp. (Can't be used above for some weird scoping reason.)
|
---|
89 | ksClue_TimestampId = 'TimestampId';
|
---|
90 |
|
---|
91 | ## @todo move to config.py?
|
---|
92 | ksVSheriffLoginName = 'vsheriff';
|
---|
93 |
|
---|
94 |
|
---|
95 | ## @name for kaasChangelogTables
|
---|
96 | ## @internal
|
---|
97 | ## @{
|
---|
98 | ksTweak_None = '';
|
---|
99 | ksTweak_NotNullAuthor = 'uidAuthorNotNull';
|
---|
100 | ksTweak_NotNullAuthorOrVSheriff = 'uidAuthorNotNullOrVSheriff';
|
---|
101 | ## @}
|
---|
102 |
|
---|
103 | ## @internal
|
---|
104 | kaasChangelogTables = (
|
---|
105 | # [0]: change name, [1]: Table name, [2]: key column, [3]:later, [4]: tweak
|
---|
106 | ( ksWhat_TestBox, 'TestBoxes', 'idTestBox', None, ksTweak_NotNullAuthor, ),
|
---|
107 | ( ksWhat_TestBox, 'TestBoxesInSchedGroups', 'idTestBox', None, ksTweak_None, ),
|
---|
108 | ( ksWhat_TestCase, 'TestCases', 'idTestCase', None, ksTweak_None, ),
|
---|
109 | ( ksWhat_TestCase, 'TestCaseArgs', 'idTestCase', None, ksTweak_None, ),
|
---|
110 | ( ksWhat_TestCase, 'TestCaseDeps', 'idTestCase', None, ksTweak_None, ),
|
---|
111 | ( ksWhat_TestCase, 'TestCaseGlobalRsrcDeps', 'idTestCase', None, ksTweak_None, ),
|
---|
112 | ( ksWhat_Blacklisting, 'BuildBlacklist', 'idBlacklisting', None, ksTweak_None, ),
|
---|
113 | ( ksWhat_Build, 'Builds', 'idBuild', None, ksTweak_NotNullAuthor, ),
|
---|
114 | ( ksWhat_BuildSource, 'BuildSources', 'idBuildSrc', None, ksTweak_None, ),
|
---|
115 | ( ksWhat_FailureCategory, 'FailureCategories', 'idFailureCategory', None, ksTweak_None, ),
|
---|
116 | ( ksWhat_FailureReason, 'FailureReasons', 'idFailureReason', None, ksTweak_None, ),
|
---|
117 | ( ksWhat_GlobalRsrc, 'GlobalResources', 'idGlobalRsrc', None, ksTweak_None, ),
|
---|
118 | ( ksWhat_SchedGroup, 'SchedGroups', 'idSchedGroup', None, ksTweak_None, ),
|
---|
119 | ( ksWhat_SchedGroup, 'SchedGroupMembers', 'idSchedGroup', None, ksTweak_None, ),
|
---|
120 | ( ksWhat_TestGroup, 'TestGroups', 'idTestGroup', None, ksTweak_None, ),
|
---|
121 | ( ksWhat_TestGroup, 'TestGroupMembers', 'idTestGroup', None, ksTweak_None, ),
|
---|
122 | ( ksWhat_User, 'Users', 'uid', None, ksTweak_None, ),
|
---|
123 | ( ksWhat_TestResult, 'TestResultFailures', 'idTestResult', None, ksTweak_NotNullAuthorOrVSheriff, ),
|
---|
124 | );
|
---|
125 |
|
---|
126 | def __init__(self, oDb):
|
---|
127 | ModelLogicBase.__init__(self, oDb);
|
---|
128 |
|
---|
129 |
|
---|
130 | def fetchForListingEx(self, iStart, cMaxRows, tsNow, cDaysBack, aiSortColumns = None):
|
---|
131 | """
|
---|
132 | Fetches SystemLog entries.
|
---|
133 |
|
---|
134 | Returns an array (list) of SystemLogData items, empty list if none.
|
---|
135 | Raises exception on error.
|
---|
136 | """
|
---|
137 | _ = aiSortColumns;
|
---|
138 |
|
---|
139 | #
|
---|
140 | # Construct the query.
|
---|
141 | #
|
---|
142 | oUserAccountLogic = UserAccountLogic(self._oDb);
|
---|
143 | oVSheriff = oUserAccountLogic.tryFetchAccountByLoginName(self.ksVSheriffLoginName);
|
---|
144 | uidVSheriff = oVSheriff.uid if oVSheriff is not None else -1;
|
---|
145 |
|
---|
146 | if tsNow is None:
|
---|
147 | sWhereTime = self._oDb.formatBindArgs(' WHERE tsEffective >= CURRENT_TIMESTAMP - \'%s days\'::interval\n',
|
---|
148 | (cDaysBack,));
|
---|
149 | else:
|
---|
150 | sWhereTime = self._oDb.formatBindArgs(' WHERE tsEffective >= (%s::timestamptz - \'%s days\'::interval)\n'
|
---|
151 | ' AND tsEffective <= %s\n',
|
---|
152 | (tsNow, cDaysBack, tsNow));
|
---|
153 |
|
---|
154 | # Special entry for the system log.
|
---|
155 | sQuery = '(\n'
|
---|
156 | sQuery += ' SELECT NULL AS uidAuthor,\n';
|
---|
157 | sQuery += ' tsCreated AS tsEffective,\n';
|
---|
158 | sQuery += ' sEvent AS sEvent,\n';
|
---|
159 | sQuery += ' NULL AS idWhat,\n';
|
---|
160 | sQuery += ' sLogText AS sDesc\n';
|
---|
161 | sQuery += ' FROM SystemLog\n';
|
---|
162 | sQuery += sWhereTime.replace('tsEffective', 'tsCreated');
|
---|
163 | sQuery += ' ORDER BY tsCreated DESC\n'
|
---|
164 | sQuery += ')'
|
---|
165 |
|
---|
166 | for asEntry in self.kaasChangelogTables:
|
---|
167 | sQuery += ' UNION (\n'
|
---|
168 | sQuery += ' SELECT uidAuthor, tsEffective, \'' + asEntry[0] + '\', ' + asEntry[2] + ', \'\'\n';
|
---|
169 | sQuery += ' FROM ' + asEntry[1] + '\n'
|
---|
170 | sQuery += sWhereTime;
|
---|
171 | if asEntry[4] == self.ksTweak_NotNullAuthor or asEntry[4] == self.ksTweak_NotNullAuthorOrVSheriff:
|
---|
172 | sQuery += ' AND uidAuthor IS NOT NULL\n';
|
---|
173 | if asEntry[4] == self.ksTweak_NotNullAuthorOrVSheriff:
|
---|
174 | sQuery += ' AND uidAuthor <> %u\n' % (uidVSheriff,);
|
---|
175 | sQuery += ' ORDER BY tsEffective DESC\n'
|
---|
176 | sQuery += ')';
|
---|
177 | sQuery += ' ORDER BY 2 DESC\n';
|
---|
178 | sQuery += ' LIMIT %u OFFSET %u\n' % (cMaxRows, iStart, );
|
---|
179 |
|
---|
180 |
|
---|
181 | #
|
---|
182 | # Execute the query and construct the return data.
|
---|
183 | #
|
---|
184 | self._oDb.execute(sQuery);
|
---|
185 | aoRows = [];
|
---|
186 | for aoRow in self._oDb.fetchAll():
|
---|
187 | aoRows.append(SystemChangelogEntry(aoRow[1], oUserAccountLogic.cachedLookup(aoRow[0]),
|
---|
188 | aoRow[2], aoRow[3], aoRow[4]));
|
---|
189 |
|
---|
190 |
|
---|
191 | return aoRows;
|
---|
192 |
|
---|