|
[MediaWiki-CVS] SVN: [54066] trunk/extensions/CodeReview: msg#01444mediawiki-cvs
http://www.mediawiki.org/wiki/Special:Code/MediaWiki/54066 Revision: 54066 Author: brion Date: 2009-07-31 01:37:18 +0000 (Fri, 31 Jul 2009) Log Message: ----------- Server side for test run data integration into code review. Parser tests on trunk can now upload test results to a wiki running CodeReview. While the tests are running, the run data is marked as in progress and will display a spinner in the test column on the revision view. After completion, the result set is uploaded, and success/total counts are displayed, with nice red digits if there's failures. Failed tests are listed by name on the revision detail page. Currently details such as the output diff are not included, but there's a blob field ready to accept such. The status and result updates are sent to the API, action=codetestupdate. Rather than forcing the client side to figure out how to log in with an account, I'm just protecting it with an HMAC which validates that the request is legit; a shared secret should be configured on the client and server ends. Probably not too efficient in the list view as it'll pull a query per rev to get the counts... There's a summary of counts in code_test_run however there may be multiple rows as this is extended past ParserTests to encompass other test suites yet to be developed. Currently no UI for the test suite control data either; and we really need to clean up how the UI handles branching; we should make interesting branches/directories easily selectable in the UI so we can follow just trunk, or just some branch, or whatever. Note that, for instance, it only really makes sense to run the parser tests on trunk phase3, not on unrelated stuff in other branches; it'll let you send data for other versions, it just will be confusing. ;) Modified Paths: -------------- trunk/extensions/CodeReview/CodeRepository.php trunk/extensions/CodeReview/CodeReview.i18n.php trunk/extensions/CodeReview/CodeReview.php trunk/extensions/CodeReview/CodeRevision.php trunk/extensions/CodeReview/CodeRevisionListView.php trunk/extensions/CodeReview/CodeRevisionView.php trunk/extensions/CodeReview/codereview.css trunk/extensions/CodeReview/codereview.sql Added Paths: ----------- trunk/extensions/CodeReview/CodeTestResult.php trunk/extensions/CodeReview/CodeTestRun.php trunk/extensions/CodeReview/CodeTestSuite.php trunk/extensions/CodeReview/api/ApiCodeTestUpload.php trunk/extensions/CodeReview/archives/codereview-code_tests.sql Modified: trunk/extensions/CodeReview/CodeRepository.php =================================================================== --- trunk/extensions/CodeReview/CodeRepository.php 2009-07-31 01:19:00 UTC (rev 54065) +++ trunk/extensions/CodeReview/CodeRepository.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -170,6 +170,26 @@ throw new MWException( 'Failed to load expected revision data' ); return CodeRevision::newFromRow( $this, $row ); } + + /** + * Load test suite information + */ + public function getTestSuite( $name ) { + $dbr = wfGetDB( DB_SLAVE ); + $row = $dbr->selectRow( 'code_test_suite', + '*', + array( + 'ctsuite_repo_id' => $this->getId(), + 'ctsuite_name' => $name, + ), + __METHOD__ + ); + if( $row ) { + return CodeTestSuite::newFromRow( $this, $row ); + } else { + return null; + } + } /** * @param int $rev Revision ID Modified: trunk/extensions/CodeReview/CodeReview.i18n.php =================================================================== --- trunk/extensions/CodeReview/CodeReview.i18n.php 2009-07-31 01:19:00 UTC (rev 54065) +++ trunk/extensions/CodeReview/CodeReview.i18n.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -28,6 +28,7 @@ 'code-authors' => 'authors', 'code-status' => 'states', 'code-tags' => 'tags', + 'code-tests' => 'Test cases', 'code-authors-text' => 'Below is a list of repo authors in order of recent commits.', 'code-author-haslink' => 'This author is linked to the wiki user $1', 'code-author-orphan' => 'This author has no link with a wiki account', @@ -46,6 +47,7 @@ 'code-field-status' => 'Status', 'code-field-timestamp' => 'Date', 'code-field-comments' => 'Notes', + 'code-field-tests' => 'Tests', 'code-field-path' => 'Path', 'code-field-text' => 'Note', 'code-field-select' => 'Select', Modified: trunk/extensions/CodeReview/CodeReview.php =================================================================== --- trunk/extensions/CodeReview/CodeReview.php 2009-07-31 01:19:00 UTC (rev 54065) +++ trunk/extensions/CodeReview/CodeReview.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -40,6 +40,7 @@ $wgAutoloadClasses['ApiCodeUpdate'] = $dir . 'api/ApiCodeUpdate.php'; $wgAutoloadClasses['ApiCodeDiff'] = $dir . 'api/ApiCodeDiff.php'; $wgAutoloadClasses['ApiCodeComments'] = $dir . 'api/ApiCodeComments.php'; +$wgAutoloadClasses['ApiCodeTestUpload'] = $dir . 'api/ApiCodeTestUpload.php'; $wgAutoloadClasses['CodeDiffHighlighter'] = $dir . 'DiffHighlighter.php'; $wgAutoloadClasses['CodeRepository'] = $dir . 'CodeRepository.php'; @@ -66,6 +67,10 @@ $wgAutoloadClasses['CodeView'] = $dir . 'SpecialCode.php'; $wgAutoloadClasses['SpecialRepoAdmin'] = $dir . 'SpecialRepoAdmin.php'; +$wgAutoloadClasses['CodeTestSuite'] = $dir . 'CodeTestSuite.php'; +$wgAutoloadClasses['CodeTestRun'] = $dir . 'CodeTestRun.php'; +$wgAutoloadClasses['CodeTestResult'] = $dir . 'CodeTestResult.php'; + $wgSpecialPages['Code'] = 'SpecialCode'; $wgSpecialPageGroups['Code'] = 'developer'; $wgSpecialPages['RepoAdmin'] = 'SpecialRepoAdmin'; @@ -73,6 +78,7 @@ $wgAPIModules['codeupdate'] = 'ApiCodeUpdate'; $wgAPIModules['codediff'] = 'ApiCodeDiff'; +$wgAPIModules['codetestupload'] = 'ApiCodeTestUpload'; $wgAPIListModules['codecomments'] = 'ApiCodeComments'; $wgExtensionMessagesFiles['CodeReview'] = $dir . 'CodeReview.i18n.php'; @@ -129,6 +135,10 @@ // What images can be used for client-side side-by-side comparisons? $wgCodeReviewImgRegex = '/\.(png|jpg|jpeg|gif)$/i'; +// Set to a secret string for HMAC validation of test run data uploads. +// Should match test runner's $wgParserTestRemote['secret']. +$wgCodeReviewSharedSecret = false; + # Schema changes $wgHooks['LoadExtensionSchemaUpdates'][] = 'efCodeReviewSchemaUpdates'; @@ -141,6 +151,7 @@ $wgExtNewIndexes[] = array( 'code_relations', 'repo_to_from', "$base/archives/code_relations_index.sql" ); //$wgExtNewFields[] = array( 'code_rev', "$base/archives/codereview-cr_status.sql" ); // FIXME FIXME this is a change to options... don't know how $wgExtNewTables[] = array( 'code_bugs', "$base/archives/code_bugs.sql" ); + $wgExtNewTables[] = array( 'code_test_suite', "$base/archives/codereview-code_tests.sql" ); } elseif( $wgDBtype == 'postgres' ) { // TODO } Modified: trunk/extensions/CodeReview/CodeRevision.php =================================================================== --- trunk/extensions/CodeReview/CodeRevision.php 2009-07-31 01:19:00 UTC (rev 54065) +++ trunk/extensions/CodeReview/CodeRevision.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -578,6 +578,56 @@ public function isValidTag( $tag ) { return ( $this->normalizeTag( $tag ) !== false ); } + + public function getTestRuns() { + $dbr = wfGetDB( DB_SLAVE ); + $result = $dbr->select( + array( + 'code_test_suite', + 'code_test_run', + ), + '*', + array( + 'ctsuite_repo_id' => $this->mRepoId, + 'ctsuite_id=ctrun_suite_id', + 'ctrun_rev_id' => $this->mId, + ), + __METHOD__ ); + $runs = array(); + foreach( $result as $row ) { + $suite = CodeTestSuite::newFromRow( $this->mRepo, $row ); + $runs[] = new CodeTestRun( $suite, $row ); + } + return $runs; + } + + public function getTestResults( $success = null ) { + $dbr = wfGetDB( DB_SLAVE ); + $conds = array( + 'ctr_repo_id' => $this->mRepoId, + 'ctr_rev_id' => $this->mId, + 'ctr_case_id=ctc_id', + 'ctc_suite_id=cts_id' ); + if( $success === true ) { + $conds['ctr_result'] = 1; + } elseif( $success === false ) { + $conds['ctr_result'] = 0; + } + $results = $dbr->select( + array( + 'code_test_result', + 'code_test_case', + 'code_test_suite', + ), + '*', + $conds, + __METHOD__ ); + $out = array(); + foreach( $results as $row ) { + $out[] = new CodeTestResult( $row ); + } + return $out; + } public function getPrevious() { // hack! Modified: trunk/extensions/CodeReview/CodeRevisionListView.php =================================================================== --- trunk/extensions/CodeReview/CodeRevisionListView.php 2009-07-31 01:19:00 UTC (rev 54065) +++ trunk/extensions/CodeReview/CodeRevisionListView.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -187,7 +187,7 @@ 'options' => array( 'GROUP BY' => 'cp_rev_id', 'USE INDEX' => array( 'code_path' => 'cp_repo_id' ) ), 'join_conds' => array( 'code_rev' => array( 'INNER JOIN', 'cr_repo_id = cp_repo_id AND cr_id = cp_rev_id' ), - 'code_comment' => array( 'LEFT JOIN', 'cc_repo_id = cp_repo_id AND cc_rev_id = cp_rev_id' ) + 'code_comment' => array( 'LEFT JOIN', 'cc_repo_id = cp_repo_id AND cc_rev_id = cp_rev_id' ), ) ); // No path; entire repo... @@ -198,7 +198,7 @@ 'conds' => array( 'cr_repo_id' => $this->mRepo->getId() ), 'options' => array( 'GROUP BY' => 'cr_id' ), 'join_conds' => array( - 'code_comment' => array( 'LEFT JOIN', 'cc_repo_id = cr_repo_id AND cc_rev_id = cr_id' ) + 'code_comment' => array( 'LEFT JOIN', 'cc_repo_id = cr_repo_id AND cc_rev_id = cr_id' ), ) ); } @@ -206,8 +206,15 @@ } function getSelectFields() { - return array( $this->getDefaultSort(), 'cr_status', 'COUNT( DISTINCT cc_id ) AS comments', - 'cr_path', 'cr_message', 'cr_author', 'cr_timestamp' ); + return array( $this->getDefaultSort(), + 'cr_id', + 'cr_repo_id', + 'cr_status', + 'COUNT(DISTINCT cc_id) AS comments', + 'cr_path', + 'cr_message', + 'cr_author', + 'cr_timestamp' ); } function getFieldNames() { @@ -215,6 +222,7 @@ $this->getDefaultSort() => wfMsg( 'code-field-id' ), 'cr_status' => wfMsg( 'code-field-status' ), 'comments' => wfMsg( 'code-field-comments' ), + 'tests' => wfMsg( 'code-field-tests' ), 'cr_path' => wfMsg( 'code-field-path' ), 'cr_message' => wfMsg( 'code-field-message' ), 'cr_author' => wfMsg( 'code-field-author' ), @@ -260,6 +268,40 @@ } else { return intval( $value ); } + case 'tests': + // fixme -- this still isn't too efficient... + $rev = CodeRevision::newFromRow( $this->mRepo, $row ); + $runs = $rev->getTestRuns(); + if( empty( $runs ) ) { + return ' '; + } else { + $total = 0; + $success = 0; + $progress = false; + foreach( $runs as $run ) { + $total += $run->countTotal; + $success += $run->countSuccess; + if( $run->status == 'running' ) { + $progress = true; + } + } + if( $progress ) { + global $wgStylePath; + return Xml::element( 'img', array( + 'src' => "$wgStylePath/common/images/spinner.gif", + 'width' => 20, + 'height' => 20, + 'alt' => "...", + 'title' => "Tests in progress...", + )); + } + if( $success == $total ) { + $class = 'mw-codereview-success'; + } else { + $class = 'mw-codereview-fail'; + } + return "<span class='$class'><strong>$success</strong>/$total</span>"; + } case 'cr_path': return Xml::openElement( 'div', array( 'title' => (string)$value ) ) . $this->mView->mSkin->link( Modified: trunk/extensions/CodeReview/CodeRevisionView.php =================================================================== --- trunk/extensions/CodeReview/CodeRevisionView.php 2009-07-31 01:19:00 UTC (rev 54065) +++ trunk/extensions/CodeReview/CodeRevisionView.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -81,6 +81,12 @@ } $html .= $this->formatMetaData( $fields ); + # Show test case info + $tests = $this->formatTests(); + if( $tests ) { + $html .= "<h2 id='code-tests'>" . wfMsgHtml( 'code-tests' ) . + "</h2>\n" . $tests; + } # Output diff if ( $this->mRev->isDiffable() ) { $diffHtml = $this->formatDiff(); @@ -282,6 +288,42 @@ return $this->mSkin->link( $special, htmlspecialchars( $tag ) ); } + protected function formatTests() { + $runs = $this->mRev->getTestRuns(); + $html = ''; + if( count( $runs ) ) { + foreach( $runs as $run ) { + $html .= "<h3>" . htmlspecialchars( $run->suite->name ) . "</h3>\n"; + if( $run->status == 'complete' ) { + $total = $run->countTotal; + $success = $run->countSuccess; + $failed = $total - $success; + if( $failed ) { + $html .= "<p><span class='mw-codereview-success'>$success</span> succeeded tests, " . + "<span class='mw-codereview-fail'>$failed</span> failed tests:</p>"; + + $tests = $run->getResults( false ); + $html .= "<ul>\n"; + foreach( $tests as $test ) { + $html .= "<li>" . htmlspecialchars( $test->caseName ) . "</li>\n"; + } + $html .= "</ul>\n"; + } else { + $html .= "<p><span class='mw-codereview-success'>$success</span> succeeded tests.</p>"; + + } + } elseif( $run->status == "running" ) { + $html .= "<p>Test cases are running...</p>"; + } elseif( $run->status == "abort" ) { + $html .= "<p>Test run aborted.</p>"; + } else { + // Err, this shouldn't happen? + } + } + } + return $html; + } + protected function formatDiff() { global $wgEnableAPI; Added: trunk/extensions/CodeReview/CodeTestResult.php =================================================================== --- trunk/extensions/CodeReview/CodeTestResult.php (rev 0) +++ trunk/extensions/CodeReview/CodeTestResult.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -0,0 +1,11 @@ +<?php + +class CodeTestResult { + function __construct( CodeTestRun $run, $row ) { + $this->run = $run; + $this->id = $row->ctresult_id; + $this->caseId = $row->ctresult_case_id; + $this->caseName = $row->ctcase_name; + $this->success = (bool)$row->ctresult_success; + } +} Property changes on: trunk/extensions/CodeReview/CodeTestResult.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/extensions/CodeReview/CodeTestRun.php =================================================================== --- trunk/extensions/CodeReview/CodeTestRun.php (rev 0) +++ trunk/extensions/CodeReview/CodeTestRun.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -0,0 +1,170 @@ +<?php + +class CodeTestRun { + public function __construct( CodeTestSuite $suite, $row ) { + if( is_object( $row ) ) { + $row = wfObjectToArray( $row ); + } + $this->suite = $suite; + $this->id = intval( $row['ctrun_id'] ); + $this->revId = intval( $row['ctrun_rev_id'] ); + $this->status = $row['ctrun_status']; + $this->countTotal = $row['ctrun_count_total']; + $this->countSuccess = $row['ctrun_count_success']; + + $this->mCaseMap = null; // Lazy-initialize... + } + + public function getResults( $success=null ) { + $dbr = wfGetDB( DB_MASTER ); + $conds = array( + 'ctresult_run_id' => $this->id, + 'ctresult_case_id=ctcase_id', + ); + if( $success !== null ) { + $conds['ctresult_success'] = $success ? 1 : 0; + } + + $result = $dbr->select( + array( + 'code_test_result', + 'code_test_case', + ), + '*', + $conds, + __METHOD__ ); + + $out = array(); + foreach( $result as $row ) { + $out[] = new CodeTestResult( $this, $row ); + } + return $out; + } + + public static function newFromRevId( CodeTestSuite $suite, $revId ) { + $dbr = wfGetDB( DB_MASTER ); + $row = $dbr->selectRow( 'code_test_run', + '*', + array( + 'ctrun_suite_id' => $suite->id, + 'ctrun_rev_id' => $revId, + ), + __METHOD__ ); + if( $row ) { + return new CodeTestRun( $suite, $row ); + } else { + return null; + } + } + + public function setStatus( $status ) { + $this->status = $status; + $dbw = wfGetDB( DB_MASTER ); + $dbw->update( + 'code_test_run', + array( + 'ctrun_status' => $status, + ), + array( + 'ctrun_id' => $this->id, + ), + __METHOD__ ); + } + + public static function insertRun( CodeTestSuite $suite, $revId, $status, $results=array() ) { + $dbw = wfGetDB( DB_MASTER ); + $countTotal = count( $results ); + $countSucceeded = count( array_filter( $results ) ); + + $insertData = array( + 'ctrun_suite_id' => $suite->id, + 'ctrun_rev_id' => $revId, + 'ctrun_status' => $status, + 'ctrun_count_total' => $countTotal, + 'ctrun_count_success' => $countSucceeded, + ); + $dbw->insert( 'code_test_run', + $insertData, + __METHOD__ ); + + $insertData['ctrun_id'] = $dbw->insertId(); + $run = new CodeTestRun( $suite, $insertData ); + if( $status == 'complete' && $results ) { + $run->insertData( $results ); + } + return $run; + } + + public function getCaseId( $caseName ) { + $this->loadCaseMap(); + if( isset( $this->mCaseMap[$caseName] ) ) { + return $this->mCaseMap[$caseName]; + } else { + $dbw = wfGetDB( DB_MASTER ); + $dbw->insert( 'code_test_case', + array( + 'ctcase_suite_id' => $this->id, + 'ctcase_name' => $caseName, + ), + __METHOD__ ); + $id = intval( $dbw->insertId() ); + $this->mCaseMap[$caseName] = $id; + return $id; + } + } + + protected function loadCaseMap() { + if( is_null( $this->mCaseMap ) ) { + $this->mCaseMap = array(); + $dbw = wfGetDB( DB_MASTER ); + $result = $dbw->select( 'code_test_case', + array( + 'ctcase_id', + 'ctcase_name', + ), + array( + 'ctcase_suite_id' => $this->id, + ), + __METHOD__ + ); + foreach( $result as $row ) { + $this->mCaseMap[$row->ctcase_name] = intval( $row->ctcase_id ); + } + } + } + + public function saveResults( $results ) { + $this->insertResults( $results ); + $this->status = "complete"; + $dbw = wfGetDB( DB_MASTER ); + $dbw->update( + 'code_test_run', + array( + 'ctrun_status' => $this->status, + 'ctrun_count_total' => $this->countTotal, + 'ctrun_count_success' => $this->countSuccess, + ), + array( + 'ctrun_id' => $this->id, + ), + __METHOD__ ); + } + + public function insertResults( $results ) { + $dbw = wfGetDB( DB_MASTER ); + $this->countTotal = 0; + $this->countSuccess = 0; + foreach( $results as $caseName => $result ) { + $this->countTotal++; + if( $result ) { + $this->countSuccess++; + } + $insertData[] = array( + 'ctresult_run_id' => $this->id, + 'ctresult_case_id' => $this->getCaseId( $caseName ), + 'ctresult_success' => $result ? 1 : 0, + ); + } + $dbw->insert( 'code_test_result', $insertData, __METHOD__ ); + } +} Property changes on: trunk/extensions/CodeReview/CodeTestRun.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/extensions/CodeReview/CodeTestSuite.php =================================================================== --- trunk/extensions/CodeReview/CodeTestSuite.php (rev 0) +++ trunk/extensions/CodeReview/CodeTestSuite.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -0,0 +1,38 @@ +<?php + +class CodeTestSuite { + public static function newFromRow( CodeRepository $repo, $row ) { + $suite = new CodeTestSuite(); + $suite->id = intval( $row->ctsuite_id ); + $suite->repo = $repo; + $suite->repoId = $repo->getId(); + $suite->branchPath = $row->ctsuite_branch_path; + $suite->name = $row->ctsuite_name; + $suite->desc = $row->ctsuite_desc; + return $suite; + } + + function getRun( $revId ) { + return CodeTestRun::newFromRevId( $this, $revId ); + } + + function setStatus( $revId, $status ) { + $run = $this->getRun( $revId ); + if( $run ) { + $run->setStatus( $status ); + } else { + $run = CodeTestRun::insertRun( $this, $revId, $status ); + } + return $run; + } + + function saveResults( $revId, $results ) { + $run = $this->getRun( $revId ); + if( $run ) { + $run->saveResults( $results ); + } else { + $run = CodeTestRun::insertRun( $this, $revId, "complete", $results ); + } + return $run; + } +} Property changes on: trunk/extensions/CodeReview/CodeTestSuite.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/extensions/CodeReview/api/ApiCodeTestUpload.php =================================================================== --- trunk/extensions/CodeReview/api/ApiCodeTestUpload.php (rev 0) +++ trunk/extensions/CodeReview/api/ApiCodeTestUpload.php 2009-07-31 01:37:18 UTC (rev 54066) @@ -0,0 +1,119 @@ +<?php + +class ApiCodeTestUpload extends ApiBase { + + public function execute() { + global $wgUser; + // Before doing anything at all, let's check permissions + if( !$wgUser->isAllowed('codereview-use') ) { + $this->dieUsage('You don\'t have permission to upload test results', 'permissiondenied'); + } + $params = $this->extractRequestParams(); + + $this->validateParams( $params ); + $this->validateHmac( $params ); + + $repo = CodeRepository::newFromName( $params['repo'] ); + if( !$repo ) { + $this->dieUsage( "Invalid repo ``{$params['repo']}''", 'invalidrepo' ); + } + + $suite = $repo->getTestSuite( $params['suite'] ); + if( !$suite ) { + $this->dieUsage( "Invalid test suite ``{$params['suite']}''", 'invalidsuite' ); + } + + // Note that we might be testing a revision that hasn't gotten slurped in yet, + // so we won't reject data for revisions we don't know about yet. + $revId = intval( $params['rev'] ); + + $status = $params['status']; + if( $status == 'running' || $status == 'aborted' ) { + // Set the 'tests running' flag so we can mark it... + $suite->setStatus( $revId, $status ); + } elseif( $status == 'complete' ) { + // Save data and mark running test as completed. + $results = json_decode( $params['results'], true ); + if( !is_array( $results ) ) { + $this->dieUsage( "Invalid test result data", 'invalidresults' ); + } + $suite->saveResults( $revId, $results ); + } + } + + protected function validateParams( $params ) { + $required = array( 'repo', 'suite', 'rev', 'status', 'hmac' ); + if( isset( $params['status'] ) && $params['status'] == 'complete' ) { + $required[] = 'results'; + } + foreach( $required as $arg ) { + if ( !isset( $params[$arg] ) ) { + $this->dieUsageMsg( array( 'missingparam', $arg ) ); + } + } + } + + protected function validateHmac( $params ) { + global $wgCodeReviewSharedSecret; + + // Generate a hash MAC to validate our credentials + $message = array( + $params['repo'], + $params['suite'], + $params['rev'], + $params['status'], + ); + if( $params['status'] == "complete" ) { + $message[] = $params['results']; + } + $hmac = hash_hmac( "sha1", implode( "|", $message ), $wgCodeReviewSharedSecret ); + if( $hmac != $params['hmac'] ) { + $this->dieUsageMsg( array( 'invalidhmac', $params['hmac'] ) ); + } + } + + public function mustBePosted() { + // Discourage casual browsing :) + return true; + } + + public function isWriteMode() { + return true; + } + + public function getAllowedParams() { + return array( + 'repo' => null, + 'suite' => null, + 'rev' => array( + ApiBase::PARAM_TYPE => 'integer', + ApiBase::PARAM_MIN => 1 + ), + 'status' => array( + ApiBase::PARAM_TYPE => array( 'running', 'complete', 'abort' ), + ), + 'hmac' => null, + 'results' => null, + ); + } + + public function getParamDescription() { + return array( + 'repo' => 'Name of repository to update', + 'suite' => 'Name of test suite to record run results for', + 'rev' => 'Revision ID tests were run against', + 'status' => 'Status of test run', + 'hmac' => 'HMAC validation', + 'results' => 'JSON-encoded map of test names to success results, for status "complete"', + ); + } + + public function getDescription() { + return array( + 'Upload CodeReview test run results from a test runner.' ); + } + + public function getVersion() { + return __CLASS__ . ': $Id: ApiCodeUpdate.php 48928 2009-03-27 18:41:20Z catrope $'; + } +} Property changes on: trunk/extensions/CodeReview/api/ApiCodeTestUpload.php ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/extensions/CodeReview/archives/codereview-code_tests.sql =================================================================== --- trunk/extensions/CodeReview/archives/codereview-code_tests.sql (rev 0) +++ trunk/extensions/CodeReview/archives/codereview-code_tests.sql 2009-07-31 01:37:18 UTC (rev 54066) @@ -0,0 +1,66 @@ +-- +-- Information on available test suites +DROP TABLE IF EXISTS /*$wgDBprefix*/code_test_suite; +CREATE TABLE /*$wgDBprefix*/code_test_suite ( + -- Unique ID per test suite + ctsuite_id int auto_increment not null, + + -- Repository ID of the code base this applies to + ctsuite_repo_id int not null, + + -- Which branch path this applies to, eg '/trunk/phase3' + ctsuite_branch_path varchar(255) not null, + + -- Pleasantly user-readable name, eg "ParserTests" + ctsuite_name varchar(255) not null, + + -- Description... + ctsuite_desc varchar(255) not null, + + primary key ctsuite_id (ctsuite_id) +) /*$wgDBtableOptions*/; + +DROP TABLE IF EXISTS /*$wgDBprefix*/code_test_case; +CREATE TABLE /*$wgDBprefix*/code_test_case ( + ctcase_id int auto_increment not null, + ctcase_suite_id int not null, + ctcase_name varchar(255) not null, + + primary key ctc_id (ctcase_id), + key (ctcase_suite_id, ctcase_id) +) /*$wgDBtableOptions*/; + +DROP TABLE IF EXISTS /*$wgDBprefix*/code_test_run; +CREATE TABLE /*$wgDBprefix*/code_test_run ( + ctrun_id int auto_increment not null, + + ctrun_suite_id int not null, + ctrun_rev_id int not null, + + ctrun_status enum ('running', 'complete', 'abort'), + + ctrun_count_total int, + ctrun_count_success int, + + primary key ctrun_id (ctrun_id), + key suite_rev (ctrun_suite_id, ctrun_rev_id) +) /*$wgDBtableOptions*/; + + +DROP TABLE IF EXISTS /*$wgDBprefix*/code_test_result; +CREATE TABLE /*$wgDBprefix*/code_test_result ( + ctresult_id int auto_increment not null, + + -- Which test run and case are we on? + ctresult_run_id int not null, + ctresult_case_id int not null, + + -- Did we succeed or fail? + ctresult_success bool not null, + + -- Optional HTML chunk data + ctresult_details blob, + + primary key ctr_id (ctresult_id), + key run_id (ctresult_run_id, ctresult_id) +) /*$wgDBtableOptions*/; Property changes on: trunk/extensions/CodeReview/archives/codereview-code_tests.sql ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/extensions/CodeReview/codereview.css =================================================================== --- trunk/extensions/CodeReview/codereview.css 2009-07-31 01:19:00 UTC (rev 54065) +++ trunk/extensions/CodeReview/codereview.css 2009-07-31 01:37:18 UTC (rev 54066) @@ -78,6 +78,13 @@ color: #666; } +.mw-codereview-success { + color: #1a2; +} +.mw-codereview-fail { + color: #d21; +} + /* Diffs */ .mw-codereview-diff ins { text-decoration: none; Modified: trunk/extensions/CodeReview/codereview.sql =================================================================== --- trunk/extensions/CodeReview/codereview.sql 2009-07-31 01:19:00 UTC (rev 54065) +++ trunk/extensions/CodeReview/codereview.sql 2009-07-31 01:37:18 UTC (rev 54066) @@ -65,7 +65,7 @@ cr_diff mediumblob NULL, -- Text flags: gzip,utf-8,external cr_flags tinyblob NOT NULL, - + primary key (cr_repo_id, cr_id), key (cr_repo_id, cr_timestamp), key cr_repo_author (cr_repo_id, cr_author, cr_timestamp) @@ -217,3 +217,70 @@ key cpc_repo_rev_time (cpc_repo_id, cpc_rev_id, cpc_timestamp), key cpc_repo_time (cpc_repo_id, cpc_timestamp) ) /*$wgDBTableOptions*/; + +-- +-- Information on available test suites +DROP TABLE IF EXISTS /*$wgDBprefix*/code_test_suite; +CREATE TABLE /*$wgDBprefix*/code_test_suite ( + -- Unique ID per test suite + ctsuite_id int auto_increment not null, + + -- Repository ID of the code base this applies to + ctsuite_repo_id int not null, + + -- Which branch path this applies to, eg '/trunk/phase3' + ctsuite_branch_path varchar(255) not null, + + -- Pleasantly user-readable name, eg "ParserTests" + ctsuite_name varchar(255) not null, + + -- Description... + ctsuite_desc varchar(255) not null, + + primary key ctsuite_id (ctsuite_id) +) /*$wgDBtableOptions*/; + +DROP TABLE IF EXISTS /*$wgDBprefix*/code_test_case; +CREATE TABLE /*$wgDBprefix*/code_test_case ( + ctcase_id int auto_increment not null, + ctcase_suite_id int not null, + ctcase_name varchar(255) not null, + + primary key ctc_id (ctcase_id), + key (ctcase_suite_id, ctcase_id) +) /*$wgDBtableOptions*/; + +DROP TABLE IF EXISTS /*$wgDBprefix*/code_test_run; +CREATE TABLE /*$wgDBprefix*/code_test_run ( + ctrun_id int auto_increment not null, + + ctrun_suite_id int not null, + ctrun_rev_id int not null, + + ctrun_status enum ('running', 'complete', 'abort'), + + ctrun_count_total int, + ctrun_count_success int, + + primary key ctrun_id (ctrun_id), + key suite_rev (ctrun_suite_id, ctrun_rev_id) +) /*$wgDBtableOptions*/; + + +DROP TABLE IF EXISTS /*$wgDBprefix*/code_test_result; +CREATE TABLE /*$wgDBprefix*/code_test_result ( + ctresult_id int auto_increment not null, + + -- Which test run and case are we on? + ctresult_run_id int not null, + ctresult_case_id int not null, + + -- Did we succeed or fail? + ctresult_success bool not null, + + -- Optional HTML chunk data + ctresult_details blob, + + primary key ctr_id (ctresult_id), + key run_id (ctresult_run_id, ctresult_id) +) /*$wgDBtableOptions*/; _______________________________________________ MediaWiki-CVS mailing list MediaWiki-CVS@xxxxxxxxxxxxxxxxxxx https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs
|
|
||||||||||||||||||||||||||
|
|
|
| News | Mail Home | sitemap | FAQ | advertise |