/** * Update client 'alive' and refresh client config. * * @actionMethod POST: Required. * @actionParam run_token string * @actionParam client_id int */ public function doAction() { $conf = $this->getContext()->getConf(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError('requires-post'); return; } $runToken = $request->getVal('run_token'); if ($conf->client->requireRunToken && !$runToken) { $this->setError('missing-parameters', 'This TestSwarm does not allow unauthorized clients to join the swarm.'); return; } $clientID = $request->getInt('client_id'); if (!$clientID) { $this->setError('missing-parameters'); return; } // Create a Client object that verifies client id, user agent and run token. // Also updates the client 'alive' timestamp. // Throws exception (caught higher up) if stuff is invalid. $client = Client::newFromContext($this->getContext(), $runToken, $clientID); $db = $this->getContext()->getDB(); $device_name = $db->getOne(str_queryf("SELECT device_name FROM clients WHERE id = %u;", $clientID)); if (!isset($device_name)) { $device_name = 'Testswarm ID = ' . $clientID; } $this->setData(array('status' => 'ok', 'confUpdate' => array('client' => $conf->client, 'deviceName' => $device_name))); }
/** * @actionMethod POST: Required. * @actionParam client_id int * @actionParam run_token string * @actionParam run_id int * @actionParam fail int * @actionParam error int * @actionParam total int * @actionParam results string: HTML snapshot of the test results page. */ public function doAction() { $browserInfo = $this->getContext()->getBrowserInfo(); $conf = $this->getContext()->getConf(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $runToken = $request->getVal("run_token"); if ($conf->client->requireRunToken && !$runToken) { $this->setError("invalid-input", "This TestSwarm does not allow unauthorized clients to join the swarm."); return; } $clientID = $request->getInt("client_id"); if (!$clientID) { $this->setError("invalid-input"); return; } // Create a Client object that verifies client id, user agent and run token. // Also updates the client 'alive' timestamp. // Throws exception (caught higher up) if stuff is invalid. $client = Client::newFromContext($this->getContext(), $runToken, $clientID); $runID = $request->getInt("run_id"); $fail = $request->getInt("fail"); $error = $request->getInt("error"); $total = $request->getInt("total"); $results = gzencode($request->getVal("results", "")); $db->query(str_queryf("UPDATE\n\t\t\t\trun_client\n\t\t\tSET\n\t\t\t\tstatus = 2,\n\t\t\t\tfail = %u,\n\t\t\t\terror = %u,\n\t\t\t\ttotal = %u,\n\t\t\t\tresults = %s,\n\t\t\t\tupdated = %s\n\t\t\tWHERE client_id = %u\n\t\t\tAND run_id = %u\n\t\t\tLIMIT 1;", $fail, $error, $total, $results, swarmdb_dateformat(SWARM_NOW), $clientID, $runID)); if (mysql_affected_rows() > 0) { // If we're 100% passing we don't need any more runs // Clear out other entries from other browsers for the same run // that were bad, since we now have a good one. if ($total > 0 && $fail === 0 && $error === 0) { $rows = $db->getRows(str_queryf("SELECT client_id\n\t\t\t\t\tFROM\n\t\t\t\t\t\trun_client, clients\n\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\tAND client_id != %u\n\t\t\t\t\tAND (total <= 0 OR error > 0 OR fail > 0)\n\t\t\t\t\tAND clients.id = client_id\n\t\t\t\t\tAND clients.useragent_id = %s;", $runID, $clientID, $client->getClientRow()->useragent_id)); if ($rows) { foreach ($rows as $row) { $db->query(str_queryf("DELETE\n\t\t\t\t\t\t\tFROM run_client\n\t\t\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\t\t\tAND client_id = %u;", $runID, $row->client_id)); } } $db->query(str_queryf("UPDATE\n\t\t\t\t\t\trun_useragent\n\t\t\t\t\tSET\n\t\t\t\t\t\truns = max,\n\t\t\t\t\t\tcompleted = completed + 1,\n\t\t\t\t\t\tstatus = 2,\n\t\t\t\t\t\tupdated = %s\n\t\t\t\t\tWHERE useragent_id = %s\n\t\t\t\t\tAND run_id = %u\n\t\t\t\t\tLIMIT 1;", swarmdb_dateformat(SWARM_NOW), $browserInfo->getSwarmUaID(), $runID)); } else { // Clear out old runs that timed out. if ($total > 0) { $rows = $db->getRows(str_queryf("SELECT\n\t\t\t\t\t\t\tclient_id\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\trun_client\n\t\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\t\tAND client_id != %u\n\t\t\t\t\t\tAND total <= 0;", $runID, $clientID)); if ($rows) { foreach ($rows as $row) { $db->query(str_queryf("DELETE\n\t\t\t\t\t\t\t\tFROM run_client\n\t\t\t\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\t\t\t\tAND client_id = %u;", $runID, $row->client_id)); } } } $db->query(str_queryf("UPDATE\n\t\t\t\t\t\trun_useragent\n\t\t\t\t\tSET\n\t\t\t\t\t\tcompleted = completed + 1,\n\t\t\t\t\t\tstatus = IF(completed + 1 < max, 1, 2),\n\t\t\t\t\t\tupdated = %s\n\t\t\t\t\tWHERE useragent_id = %s\n\t\t\t\t\tAND run_id = %u\n\t\t\t\t\tLIMIT 1;", swarmdb_dateformat(SWARM_NOW), $browserInfo->getSwarmUaID(), $runID)); } } $this->setData("ok"); }
protected function initContent() { $browserInfo = $this->getContext()->getBrowserInfo(); $conf = $this->getContext()->getConf(); $request = $this->getContext()->getRequest(); $this->setTitle('Test runner'); $runToken = null; if ($conf->client->requireRunToken) { $runToken = $request->getVal("run_token"); if (!$runToken) { return '<div class="alert alert-error">This swarm has restricted access to join the swarm.</div>'; } } $this->bodyScripts[] = swarmpath("js/run.js?" . time()); $client = Client::newFromContext($this->getContext(), $runToken); $html = '<script>' . 'SWARM.client_id = ' . json_encode($client->getClientRow()->id) . ';' . 'SWARM.run_token = ' . json_encode($runToken) . ';' . '</script>'; $html .= '<div class="row">' . '<div class="span2">' . $browserInfo->getIconHtml() . '</div>' . '<div class="span7">' . '<h2>' . htmlspecialchars($client->getClientRow()->name) . '</h2>' . '<p><strong>Status:</strong> <span id="msg"></span></p>' . '</div>' . '</div>' . '<div class="well">' . '<h3>History</h3>' . '<ul id="history"></ul>' . '</div>' . '<div id="iframes"></div>'; return $html; }
protected function initContent() { $browserInfo = $this->getContext()->getBrowserInfo(); $conf = $this->getContext()->getConf(); $request = $this->getContext()->getRequest(); $uaItem = $browserInfo->getSwarmUaItem(); $runToken = null; if ($conf->client->requireRunToken) { $runToken = $request->getVal("run_token"); if (!$runToken) { throw new SwarmException("This swarm has restricted access to join the swarm."); } } $this->setTitle("Test runner"); $this->displayPageTitle = false; $this->displayNavBar = false; $this->useContainerCssClass = true; if ($browserInfo->getSwarmUaItem()->id === "PS3") { $this->bodyScripts[] = swarmpath("js/base64encoder.js"); } $this->bodyScripts[] = swarmpath("js/run.js?" . time()); $client = null; // Try to get the client id from the cookie. $clientId = $this->getClientIdFromCookie(); if (isset($clientId)) { // If client id is present then try to reuse it. // This might throw an exception if client id doesn't exist on the database, the user agent doesn't match or the ip address doesn't match the database record. try { $client = Client::newFromContext($this->getContext(), $runToken, $clientId, true); } catch (Exception $e) { } } // $client is not set if restoring client id failed or cookie is not present. if (!isset($client)) { $client = Client::newFromContext($this->getContext(), $runToken); $clientId = $client->getClientRow()->id; $this->saveClientIdInCookie($clientId); } $html = '<script>' . 'SWARM.client_id = ' . json_encode($clientId) . ';' . 'SWARM.run_token = ' . json_encode($runToken) . ';' . 'SWARM.decode_html = ' . json_encode(isMaple()) . ';' . '</script>'; $html .= '<div class="row">' . '<div class="span2">' . '<div class="well pagination-centered thumbnail">' . '<img src="' . swarmpath("img/{$uaItem->displayicon}.sm.png") . '" class="swarm-browsericon ' . '" alt="' . htmlspecialchars($uaItem->displaytitle) . '" title="' . htmlspecialchars($uaItem->displaytitle) . '">' . '<span class="label">' . htmlspecialchars($uaItem->displaytitle) . '</span>' . '<br/>' . '<span class="label label-info" id="deviceName"></span>' . '</div>' . '</div>' . '<div class="span7">' . '<h2>' . htmlspecialchars($client->getUserRow()->name) . '</h2>' . '<p><strong>Status:</strong> <span id="msg"></span></p>' . '</div>' . '</div>' . '<div id="iframes"></div>' . '<div class="well">' . '<h3>History</h3>' . '<ul id="history"></ul>' . '</div>'; return $html; }
protected function initContent() { $browserInfo = $this->getContext()->getBrowserInfo(); $conf = $this->getContext()->getConf(); $request = $this->getContext()->getRequest(); $uaItem = $browserInfo->getSwarmUaItem(); $runToken = null; if ($conf->client->requireRunToken) { $runToken = $request->getVal("run_token"); if (!$runToken) { throw new SwarmException("This swarm has restricted access to join the swarm."); } } $this->setTitle("Test runner"); $this->bodyScripts[] = swarmpath("js/run.js?" . time()); $client = Client::newFromContext($this->getContext(), $runToken); $html = '<script>' . 'SWARM.client_id = ' . json_encode($client->getClientRow()->id) . ';' . 'SWARM.run_token = ' . json_encode($runToken) . ';' . '</script>'; $html .= '<div class="row">' . '<div class="span2">' . '<div class="well pagination-centered thumbnail">' . '<img src="' . swarmpath("img/{$uaItem->displayicon}.sm.png") . '" class="swarm-browsericon ' . '" alt="' . htmlspecialchars($uaItem->displaytitle) . '" title="' . htmlspecialchars($uaItem->displaytitle) . '">' . '<span class="label">' . htmlspecialchars($uaItem->displaytitle) . '</span>' . '</div>' . '</div>' . '<div class="span7">' . '<h2>' . htmlspecialchars($client->getUserRow()->name) . '</h2>' . '<p><strong>Status:</strong> <span id="msg"></span></p>' . '</div>' . '</div>' . '<div class="well">' . '<h3>History</h3>' . '<ul id="history"></ul>' . '</div>' . '<div id="iframes"></div>'; return $html; }
/** * @actionMethod POST: Required. * @actionParam run_token string * @actionParam client_id int */ public function doAction() { $browserInfo = $this->getContext()->getBrowserInfo(); $conf = $this->getContext()->getConf(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $runToken = $request->getVal("run_token"); if ($conf->client->requireRunToken && !$runToken) { $this->setError("invalid-input", "This TestSwarm does not allow unauthorized clients to join the swarm."); return; } $clientID = $request->getInt("client_id"); if (!$clientID) { $this->setError("invalid-input"); return; } // Create a Client object that verifies client id, user agent and run token. // Also updates the client 'alive' timestamp. // Throws exception (caught higher up) if stuff is invalid. $client = Client::newFromContext($this->getContext(), $runToken, $clientID); // Get oldest run for this user agent, that isn't on the max yet and isn't // already ran by another client. $runID = $db->getOne(str_queryf("SELECT\n\t\t\t\trun_id\n\t\t\tFROM\n\t\t\t\trun_useragent\n\t\t\tWHERE useragent_id = %s\n\t\t\tAND runs < max\n\t\t\tAND NOT EXISTS (SELECT 1 FROM run_client WHERE run_useragent.run_id = run_id AND client_id = %u)\n\t\t\tORDER BY run_id DESC\n\t\t\tLIMIT 1;", $browserInfo->getSwarmUaID(), $clientID)); $runInfo = false; // A run was found for the current user_agent if ($runID) { $row = $db->getRow(str_queryf("SELECT\n\t\t\t\t\truns.url as run_url,\n\t\t\t\t\tjobs.name as job_name,\n\t\t\t\t\truns.name as run_name\n\t\t\t\tFROM\n\t\t\t\t\truns, jobs\n\t\t\t\tWHERE runs.id = %u\n\t\t\t\tAND jobs.id = runs.job_id\n\t\t\t\tLIMIT 1;", $runID)); if ($row->run_url && $row->job_name && $row->run_name) { # Mark the run as "in progress" on the useragent $db->query(str_queryf("UPDATE run_useragent\n\t\t\t\t\tSET\n\t\t\t\t\t\truns = runs + 1,\n\t\t\t\t\t\tstatus = 1,\n\t\t\t\t\t\tupdated = %s\n\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\tAND useragent_id = %s\n\t\t\t\t\tLIMIT 1;", swarmdb_dateformat(SWARM_NOW), $runID, $browserInfo->getSwarmUaID())); # Initialize the client run $db->query(str_queryf("INSERT INTO run_client\n\t\t\t\t\t(run_id, client_id, status, updated, created)\n\t\t\t\t\tVALUES(%u, %u, 1, %s, %s);", $runID, $clientID, swarmdb_dateformat(SWARM_NOW), swarmdb_dateformat(SWARM_NOW))); $runInfo = array("id" => $runID, "url" => $row->run_url, "desc" => $row->job_name . ' ' . $row->run_name); } } $this->setData(array("confUpdate" => array("client" => $conf->client), "runInfo" => $runInfo)); }
/** * @actionMethod POST: Required. * @actionParam int client_id * @actionParam string run_token * @actionParam int run_id * @actionParam string results_id * @actionParam string results_store_token * @actionParam int total * @actionParam int fail * @actionParam int error * @actionParam int status: `runresults.status` * @actionParam string report_html: HTML snapshot of the test results page. */ public function doAction() { $browserInfo = $this->getContext()->getBrowserInfo(); $conf = $this->getContext()->getConf(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError('requires-post'); return; } $runToken = $request->getVal('run_token'); if ($conf->client->requireRunToken && !$runToken) { $this->setError('missing-parameters', 'This TestSwarm does not allow unauthorized clients to join the swarm.'); return; } $runID = $request->getInt('run_id'); $clientID = $request->getInt('client_id'); $resultsID = $request->getVal('results_id'); $resultsStoreToken = $request->getVal('results_store_token'); if (!$runID || !$clientID || !$resultsID || !$resultsStoreToken) { $this->setError('missing-parameters'); return; } // Create a Client object that verifies client id, user agent and run token. // Also updates the client 'alive' timestamp. // Throws exception (caught higher up) if stuff is invalid. $client = Client::newFromContext($this->getContext(), $runToken, $clientID); $total = $request->getInt('total', 0); $fail = $request->getInt('fail', 0); $error = $request->getInt('error', 0); $status = $request->getInt('status', 2); $reportHtml = $request->getVal('report_html', ''); if (!in_array($status, array(2, 3))) { $this->setError('invalid-input', 'Illegal status to be set from the client side in action=saverun.'); return; } // Verify this runresults row exists, // also naturally validates run_id and store_token $res = $db->query(str_queryf('SELECT id FROM runresults WHERE id = %u AND run_id = %u AND store_token = %s;', $resultsID, $runID, sha1($resultsStoreToken))); if (!$res || $db->getNumRows($res) !== 1) { $this->setError('invalid-input'); return; } $db->query(str_queryf('UPDATE runresults SET status = %u, total = %u, fail = %u, error = %u, report_html = %s, updated = %s WHERE id = %u LIMIT 1;', $status, $total, $fail, $error, gzencode($reportHtml), swarmdb_dateformat(SWARM_NOW), $resultsID)); if ($db->getAffectedRows() !== 1) { $this->setError('internal-error', 'Updating of results table failed.'); return; } $isPassed = $total > 0 && $fail === 0 && $error === 0; // Use results_id in the WHERE clause as additional check, just in case // this runresults row is no longer the primary linked one. // This fixes a race condition where (for some reason) 2 clients run the // same run, and the "good" one started last and finishes first. When the // "bad" client finishes and updates this run as not passing, it would // mismatch the results the user would find in the linked report from runresults. // Be sure to use it only as "WHERE" not in "SET", as that could cause // an equally bad effect (unlink a good run). if ($isPassed) { $db->query(str_queryf('UPDATE run_useragent SET completed = completed + 1, status = 2, updated = %s WHERE run_id = %u AND useragent_id = %s AND results_id = %u LIMIT 1;', swarmdb_dateformat(SWARM_NOW), $runID, $browserInfo->getSwarmUaID(), $resultsID)); } else { // If we don't pass and we haven't reached max yet, // set status back to 0 so that this run may be // distributed again (see also GetrunAction), // If we don't pass and did reach the max, set // status=2. $db->query(str_queryf('UPDATE run_useragent SET completed = completed + 1, status = IF(completed + 1 < max, 0, 2), updated = %s WHERE run_id = %u AND useragent_id = %s AND results_id = %u LIMIT 1;', swarmdb_dateformat(SWARM_NOW), $runID, $browserInfo->getSwarmUaID(), $resultsID)); } $this->setData('ok'); }
/** * @actionMethod POST: Required. * @actionParam run_token string * @actionParam client_id int */ public function doAction() { $browserInfo = $this->getContext()->getBrowserInfo(); $conf = $this->getContext()->getConf(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $runToken = $request->getVal("run_token"); if ($conf->client->requireRunToken && !$runToken) { $this->setError("missing-parameters", "This TestSwarm does not allow unauthorized clients to join the swarm."); return; } $clientID = $request->getInt("client_id"); if (!$clientID) { $this->setError("missing-parameters"); return; } // Create a Client object that verifies client id, user agent and run token. // Also updates the client 'alive' timestamp. // Throws exception (caught higher up) if stuff is invalid. $client = Client::newFromContext($this->getContext(), $runToken, $clientID); // Get oldest idle (status=0) run for this user agent. // Except if it was already ran in this client in the past (client_id=%u), because // in that case it must've failed. We don't want it to run in the same client again. $runID = $db->getOne(str_queryf('SELECT run_id FROM run_useragent WHERE useragent_id = %s AND status = 0 AND NOT EXISTS (SELECT 1 FROM runresults WHERE runresults.run_id = run_useragent.run_id AND runresults.client_id = %u) ORDER BY run_id DESC LIMIT 1;', $browserInfo->getSwarmUaID(), $clientID)); $runInfo = false; // A run was found for the current user_agent if ($runID) { $row = $db->getRow(str_queryf("SELECT\n\t\t\t\t\truns.url as run_url,\n\t\t\t\t\tjobs.name as job_name,\n\t\t\t\t\truns.name as run_name\n\t\t\t\tFROM\n\t\t\t\t\truns, jobs\n\t\t\t\tWHERE runs.id = %u\n\t\t\t\tAND jobs.id = runs.job_id\n\t\t\t\tLIMIT 1;", $runID)); if ($row->run_url && $row->job_name && $row->run_name) { // Create stub runresults entry $storeToken = sha1(mt_rand()); $isInserted = $db->query(str_queryf('INSERT INTO runresults (run_id, client_id, status, store_token, updated, created) VALUES(%u, %u, 1, %s, %s, %s);', $runID, $clientID, sha1($storeToken), swarmdb_dateformat(SWARM_NOW), swarmdb_dateformat(SWARM_NOW))); $runresultsId = $db->getInsertId(); if (!$isInserted || !$runresultsId) { $this->setError('internal-error', 'Creation of runresults database entry failed.'); return false; } // Mark as in-progress (status=1), and link runresults entry $db->query(str_queryf('UPDATE run_useragent SET status = 1, updated = %s, results_id = %u WHERE run_id = %u AND useragent_id = %s LIMIT 1;', swarmdb_dateformat(SWARM_NOW), $runresultsId, $runID, $browserInfo->getSwarmUaID())); $runInfo = array("id" => $runID, "url" => $row->run_url, "desc" => $row->job_name . ' ' . $row->run_name, 'resultsId' => $runresultsId, 'resultsStoreToken' => $storeToken); } } $this->setData(array('runInfo' => $runInfo)); }