Changeset 297


Ignore:
Timestamp:
02/22/10 17:40:26 (10 years ago)
Author:
sander
Message:

Generate and display jobs and results for test suites

Location:
trunk/server/www/app
Files:
3 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/server/www/app/config/core.php.default

    r286 r297  
    226226        Cache::config('default', array('engine' => 'File')); 
    227227/** 
     228 * Set the default language 
     229 */ 
     230        Configure::write('Config.language', 'eng'); 
     231/** 
    228232 * The administrator E-mail address 
    229233 */ 
     
    288292                Configure::write('Factory.polltime', (6 * 60)); 
    289293        } 
     294/** 
     295 * The number of seconds a factory must be running uninterrupted before it is considered "stable". Testsuite jobs will only be 
     296 * generated for stable factories. This way experimetal, development or unstable factories will not be overloaded with hundreds 
     297 * of jobs. 
     298 */ 
     299        Configure::write('Factory.stabletime', (60 * 60 * 24)); 
    290300/** 
    291301 * BeanStalk Configuration 
     
    346356 */ 
    347357        Configure::write('Anonymiser.path', '/usr/bin/iodf-greek.py'); 
     358/** 
     359 * Testsuite uid/gid settings 
     360 */ 
     361        Configure::write('Testsuite.user_id', ''); 
     362        Configure::write('Testsuite.group_id', ''); 
    348363?> 
  • trunk/server/www/app/config/sql/schema.php

    r295 r297  
    11<?php  
    22/* SVN FILE: $Id$ */ 
    3 /* App schema generated on: 2010-02-10 15:02:05 : 1265810465*/ 
     3/* App schema generated on: 2010-02-22 13:02:55 : 1266842515*/ 
    44class AppSchema extends CakeSchema { 
    55        var $name = 'App'; 
     
    4747                        'id' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36, 'key' => 'primary'), 
    4848                        'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 40), 
     49                        'icon' => array('type' => 'string', 'null' => false, 'default' => NULL), 
    4950                        'code' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 3), 
    5051                        'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)) 
  • trunk/server/www/app/controllers/galleries_controller.php

    r294 r297  
    2828         
    2929        /** The controller helpers */ 
    30         public $helpers = array('Html', 'Form', 'Javascript', 'RequestModel', 'ResultModel', 'ValidatorModel'); 
     30        public $helpers = array('Html', 'Form', 'Javascript', 'RequestModel', 'JobModel', 'ValidatorModel'); 
    3131 
    3232        /** The models this controller uses */ 
     
    141141                                'Request', 
    142142                                'Request.Validator' => array('order' => 'Validator.name ASC'), 
    143                                 'Request.Job', 
     143                                'Request.Job' => array('order' => array( 
     144                                        'Application.name ASC', 
     145                                        'Job.version ASC', 
     146                                        'Platform.name ASC', 
     147                                        'Format.name ASC', 
     148                                )), 
    144149                                'Request.Job.Application', 
     150                                'Request.Job.Format', 
    145151                                'Request.Job.Platform', 
    146152                                'Request.Job.Result', 
     
    172178                                        'contain' => array( 
    173179                                                'Application', 
     180                                                'Format', 
    174181                                                'Platform', 
    175182                                                'Result', 
    176183                                                'Result.Validator' 
     184                                        ), 
     185                                        'order' => array( 
     186                                                'Application.name ASC', 
     187                                                'Job.version ASC', 
     188                                                'Platform.name ASC', 
     189                                                'Format.name ASC', 
    177190                                        ), 
    178191                                )); 
  • trunk/server/www/app/controllers/jobs_controller.php

    r295 r297  
    332332                                        AND `Job`.`format_id` IN  (" . implode(', ', $formats) . ") 
    333333                                        AND `Request`.`state` = " . Request::STATE_QUEUED . " 
    334                                         AND `Request`.`expire` > '" . date('Y-m-d H:i:s') . "' 
     334                                        AND (`Request`.`expire` > '" . date('Y-m-d H:i:s') . "' OR `Request`.`expire` IS NULL) 
    335335                                        AND `Mimetype`.`doctype_id` IN (" . implode(', ', $doctypes) . ") 
    336336                                        AND (`Request`.`own_factory` = 0 
    337337                                                OR (`Request`.`own_factory` = 1 AND `Request`.`user_id` = '" . $this->AuthCert->user('id') . "') 
    338                                         )"); 
     338                                        ) 
     339                                ORDER BY `Request`.`own_factory` DESC, 
     340                                        `Request`.`priority` ASC, 
     341                                        `Request`.`created` ASC 
     342                                LIMIT 0,1"); 
    339343                        $jobs = array_merge($jobs, $jobSet); 
    340344                } 
     
    344348                } 
    345349 
    346                 $jobs = Set::sort($jobs, '{n}.Request.created', SORT_ASC); 
    347                 $jobs = Set::sort($jobs, '{n}.Request.priority', SORT_ASC); 
    348                 $jobs = Set::sort($jobs, '{n}.Request.own_factory', SORT_DESC); 
     350                usort($jobs, array($this, '_cmpJobs')); 
    349351                $job = array_shift($jobs); 
    350352 
     
    377379 
    378380        /** 
     381         * A helper function to sort jobs for xmlrpc_poll() 
     382         */ 
     383        public function _cmpJobs($a, $b) 
     384        { 
     385                // First, look at the own_factory flag 
     386                if ($a['Request']['own_factory'] == 1 && $b['Request']['own_factory'] == 0) { 
     387                        return -1; 
     388                } 
     389                if ($a['Request']['own_factory'] == 0 && $b['Request']['own_factory'] == 1) { 
     390                        return 1; 
     391                } 
     392 
     393                // Next, look at the priority 
     394                if ($a['Request']['priority'] < $b['Request']['priority']) { 
     395                        return -1; 
     396                } 
     397                if ($a['Request']['priority'] > $b['Request']['priority']) { 
     398                        return 1; 
     399                } 
     400 
     401                // If the priorities are also equal, look at the creation date 
     402                return ($a['Request']['created'] < $b['Request']['created']) ? -1 : 1; 
     403        } 
     404 
     405        /** 
    379406         * Finish a job by uploading the result 
    380407         * 
  • trunk/server/www/app/controllers/validators_controller.php

    r283 r297  
    3737        { 
    3838                parent::beforeFilter(); 
    39                 if (Configure::read('Auth.allowAnonymous')) { 
    40                         $this->AuthCert->allow('view'); 
    41                 } 
     39                $this->AuthCert->allow('view'); 
    4240        } 
    4341 
     
    5957                $this->Validator->contain(array( 
    6058                        'Request', 
    61                         'Request.Gallery', 
    6259                        'Result', 
    6360                        'Result.Job', 
     
    6562                        'Result.Job.Platform', 
    6663                        'Result.Job.Request', 
    67                         'Result.Job.Request.Gallery', 
    6864                )); 
    6965                 
     
    7369                } 
    7470 
    75                 if ($validator['Request']['user_id'] == $this->AuthCert->user('id')) { 
    76                         return $validator; 
    77                 } 
    78  
    79                 if (!empty($validator['Request']['Gallery'])) { 
     71                if ($this->Validator->Request->checkAccess($this->AuthCert->user('id'), 'read', $validator['Request']['id'])) { 
    8072                        return $validator; 
    8173                } 
     
    10395        { 
    10496                $validator = $this->_getValidator($id); 
     97 
     98                // Strip HTML skeleton 
     99                if (preg_match('#^<html>.*<body>(.*)</body>#si', $validator['Validator']['response'], $match)) { 
     100                        $validator['Validator']['response'] = $match[1]; 
     101                } 
     102 
    105103                $this->set(array( 
    106104                        'validator' => $validator, 
  • trunk/server/www/app/models/gallery.php

    r294 r297  
    170170 
    171171        /** 
     172         * Return all requests and jobs associated with a gallery and all subgalleries 
     173         * @param int $id The Gallery ID 
     174         * @return array 
     175         */ 
     176        public function getRequests($id = null) 
     177        { 
     178                if (!$id) { 
     179                        $id = $this->id; 
     180                } 
     181 
     182                if (!$id) { 
     183                        return array(); 
     184                } 
     185 
     186                $gallery = $this->find('first', array( 
     187                        'conditions' => array('Gallery.id' => $id), 
     188                        'recursive' => -1, 
     189                )); 
     190 
     191                $result = $this->GalleriesRequest->find('all', array( 
     192                        'conditions' => array('GalleriesRequest.gallery_id' => $id), 
     193                        'recursive' => -1, 
     194                )); 
     195                $request_ids = Set::extract('/GalleriesRequest/request_id', $result); 
     196 
     197                $result = $this->query('SELECT DISTINCT `GalleriesRequest`.`request_id` 
     198                        FROM `galleries_requests` AS `GalleriesRequest` 
     199                        LEFT JOIN `galleries` AS `Gallery` 
     200                                ON `GalleriesRequest`.`gallery_id` = `Gallery`.`id` 
     201                        WHERE 
     202                                `Gallery`.`lft` > ' . $gallery['Gallery']['lft'] . ' 
     203                                AND `Gallery`.`rght` < ' . $gallery['Gallery']['rght']); 
     204                $subgallery_request_ids = Set::extract('/GalleriesRequest/request_id', $result); 
     205 
     206                $request_ids = Set::merge($request_ids, $subgallery_request_ids); 
     207 
     208                $requests = $this->Request->find('all', array( 
     209                        'contain' => array('Job', 'Mimetype'), 
     210                        'conditions' => array('Request.id' => $request_ids), 
     211                )); 
     212 
     213                return $requests; 
     214        } 
     215 
     216        /** 
    172217         * Convert the Markdown description to HTML before saving 
    173218         * @return boolean True to continue saving 
  • trunk/server/www/app/models/request.php

    r295 r297  
    164164         * 
    165165         * @param array $jobs An array of jobs 
     166         * @param string $id The request ID 
    166167         * @return int The number of jobs created 
    167168         */ 
    168         public function addJobs($jobs = array()) 
    169         {        
     169        public function addJobs($jobs = array(), $id = null) 
     170        { 
    170171                // Load the Application model. We need that below. 
    171172                $Application = ClassRegistry::init('Application'); 
     173 
     174                // Load the request 
     175                if (!$id) { 
     176                        $id = $this->id; 
     177                } 
     178 
     179                if (!$id) { 
     180                        return 0; 
     181                } 
     182 
     183                $request = $this->find('first', array( 
     184                        'conditions' => array('Request.id' => $id), 
     185                        'recursive' => -1, 
     186                )); 
    172187 
    173188                // Find the Mimetype associated with the request 
    174189                // We can use this to check the doctype on the submitted jobs below 
    175190                $mimetype = $this->Mimetype->find('first', array('conditions' => array( 
    176                         'Mimetype.id' => $this->data['Request']['mimetype_id'], 
     191                        'Mimetype.id' => $request['Request']['mimetype_id'], 
    177192                ))); 
    178193 
    179194                $jobCount = 0; 
    180195                foreach ($jobs as $job) { 
    181                         $job['request_id'] = $this->id; 
     196                        $job['request_id'] = $id; 
    182197 
    183198                        // Check the request mimetype against the supported doctype 
  • trunk/server/www/app/models/testsuite.php

    r294 r297  
    2828 
    2929        /** 
    30          * Synchronise all testsuites to the database 
     30         * Synchronise all testsuite files to the database 
    3131         */ 
    3232        public function synchronise() 
     
    247247                } 
    248248        } 
     249 
     250        /** 
     251         * Add jobs to all the test suite requests for all stable factories 
     252         */ 
     253        public function addJobs() 
     254        { 
     255                // Load the necessary models 
     256                $this->Worker = ClassRegistry::init('Worker'); 
     257                $this->Request = ClassRegistry::init('Request'); 
     258 
     259                $workers = $this->Worker->getActive(true); 
     260                $requests = $this->_getRequests(); 
     261 
     262                foreach ($requests as $request) { 
     263                        $this->_addJobs($request, $workers); 
     264                } 
     265        } 
     266 
     267        /** 
     268         * Get all requests and jobs that belong to all test suites 
     269         */ 
     270        private function _getRequests() 
     271        { 
     272                $requests = array(); 
     273                $suites = $this->find('all', array('recursive' => -1)); 
     274 
     275                foreach ($suites as $suite) { 
     276                        $requests = Set::merge( 
     277                                $requests, 
     278                                $this->Gallery->getRequests($suite['Testsuite']['gallery_id']) 
     279                        ); 
     280                } 
     281 
     282                return $requests; 
     283        } 
     284 
     285        /** 
     286         * Add jobs for $workers to a single request 
     287         * @param array $workers An array of available workers 
     288         * @param array $request The request to add the jobs to 
     289         */ 
     290        private function _addJobs($request, $workers) 
     291        { 
     292                $newJobs = array(); 
     293                foreach ($workers as $worker) { 
     294                        // If the worker does not support this doctype, skip it. 
     295                        if ($request['Mimetype']['doctype_id'] != $worker['Doctype']['id']) { 
     296                                continue; 
     297                        } 
     298 
     299                        foreach ($worker['Format'] as $format) { 
     300                                $match = false; 
     301 
     302                                foreach ($request['Job'] as $job) { 
     303                                        $match = ( 
     304                                                $job['platform_id'] == $worker['Platform']['id'] 
     305                                                && $job['application_id'] == $worker['Application']['id'] 
     306                                                && $job['version'] == $worker['Worker']['version'] 
     307                                                && $job['format_id'] == $format['id'] 
     308                                        ); 
     309 
     310                                        // If a job already exists we're done checking 
     311                                        if ($match) { 
     312                                                break; 
     313                                        } 
     314                                } 
     315 
     316                                if ($match) { 
     317                                        continue; 
     318                                } 
     319 
     320                                // If we get here, no suitable job exists and we need to add one 
     321                                $newJobs[] = array( 
     322                                        'platform_id' => $worker['Platform']['id'], 
     323                                        'application_id' => $worker['Application']['id'], 
     324                                        'version' => $worker['Worker']['version'], 
     325                                        'format_id' => $format['id'], 
     326                                ); 
     327                        } 
     328                } 
     329                 
     330                $this->Request->id = $request['Request']['id']; 
     331                $this->Request->addJobs($newJobs); 
     332        } 
    249333} 
    250334 
  • trunk/server/www/app/models/worker.php

    r234 r297  
    5555        /** 
    5656         * Get a list of all active worker types. That is, unique combinations of Platform, Doctype and Application 
    57          * 
    58          * @param integer $time Maximum time since the last poll, in minutes 
     57         * @param boolean $stable If true, return only stable factories 
    5958         * @return array 
    6059         */ 
    61         public function getActive() 
     60        public function getActive($stable = false) 
    6261        { 
    6362                App::import('Sanitize'); 
     63                $time = date('Y-m-d H:i:s', time() - Configure::read('Factory.polltime')); 
    6464 
    65                 $time = date('Y-m-d H:i:s', time() - Configure::read('Factory.polltime')); 
     65                if ($stable) { 
     66                        $stableTime = date('Y-m-d H:i:s', time() - Configure::read('Factory.stabletime')); 
     67                        $sqlWhere = "AND `Factory`.`active_since` != '0000-00-00 00:00:00' 
     68                                     AND `Factory`.`active_since` < '$stableTime' 
     69                                     AND `Worker`.`development` = 0"; 
     70                } else { 
     71                        $sqlWhere = ''; 
     72                } 
     73 
    6674                $active = $this->query("SELECT DISTINCT 
    6775                                `Worker`.`version`, 
     
    8290                        LEFT JOIN `doctypes` AS `Doctype` ON (`ApplicationsDoctype`.`doctype_id` = `Doctype`.`id`) 
    8391                        WHERE `Factory`.`last_poll` > '$time' 
     92                                $sqlWhere 
    8493                        ORDER BY `Platform`.`name` ASC, `Application`.`name` ASC, `Worker`.`version` ASC"); 
    8594 
     
    100109                                        LEFT JOIN `applications_doctypes` AS `ApplicationsDoctype` ON `Application`.`id` = `ApplicationsDoctype`.`application_id` 
    101110                                        WHERE `Factory`.`last_poll` > '$time' 
     111                                                $sqlWhere 
    102112                                                AND `Worker`.`version` = '" . Sanitize::escape($app['Worker']['version']) . "' 
    103113                                                AND `Application`.`id` = '" . $app['Application']['id'] . "' 
  • trunk/server/www/app/vendors/shells/cron.php

    r296 r297  
    4747 
    4848        /** 
     49         * Generate new jobs for the test suites. This should be run once per day. 
     50         */ 
     51        public function updateTestsuites() 
     52        { 
     53                $Testsuite = ClassRegistry::init('Testsuite'); 
     54                $this->out($Testsuite->addJobs()); 
     55        } 
     56 
     57        /** 
    4958         * Print shell help 
    5059         */ 
     
    5766                $this->out('Commands:'); 
    5867                $this->out("\n\texpire\n\t\tSet STATE_EXPIRED on all requests whose expiry time has passed.\n\t\tThis should be run every minute."); 
    59                 $this->out("\n\tsyncTestsuites\n\t\tSynchronise all ODF testsuites.\n\t\tThis should be run every hour."); 
     68                $this->out("\n\tupdateTestsuites\n\t\tCreate jopbs for all ODF testsuites.\n\t\tThis should be run every hour."); 
    6069                $this->out("\n\thelp\n\t\tShow this help"); 
    6170                $this->out(''); 
  • trunk/server/www/app/views/elements/gallery.ctp

    r293 r297  
    2424        </tr> 
    2525        <?php foreach ($request['Job'] as $job):?> 
    26         <tr class="result<?php if (!$job['Result']) { echo ' expired'; } ?>"> 
     26        <tr class="result<?php if (!$job['Result'] || !$job['Result']['id']) { echo ' expired'; } ?>"> 
    2727                        <td class="job-name" style="padding-left: <?php echo $indent + 2;?>em"> 
    2828                                <?php 
    29                                         if ($job['Result']) { 
     29                                        echo $jobModel->getFormatIcon($job); 
     30                                        if ($job['Result'] && $job['Result']['id']) { 
    3031                                                echo $html->link($job['Application']['name'] . ' ' . $job['version'] . ' (' . $job['Platform']['name'] . ')', array('controller'=> 'results', 'action'=>'view', $job['Result']['id'])); 
    3132                                        } else { 
     
    4445                        </td> 
    4546                        <td><?php echo isset($job['Result']['created']) ? $job['Result']['created'] : $job['created']; ?></td> 
    46                         <td><?php echo $resultModel->getState($job['Result']); ?></td> 
     47                        <td><?php echo $jobModel->getState($job, $request['state']); ?></td> 
    4748                        <?php if ($access):?> 
    4849                                <td class="actions">&nbsp;</td> 
  • trunk/server/www/app/views/helpers/job_model.php

    r284 r297  
    3636                } 
    3737 
    38                 if (!empty($job['Job']['Result'])) { 
     38                if (!empty($job['Job']['Result']) && !empty($job['Job']['Result']['id'])) { 
    3939                        return $this->output($job['Job']['Result']['Format']['name']); 
     40                } 
     41 
     42                return $this->getState($job, $request_state); 
     43        } 
     44 
     45        /** 
     46         * Return the state of a job 
     47         */ 
     48        public function getState($job, $request_state) 
     49        { 
     50                if (!isset($job['Job'])) { 
     51                        $job = array('Job' => $job); 
     52                } 
     53 
     54                if (!empty($job['Job']['Result']) && !empty($job['Job']['Result']['id'])) { 
     55                        return $this->output(__('Finished', true)); 
    4056                } 
    4157 
     
    87103                return $this->output($this->Html->image('icons/error.png', array('alt' => __('Failed', true)))); 
    88104        } 
     105 
     106        /** 
     107         * Return the small format icon of a job 
     108         */ 
     109        public function getFormatIcon($job) 
     110        { 
     111                if (!isset($job['Job'])) { 
     112                        $job = array('Job' => $job); 
     113                } 
     114 
     115                if (empty($job['Job']['Format'])) { 
     116                        return; 
     117                } 
     118 
     119                return $this->output($this->Html->image('icons/' . $job['Job']['Format']['icon'], array( 
     120                        'alt' => $job['Job']['Format']['name'], 
     121                )) . ' '); 
     122        } 
    89123} 
    90124 
Note: See TracChangeset for help on using the changeset viewer.