Пример #1
0
 protected function execute()
 {
     $conf = $this->getContext()->getConf();
     $browserIndex = BrowserInfo::getBrowserIndex();
     // Output
     $set = $this->getOption('set');
     if ($set) {
         if (isset($conf->browserSets->{$set})) {
             $this->out("{$set}:\n* " . implode("\n* ", $conf->browserSets->{$set}));
         } else {
             $this->error("Browser set `{$set}` does not exist.");
         }
     } else {
         foreach ($conf->browserSets as $set => $browsers) {
             $this->out("\n{$set}:\n* " . implode("\n* ", $browsers));
         }
         $this->out("\n(everything):\n* " . implode("\n* ", array_keys((array) $browserIndex)));
     }
 }
Пример #2
0
    /**
     * Iterate over all run rows and aggregate the runs and user agents.
     * @return Array List of runs and userAgents.
     */
    public static function getDataFromRunRows(TestSwarmContext $context, $runRows)
    {
        $db = $context->getDB();
        $userAgentIDs = array();
        $runs = array();
        foreach ($runRows as $runRow) {
            $runInfo = array('id' => $runRow->id, 'name' => $runRow->name, 'url' => $runRow->url);
            $runUaRuns = array();
            // Get list of useragents that this run is scheduled for
            $runUaRows = $db->getRows(str_queryf('SELECT
					status,
					useragent_id,
					results_id
				FROM
					run_useragent
				WHERE run_useragent.run_id = %u;', $runRow->id));
            if ($runUaRows) {
                foreach ($runUaRows as $runUaRow) {
                    // Add UA ID to the list. After we've collected
                    // all the UA IDs we'll perform one query for all of them
                    // to gather the info from the useragents table
                    $userAgentIDs[] = $runUaRow->useragent_id;
                    if (!$runUaRow->results_id) {
                        $runUaRuns[$runUaRow->useragent_id] = array('runStatus' => 'new');
                    } else {
                        $runresultsRow = $db->getRow(str_queryf('SELECT
								id,
								client_id,
								status,
								total,
								fail,
								error
							FROM runresults
							WHERE id = %u;', $runUaRow->results_id));
                        if (!$runresultsRow) {
                            $this->setError('data-corrupt');
                            return;
                        }
                        $runUaRuns[$runUaRow->useragent_id] = array('useragentID' => $runUaRow->useragent_id, 'clientID' => $runresultsRow->client_id, 'failedTests' => $runresultsRow->fail, 'totalTests' => $runresultsRow->total, 'errors' => $runresultsRow->error, 'runStatus' => self::getRunresultsStatus($runresultsRow), 'runResultsUrl' => swarmpath('result/' . $runUaRow->results_id), 'runResultsLabel' => $runresultsRow->status != ResultAction::$STATE_FINISHED ? '' : ($runresultsRow->error > 0 ? $runresultsRow->error : ($runresultsRow->fail > 0 ? $runresultsRow->fail : $runresultsRow->total)));
                    }
                }
                uksort($runUaRuns, array($context->getBrowserInfo(), 'sortUaId'));
                $runs[] = array('info' => $runInfo, 'uaRuns' => $runUaRuns);
            }
        }
        // Get information for all encounted useragents
        $browserIndex = BrowserInfo::getBrowserIndex();
        $userAgents = array();
        foreach ($userAgentIDs as $uaID) {
            if (!isset($browserIndex->{$uaID})) {
                // If it isn't in the index anymore, it means it has been removed from the browserSets
                // configuration. Use a generic fallback object;
                $userAgents[$uaID] = BrowserInfo::makeGenericUaData($uaID);
            } else {
                $userAgents[$uaID] = (array) $browserIndex->{$uaID};
            }
        }
        uasort($userAgents, 'BrowserInfo::sortUaData');
        return array('runs' => $runs, 'userAgents' => $userAgents);
    }
Пример #3
0
    protected function getAddjobFormHtml()
    {
        $conf = $this->getContext()->getConf();
        $request = $this->getContext()->getRequest();
        $auth = $this->getContext()->getAuth();
        $browserIndex = BrowserInfo::getBrowserIndex();
        $addjobPageUrlEsc = htmlspecialchars(swarmpath('addjob'));
        $authIDEsc = htmlspecialchars($request->getVal('authID', $auth ? $auth->project->id : ''));
        $authTokenEsc = htmlspecialchars($request->getVal('authToken', $auth ? $auth->sessionToken : ''));
        $formHtml = <<<HTML
<form action="{$addjobPageUrlEsc}" method="post" class="form-horizontal">

\t<fieldset>
\t\t<legend>Authentication</legend>

\t\t<div class="control-group">
\t\t\t<label class="control-label" for="form-authID">Project ID:</label>
\t\t\t<div class="controls">
\t\t\t\t<input type="text" name="authID" required value="{$authIDEsc}" id="form-authID">
\t\t\t</div>
\t\t</div>
\t\t<div class="control-group">
\t\t\t<label class="control-label" for="form-authToken">Auth token:</label>
\t\t\t<div class="controls">
\t\t\t\t<input type="text" name="authToken" required value="{$authTokenEsc}" id="form-authToken" class="input-xlarge">
\t\t\t</div>
\t\t</div>
\t</fieldset>

\t<fieldset>
\t\t<legend>Job information</legend>

\t\t<div class="control-group">
\t\t\t<label class="control-label" for="form-jobName">Job name:</label>
\t\t\t<div class="controls">
\t\t\t\t<input type="text" name="jobName" required maxlength="255" id="form-jobName" class="input-xlarge">
\t\t\t\t<span class="help-inline">HTML, up to 255 characters</span>
\t\t\t</div>
\t\t</div>
\t\t<div class="control-group">
\t\t\t<label class="control-label" for="form-runMax">Run max:</label>
\t\t\t<div class="controls">
\t\t\t\t<input type="number" name="runMax" required min="1" max="99" value="2" id="form-runMax" size="5">
\t\t\t\t<p class="help-block">This is the maximum number of times a run is ran in a user agent. If a run passes
\t\t\t\twithout failures then it is only ran once. If it does not pass, TestSwarm will re-try the run
\t\t\t\t(up to "Run max" times) for that useragent to avoid error pollution due to time-outs, slow
\t\t\t\tcomputers or other unrelated conditions that can cause the server to not receive a success report.</p>
\t\t\t</div>
\t\t</div>
\t</fieldset>

\t<fieldset>
\t\t<legend>Browsers</legend>

\t\t<p>Choose which groups of user agents this job should be ran in. Some of the groups may
\t\toverlap each other, TestSwarm will detect and remove duplicate entries in the resulting set.</p>

HTML;
        foreach ($conf->browserSets as $browserSet => $browsers) {
            $set = htmlspecialchars($browserSet);
            $browsersHtml = '';
            $last = count($browsers) - 1;
            foreach ($browsers as $i => $uaID) {
                $uaData = $browserIndex->{$uaID};
                if ($i === 0) {
                    $browsersHtml .= '<br>';
                } elseif ($i === $last) {
                    $browsersHtml .= '<br> and ';
                } else {
                    $browsersHtml .= ',<br>';
                }
                $browsersHtml .= htmlspecialchars($uaData->displayInfo['title']);
            }
            $formHtml .= <<<HTML
\t\t<div class="control-group">
\t\t\t<label class="checkbox" for="form-browserset-{$set}">
\t\t\t\t<input type="checkbox" name="browserSets[]" value="{$set}" id="form-browserset-{$set}">
\t\t\t\t<strong>{$set}</strong>: {$browsersHtml}.
\t\t\t</label>
\t\t</div>
HTML;
        }
        $formHtml .= <<<HTML
\t</fieldset>

\t<fieldset>
\t\t<legend>Runs</legend>

\t\t<p>Each job consists of several runs. Every run has a name and a url to where that test suite can be ran. All the test suites should probably have the same common code base or some other grouping characteristic, where each run is part of the larger test suite. As example, for a QUnit test suite the <code>filter</code> url parameter can be used to only run one of the "modules" so every run would be the name of that module and the URL to the testsuite with <code>?filter=modulename</code> appended to it.</p>

\t\t<div id="runs-container" class="well">
\t\t\t<fieldset>
\t\t\t\t<legend>Run 1</legend>

\t\t\t\t<label for="form-runNames1">Run name:</label>
\t\t\t\t<input type="text" name="runNames[]" id="form-runNames1" maxlength="255">
\t\t\t\t<br>
\t\t\t\t<label for="form-runUrls1">Run URL:</label>
\t\t\t\t<input type="text" name="runUrls[]" placeholder="http://" class="input-xlarge"id="form-runUrls1">
\t\t\t</fieldset>
\t\t\t<fieldset>
\t\t\t\t<legend>Run 2</legend>

\t\t\t\t<label for="form-runNames2">Run name:</label>
\t\t\t\t<input type="text" name="runNames[]" id="form-runNames2" maxlength="255">
\t\t\t\t<br>
\t\t\t\t<label for="form-runUrls2">Run URL:</label>
\t\t\t\t<input type="text" name="runUrls[]" placeholder="http://" class="input-xlarge"id="form-runUrls2">
\t\t\t</fieldset>
\t\t\t<fieldset>
\t\t\t\t<legend>Run 3</legend>

\t\t\t\t<label for="form-runNames3">Run name:</label>
\t\t\t\t<input type="text" name="runNames[]" id="form-runNames3" maxlength="255">
\t\t\t\t<br>
\t\t\t\t<label for="form-runUrls3">Run URL:</label>
\t\t\t\t<input type="text" name="runUrls[]" placeholder="http://" class="input-xlarge"id="form-runUrls3">
\t\t\t</fieldset>
\t\t</div>
\t</fieldset>

\t<div class="form-actions">
\t\t<input type="submit" value="Create job" class="btn btn-primary btn-large">
\t</div>
</form>
HTML;
        return $formHtml;
    }
Пример #4
0
 protected function findUnknown($table, $batchSize, $interactive)
 {
     $db = $this->getContext()->getDB();
     $browserIndex = BrowserInfo::getBrowserIndex();
     $uaIDs = array_keys((array) $browserIndex);
     $start = $db->getOne("SELECT MIN(id) FROM {$table};");
     $end = $db->getOne("SELECT MAX(id) FROM {$table};");
     if (!$start || !$end) {
         $this->error("The {$table} table appears empty.");
     }
     $found = array();
     $end += $batchSize - 1;
     // Do remaining chunk
     $blockStart = $start;
     $blockEnd = min($start + $batchSize - 1, $end);
     while ($blockEnd <= $end) {
         $this->out("...scanning {$table}.id {$blockStart} to {$blockEnd}");
         $rows = $db->getRows(str_queryf("SELECT DISTINCT(useragent_id) FROM {$table}\n\t\t\t\tWHERE id BETWEEN {$blockStart} AND {$blockEnd}\n\t\t\t\tAND useragent_id NOT IN %l;\n\t\t\t\t", $uaIDs));
         $blockStart += $batchSize;
         $blockEnd += $batchSize;
         // Optimise for continuing a batch, don't wait if this chunk didn't
         // affect any rows. This way we fast-forward to the next affectable chunk.
         if ($rows) {
             foreach ($rows as $row) {
                 // Don't list the same one twice.
                 if (in_array($row->useragent_id, $found)) {
                     continue;
                 }
                 $found[] = $row->useragent_id;
                 $this->out('* ' . $row->useragent_id);
                 if ($interactive) {
                     $this->out('Enter replacement uaID (or leave blank to skip):');
                     // Input should either be empty (to skip) or be a valid uaID,
                     // otherwise, repeat the question.
                     while (($input = $this->cliInput()) && !isset($browserIndex->{$input})) {
                         $this->out('The entered uaID was not found. Try again.');
                     }
                     if ($input) {
                         $this->runBatch($row->useragent_id, $input, $batchSize);
                     }
                 }
             }
         }
     }
     return $found;
 }
Пример #5
0
    /**
     * @actionParam string browserSet: Show useragents from a specific
     *  browserset only.
     * @actionParam bool onlyactive: If true, only user agents that
     *  have online clients and/or pending runs are included.
     *  If both "browserSet" and "onlyactive" are used, the overlaping
     *  subset will be output.
     */
    public function doAction()
    {
        $context = $this->getContext();
        $conf = $context->getConf();
        $db = $context->getDB();
        $request = $context->getRequest();
        $showOnlyactive = $request->getBool('onlyactive');
        $filterBrowserSet = $request->getVal('browserSet', false);
        $data = array('userAgents' => array());
        $browserIndex = BrowserInfo::getBrowserIndex();
        $browserSetByUaId = array();
        foreach ($conf->browserSets as $browserSet => $browsers) {
            foreach ($browsers as $browser) {
                $browserSetByUaId[$browser] = $browserSet;
            }
        }
        foreach ($browserIndex as $uaID => $uaData) {
            if ($filterBrowserSet && $browserSetByUaId[$uaID] !== $filterBrowserSet) {
                continue;
            }
            // Count online clients with this UA
            $clients = $db->getOne(str_queryf('SELECT
					COUNT(id)
				FROM clients
				WHERE useragent_id = %s
				AND   updated >= %s', $uaID, swarmdb_dateformat(Client::getMaxAge($context))));
            $clients = intval($clients);
            // Count active runs for this UA
            $activeRuns = $db->getOne(str_queryf('SELECT
					COUNT(*)
				FROM run_useragent
				WHERE useragent_id = %s
				AND   status = 1;', $uaID));
            $activeRuns = intval($activeRuns);
            // Count pending runs for this UA
            $pendingRuns = $db->getOne(str_queryf('SELECT
					COUNT(*)
				FROM run_useragent
				WHERE useragent_id = %s
				AND   status = 0
				AND   completed = 0;', $uaID));
            $pendingRuns = intval($pendingRuns);
            // Count past runs that can still be re-run to
            // possibly fix non-passing results
            $pendingReRuns = $db->getOne(str_queryf('SELECT
					COUNT(*)
				FROM run_useragent
				WHERE useragent_id = %s
				AND   status = 0
				AND   completed > 0;', $uaID));
            $pendingReRuns = intval($pendingReRuns);
            if (!$clients && !$activeRuns && !$pendingRuns && !$pendingReRuns) {
                if ($showOnlyactive || !isset($browserSetByUaId[$uaID])) {
                    continue;
                }
            }
            $data['userAgents'][$uaID] = array('data' => $uaData, 'stats' => array('onlineClients' => $clients, 'activeRuns' => $activeRuns, 'pendingRuns' => $pendingRuns, 'pendingReRuns' => $pendingReRuns));
        }
        // Make sure they are sorted nicely
        uasort($data['userAgents'], function ($a, $b) {
            return strnatcasecmp($a['data']->displayInfo['title'], $b['data']->displayInfo['title']);
        });
        $this->setData($data);
    }