source: trunk/server/www/app/vendors/shells/validators.php @ 390

Last change on this file since 390 was 390, checked in by sander, 11 years ago

Query Validator ID in order to remove the bad ones

File size: 7.8 KB
Line 
1<?php
2/**
3 * Officeshots.org - Test your office documents in different applications
4 * Copyright (C) 2009 Stichting Lone Wolves
5 * Written by Sander Marechal <s.marechal@jejik.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21/**
22 * A shell to re-run validators
23 */
24class ValidatorsShell extends Shell
25{
26        /** @var array The models to use */
27        public $uses = array('Validator', 'Testsuite');
28
29        /**
30         * Main function. Print help and exit.
31         */
32        public function main()
33        {
34                $this->help();
35        }
36
37        /**
38         * Re-run a subset or all validators for a test suite
39         */
40        public function rerun()
41        {
42                $suite_id = $this->_getSuite();
43                $validator = $this->_getValidator();
44                $state = $this->_getState();
45
46                $validators = $this->_getValidators($suite_id, $validator, $state);
47                foreach ($validators as $validator) {
48                        $this->Validator->id = $validator['Validator']['id'];
49                        $this->Validator->defer('run');
50                }
51
52                $this->out(sprintf('Scheduled %d validators to re-run in the background.', sizeof($validators)));
53        }
54
55        /**
56         * Add missing validators to the test suites
57         */
58        public function missing()
59        {
60                $suite_id = $this->_getSuite();
61                $validator = $this->_getValidator();
62
63                if ($validator == 'all') {
64                        $validators = Configure::read('Validator');
65                } else {
66                        $validators = array();
67                        $validators[$validator] = Configure::read('Validator.' . $validator);
68                }
69
70                $count_add = 0;
71                $count_remove = 0;
72
73                // Find all requests
74                $requests = $this->Testsuite->getRequests($suite_id, array(
75                        'Validator' => array('fields' => array('id', 'name')),
76                        'Job',
77                        'Job.Result',
78                        'Job.Result.Format',
79                        'Job.Result.Validator' => array('fields' => array('id', 'name')),
80                ));
81
82                // Loop through the requests and add missing validators
83                foreach ($requests as $request) {
84                        foreach ($validators as $validator_name => $validator_config) {
85                                if (!$validator_config) {
86                                        continue;
87                                }
88
89                                $existing = Set::extract('/Validator/name', $request);
90                                if (!in_array($validator_name, $existing)) {
91                                        $this->Validator->create();
92                                        $this->Validator->save(array('Validator' => array(
93                                                'name' => $validator_name,
94                                                'parent_id' => $request['Request']['id'],
95                                        )));
96                                        $this->Validator->defer('run');
97                                        $count_add++;
98                                }
99                        }
100                }
101
102                // Find all the results
103                $results = Set::extract('/Job/Result', $requests);
104                foreach ($results as $result) {
105                        if (empty($result['Result'])) {
106                                continue;
107                        }
108
109                        var_dump($result['Result']['Validator']);
110                        // If this is not and ODF roundtrip result, remove any validators and continue.
111                        // There was an old bug here that could cause non-ODF results to be assigned validators
112                        if ($result['Result']['Format']['code'] != 'odf') {
113                                foreach ($result['Result']['Validator'] as $validator_bug) {
114                                        $this->Validator->id = $validator_bug['id'];
115                                        $this->Validator->delete();
116                                        $count_remove++;
117                                }
118                               
119                                continue;
120                        }
121
122                        foreach ($validators as $validator_name => $validator_config) {
123                                if (!$validator_config) {
124                                        continue;
125                                }
126
127                                $existing = Set::extract('/Result/Validator/name', $result);
128                                if (!in_array($validator_name, $existing)) {
129                                        $this->Validator->create();
130                                        $this->Validator->save(array('Validator' => array(
131                                                'name' => $validator_name,
132                                                'parent_id' => $result['Result']['id'],
133                                        )));
134                                        $this->Validator->defer('run');
135                                        $count_add++;
136                                }
137                        }
138                }
139
140                $this->out(sprintf('Created and scheduled %d validators to run in the background.', $count_add));
141
142                if ($count_remove > 0) {
143                        $this->out(sprintf('Removed %d validators that were added in error.', $count_add));
144                }
145        }
146
147        /**
148         * Ask for a test suite
149         */
150        private function _getSuite()
151        {
152                $options = array(1 => 'All test suites');
153                $suites = $this->Testsuite->find('list', array(
154                        'order' => 'Testsuite.name ASC',
155                        'recursive' => -1,
156                ));
157
158                foreach ($suites as $suite) {
159                        $options[] = $suite;
160                }
161
162                $this->out('Please coose a test suite.');
163                $this->hr();
164                foreach ($options as $index => $option) {
165                        $this->out(sprintf('[%d] %s', $index, $option));
166                }
167
168                $suite_id = null;
169                while ($suite_id === null) {
170                        $suiteNum = $this->in('Enter a test suite number, or q to quit', null, 'q');
171
172                        if (strtolower($suiteNum) === 'q') {
173                                $this->out('Exit');
174                                $this->_stop();
175                        }
176
177                        $suiteNum = intval($suiteNum) - 2;
178                        if ($suiteNum >= count($suites)) {
179                                $this->out('Invalid selection');
180                                continue;
181                        }
182
183                        if ($suiteNum == -1) {
184                                $suite_id = false;
185                        } else {
186                                $suite_ids = array_keys($suites);
187                                $suite_id = $suite_ids[$suiteNum];
188                        }
189                }
190
191                return $suite_id;
192        }
193
194        /**
195         * Ask what validators to rerun
196         */
197        private function _getValidator()
198        {
199                $options = array(1 => 'All validators');
200
201                $validators = Configure::read('Validator');
202                foreach ($validators as $validator_name => $validator_config) {
203                        $options[] = $validator_name;
204                }
205
206                $this->out('Please choose a validator.');
207                $this->hr();
208                foreach ($options as $index => $option) {
209                        $this->out(sprintf('[%d] %s', $index, $option));
210                }
211
212                $validator = '';
213                while ($validator == '') {
214                        $validatorNum = $this->in('Enter a validator number, or q to quit', null, 'q');
215
216                        if (strtolower($validatorNum) === 'q') {
217                                $this->out('Exit');
218                                $this->_stop();
219                        }
220
221                        $validatorNum = intval($validatorNum);
222                        if ($validatorNum > count($options)) {
223                                $this->out('Invalid selection');
224                                continue;
225                        }
226
227                        if ($validatorNum == 1) {
228                                $validator = 'all';
229                        } else {
230                                $validator = $options[$validatorNum];
231                        }
232                }
233
234                return $validator;
235        }
236
237        /**
238         * Ask what validator states to re-run
239         */
240        private function _getState()
241        {
242                $this->out('What validator state so you wish to re-run?');
243                $this->hr();
244                $this->out('[1] All');
245                $this->out('[2] Invalid');
246                $this->out('[3] Error');
247                $this->out('[4] Invalid and Error');
248
249                while (true) {
250                        switch(strtolower($this->in('Enter a state number, or q to quit', null, 'q'))) {
251                                case 'q':
252                                        $this->out('Exit');
253                                        $this->_stop();
254                                        break;
255                                case '1': return array(Validator::STATE_VALID, Validator::STATE_INVALID, Validator::STATE_ERROR);
256                                case '2': return array(Validator::STATE_INVALID);
257                                case '3': return array(Validator::STATE_ERROR);
258                                case '4': return array(Validator::STATE_INVALID, Validator::STATE_ERROR);
259                        }
260                }
261        }
262
263        /**
264         * Get all validators based on test suite, validator name and state
265         */
266        private function _getValidators($suite, $name, $state = array())
267        {
268                $conditions = array();
269
270                if ($state) {
271                        $conditions['Validator.state'] = $state;
272                }
273
274                if ($name != 'all') {
275                        $conditions['Validator.name'] = $name;
276                }
277
278                $requests = $this->Testsuite->getRequests($suite, array(
279                        'Job',
280                        'Job.Result',
281                ));
282
283                $ids = Set::extract('/Request/id', $requests);
284                $ids = array_merge($ids, Set::extract('/Job/Result/id', $requests));
285                $conditions['Validator.parent_id'] = $ids;
286
287                $validators = $this->Validator->find('all', array(
288                        'fields' => array('id'),
289                        'conditions' => $conditions,
290                        'recursive' => -1,
291                ));
292
293                return $validators;
294        }
295
296        /**
297         * Print shell help
298         */
299        public function help()
300        {
301                $this->out('Commandline interface to work with the validators on the test suites');
302                $this->hr();
303                $this->out("Usage: cake validators <command>");
304                $this->hr();
305                $this->out('Commands:');
306                $this->out("\n\trerun\n\t\tRe-run a subset or all validators for a test suite.");
307                $this->out("\n\thelp\n\t\tShow this help");
308                $this->out('');
309        }
310}
311
312?>
Note: See TracBrowser for help on using the repository browser.