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

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

Removed a debugging statement

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                        // If this is not and ODF roundtrip result, remove any validators and continue.
110                        // There was an old bug here that could cause non-ODF results to be assigned validators
111                        if ($result['Result']['Format']['code'] != 'odf') {
112                                foreach ($result['Result']['Validator'] as $validator_bug) {
113                                        $this->Validator->id = $validator_bug['id'];
114                                        $this->Validator->delete();
115                                        $count_remove++;
116                                }
117                               
118                                continue;
119                        }
120
121                        foreach ($validators as $validator_name => $validator_config) {
122                                if (!$validator_config) {
123                                        continue;
124                                }
125
126                                $existing = Set::extract('/Result/Validator/name', $result);
127                                if (!in_array($validator_name, $existing)) {
128                                        $this->Validator->create();
129                                        $this->Validator->save(array('Validator' => array(
130                                                'name' => $validator_name,
131                                                'parent_id' => $result['Result']['id'],
132                                        )));
133                                        $this->Validator->defer('run');
134                                        $count_add++;
135                                }
136                        }
137                }
138
139                $this->out(sprintf('Created and scheduled %d validators to run in the background.', $count_add));
140
141                if ($count_remove > 0) {
142                        $this->out(sprintf('Removed %d validators that were added in error.', $count_add));
143                }
144        }
145
146        /**
147         * Ask for a test suite
148         */
149        private function _getSuite()
150        {
151                $options = array(1 => 'All test suites');
152                $suites = $this->Testsuite->find('list', array(
153                        'order' => 'Testsuite.name ASC',
154                        'recursive' => -1,
155                ));
156
157                foreach ($suites as $suite) {
158                        $options[] = $suite;
159                }
160
161                $this->out('Please coose a test suite.');
162                $this->hr();
163                foreach ($options as $index => $option) {
164                        $this->out(sprintf('[%d] %s', $index, $option));
165                }
166
167                $suite_id = null;
168                while ($suite_id === null) {
169                        $suiteNum = $this->in('Enter a test suite number, or q to quit', null, 'q');
170
171                        if (strtolower($suiteNum) === 'q') {
172                                $this->out('Exit');
173                                $this->_stop();
174                        }
175
176                        $suiteNum = intval($suiteNum) - 2;
177                        if ($suiteNum >= count($suites)) {
178                                $this->out('Invalid selection');
179                                continue;
180                        }
181
182                        if ($suiteNum == -1) {
183                                $suite_id = false;
184                        } else {
185                                $suite_ids = array_keys($suites);
186                                $suite_id = $suite_ids[$suiteNum];
187                        }
188                }
189
190                return $suite_id;
191        }
192
193        /**
194         * Ask what validators to rerun
195         */
196        private function _getValidator()
197        {
198                $options = array(1 => 'All validators');
199
200                $validators = Configure::read('Validator');
201                foreach ($validators as $validator_name => $validator_config) {
202                        $options[] = $validator_name;
203                }
204
205                $this->out('Please choose a validator.');
206                $this->hr();
207                foreach ($options as $index => $option) {
208                        $this->out(sprintf('[%d] %s', $index, $option));
209                }
210
211                $validator = '';
212                while ($validator == '') {
213                        $validatorNum = $this->in('Enter a validator number, or q to quit', null, 'q');
214
215                        if (strtolower($validatorNum) === 'q') {
216                                $this->out('Exit');
217                                $this->_stop();
218                        }
219
220                        $validatorNum = intval($validatorNum);
221                        if ($validatorNum > count($options)) {
222                                $this->out('Invalid selection');
223                                continue;
224                        }
225
226                        if ($validatorNum == 1) {
227                                $validator = 'all';
228                        } else {
229                                $validator = $options[$validatorNum];
230                        }
231                }
232
233                return $validator;
234        }
235
236        /**
237         * Ask what validator states to re-run
238         */
239        private function _getState()
240        {
241                $this->out('What validator state so you wish to re-run?');
242                $this->hr();
243                $this->out('[1] All');
244                $this->out('[2] Invalid');
245                $this->out('[3] Error');
246                $this->out('[4] Invalid and Error');
247
248                while (true) {
249                        switch(strtolower($this->in('Enter a state number, or q to quit', null, 'q'))) {
250                                case 'q':
251                                        $this->out('Exit');
252                                        $this->_stop();
253                                        break;
254                                case '1': return array(Validator::STATE_VALID, Validator::STATE_INVALID, Validator::STATE_ERROR);
255                                case '2': return array(Validator::STATE_INVALID);
256                                case '3': return array(Validator::STATE_ERROR);
257                                case '4': return array(Validator::STATE_INVALID, Validator::STATE_ERROR);
258                        }
259                }
260        }
261
262        /**
263         * Get all validators based on test suite, validator name and state
264         */
265        private function _getValidators($suite, $name, $state = array())
266        {
267                $conditions = array();
268
269                if ($state) {
270                        $conditions['Validator.state'] = $state;
271                }
272
273                if ($name != 'all') {
274                        $conditions['Validator.name'] = $name;
275                }
276
277                $requests = $this->Testsuite->getRequests($suite, array(
278                        'Job',
279                        'Job.Result',
280                ));
281
282                $ids = Set::extract('/Request/id', $requests);
283                $ids = array_merge($ids, Set::extract('/Job/Result/id', $requests));
284                $conditions['Validator.parent_id'] = $ids;
285
286                $validators = $this->Validator->find('all', array(
287                        'fields' => array('id'),
288                        'conditions' => $conditions,
289                        'recursive' => -1,
290                ));
291
292                return $validators;
293        }
294
295        /**
296         * Print shell help
297         */
298        public function help()
299        {
300                $this->out('Commandline interface to work with the validators on the test suites');
301                $this->hr();
302                $this->out("Usage: cake validators <command>");
303                $this->hr();
304                $this->out('Commands:');
305                $this->out("\n\trerun\n\t\tRe-run a subset or all validators for a test suite.");
306                $this->out("\n\thelp\n\t\tShow this help");
307                $this->out('');
308        }
309}
310
311?>
Note: See TracBrowser for help on using the repository browser.