| [ Index ] |
PHP Cross Reference of Limb3 |
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 * $Id: RemoteCoverageRecorder.php 14665 2005-03-23 19:37:50Z npac $ 4 * 5 * Copyright(c) 2004-2005, SpikeSource Inc. All Rights Reserved. 6 * Licensed under the Open Source License version 2.1 7 * (See http://www.spikesource.com/license.html) 8 */ 9 ?> 10 <?php 11 12 if(!defined("__PHPCOVERAGE_HOME")) { 13 define("__PHPCOVERAGE_HOME", dirname(dirname(__FILE__))); 14 } 15 require_once __PHPCOVERAGE_HOME . "/util/Utility.php"; 16 require_once __PHPCOVERAGE_HOME . "/CoverageRecorder.php"; 17 require_once __PHPCOVERAGE_HOME . "/remote/XdebugTraceReader.php"; 18 require_once __PHPCOVERAGE_HOME . "/parser/CoverageXmlParser.php"; 19 20 /** 21 * A Coverage recorder extension for remote Coverage measurement. 22 * 23 * @author Nimish Pachapurkar <npac@spikesource.com> 24 * @version $Revision: $ 25 * @package tests_runner 26 */ 27 class RemoteCoverageRecorder extends CoverageRecorder { 28 /*{{{ Members */ 29 30 protected $traceFilePath; 31 protected $xdebugTraceReader; 32 protected $tmpDir; 33 protected $tmpTraceFilename = "phpcoverage.xdebug.trace"; 34 protected $coverageFileName = "phpcoverage.coverage.xml"; 35 36 protected $xmlStart = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><spike-phpcoverage>"; 37 protected $xmlEnd = "</spike-phpcoverage>"; 38 39 /*}}}*/ 40 /*{{{ public function __construct() */ 41 42 /** 43 * Constructor 44 * 45 * @access public 46 */ 47 public function __construct( 48 $includePaths=array("."), 49 $excludePaths=array(), 50 $reporter="new HtmlCoverageReporter()" 51 ) { 52 parent::__construct($includePaths, $excludePaths, $reporter); 53 $this->isRemote = true; 54 $this->phpCoverageFiles[] = "phpcoverage.remote.inc.php"; 55 $this->phpCoverageFiles[] = "phpcoverage.remote.top.inc.php"; 56 $this->phpCoverageFiles[] = "phpcoverage.remote.bottom.inc.php"; 57 58 // configuration 59 global $util; 60 $this->tmpDir = $util->getTmpDir(); 61 } 62 63 /*}}}*/ 64 /*{{{ Getters and Setters */ 65 66 public function getTraceFilePath() { 67 return $this->traceFilePath; 68 } 69 70 public function setTraceFilePath($traceFilePath) { 71 $this->traceFilePath = $traceFilePath; 72 } 73 74 public function getTmpDir() { 75 return $this->tmpDir; 76 } 77 78 public function setTmpDir($tmpTraceDir) { 79 $this->tmpDir = $tmpTraceDir; 80 } 81 82 public function getCoverageFileName() { 83 return $this->coverageFileName; 84 } 85 86 public function setCoverageFileName($covFileName) { 87 $this->coverageFileName = $covFileName; 88 } 89 90 /*}}}*/ 91 /*{{{ public function cleanCoverageFile() */ 92 93 /** 94 * Deletes a coverage data file if one exists. 95 * 96 * @return Boolean True on success, False on failure. 97 * @access public 98 */ 99 public function cleanCoverageFile() { 100 $filepath = $this->tmpDir . "/" . $this->coverageFileName; 101 if(file_exists($filepath)) { 102 if(is_writable($filepath)) { 103 unlink($filepath); 104 } 105 else { 106 $this->logger->error("[RemoteCoverageRecorder::cleanCoverageFile()] " 107 . "ERROR: Cannot delete $filepath.", __FILE__, __LINE__); 108 return false; 109 } 110 } 111 return true; 112 } 113 114 /*}}}*/ 115 /*{{{ protected function prepareCoverageXml() */ 116 117 /** 118 * Convert the Coverage data into an XML. 119 * 120 * @return String XML generated from Coverage data 121 * @access protected 122 */ 123 protected function prepareCoverageXml() { 124 global $util; 125 $xmlString = ""; 126 $xmlBody = ""; 127 if(!empty($this->coverageData)) { 128 foreach($this->coverageData as $file => &$lines) { 129 $xmlBody .= "<file path=\"". $util->replaceBackslashes($file) . "\">"; 130 foreach($lines as $linenum => &$frequency) { 131 $xmlBody .= "<line line-number=\"" . $linenum . "\""; 132 $xmlBody .= " frequency=\"" . $frequency . "\"/>"; 133 } 134 $xmlBody .= "</file>\n"; 135 } 136 unset($this->coverageData); 137 } 138 else { 139 $this->logger->info("[RemoteCoverageRecorder::prepareCoverageXml()] Coverage data is empty.", 140 __FILE__, __LINE__); 141 } 142 $xmlString .= $xmlBody; 143 $this->logger->debug("[RemoteCoverageRecorder::prepareCoverageXml()] Xml: " . $xmlString, __FILE__, __LINE__); 144 return $xmlString; 145 } 146 147 /*}}}*/ 148 /*{{{ protected function parseCoverageXml() */ 149 150 /** 151 * Parse coverage XML to regenerate the Coverage data array. 152 * 153 * @param $xml XML String or URL of the coverage data 154 * @param $stream=false Is the input a stream? 155 * @return 156 * @access protected 157 */ 158 protected function parseCoverageXml(&$xml, $stream=false) { 159 $xmlParser = new CoverageXmlParser(); 160 if($stream) { 161 $xmlParser->setInput($xml); 162 } 163 else { 164 $xmlParser->setInputString($xml); 165 } 166 $xmlParser->parse(); 167 $this->coverageData =& $xmlParser->getCoverageData(); 168 } 169 170 /*}}}*/ 171 /*{{{ public function getCoverageXml() */ 172 173 /** 174 * Dumps the coverage data in XML format 175 * 176 * @access public 177 */ 178 public function getCoverageXml() { 179 $filepath = $this->tmpDir . "/" . $this->coverageFileName; 180 if(file_exists($filepath) && is_readable($filepath)) { 181 $fp = fopen($filepath, "r"); 182 if($fp) { 183 while(!feof($fp)) { 184 $xml = fread($fp, 4096); 185 echo $xml; 186 } 187 fclose($fp); 188 return true; 189 } 190 else { 191 $this->logger->error("Could not read coverage data file.", 192 __FILE__, __LINE__); 193 } 194 } 195 else { 196 $this->logger->error("[RemoteCoverageRecorder::getCoverageXml()] " 197 . "ERROR: Cannot read file " . $filepath, __FILE__, __LINE__); 198 } 199 return false; 200 } 201 202 /*}}} */ 203 /*{{{ protected function appendDataToFile() */ 204 205 /** 206 * Append coverage data to xml file 207 * 208 * @param $newXml New xml recorded 209 * @return True on success; false otherwise 210 * @access protected 211 */ 212 protected function appendDataToFile($newXml) { 213 $filepath = $this->tmpDir . "/" . $this->coverageFileName; 214 if(!file_exists($filepath)) { 215 // If new file, write the xml start and end tags 216 $bytes = file_put_contents($filepath, $this->xmlStart . "\n" . $this->xmlEnd); 217 if(!$bytes) { 218 $this->logger->critical("[RemoteCoverageRecorder::appendDataToFile()] Could not create file: " . $filepath, __FILE__, __LINE__); 219 return false; 220 } 221 } 222 if(file_exists($filepath) && is_readable($filepath)) { 223 $res = fopen($filepath, "r+"); 224 if($res) { 225 fseek($res, -1 * strlen($this->xmlEnd), SEEK_END); 226 $ret = fwrite($res, $newXml); 227 if(!$ret) { 228 $this->logger->error("[RemoteCoverageRecorder::appendDataToFile()] Could not append data to file.", 229 __FILE__, __LINE__); 230 fclose($res); 231 return false; 232 } 233 fwrite($res, $this->xmlEnd); 234 fclose($res); 235 } 236 else { 237 $this->logger->error("[RemoteCoverageRecorder::appendDataToFile()] Error opening file for writing: " . $filepath, 238 __FILE__, __LINE__); 239 return false; 240 } 241 } 242 return true; 243 } 244 245 /*}}}*/ 246 /*{{{ public function saveCoverageXml() */ 247 248 /** 249 * Append coverage xml to a xml data file. 250 * 251 * @return Boolean True on success, False on error 252 * @access public 253 */ 254 public function saveCoverageXml() { 255 $filepath = $this->tmpDir . "/" . $this->coverageFileName; 256 if($this->stopInstrumentation()) { 257 $xml = $this->prepareCoverageXml(); 258 $ret = $this->appendDataToFile($xml); 259 if(!$ret) { 260 $this->logger->warn("[RemoteCoverageRecorder::saveCoverageXml()] " 261 . "ERROR: Nothing was written to " . $filepath, 262 __FILE__, __LINE__); 263 return false; 264 } 265 $this->logger->info("[RemoteCoverageRecorder::saveCoverageXml()] " 266 . "Saved XML to $filepath; size: [" . filesize($filepath) 267 . "]", __FILE__, __LINE__); 268 return true; 269 } 270 return false; 271 } 272 273 /*}}}*/ 274 /*{{{ public function generateReport() */ 275 276 /** 277 * Generate report from the xml coverage data 278 * The preferred method for usage of this function is 279 * passing a stream of the XML data in. This is much more 280 * efficient and consumes less memory. 281 * 282 * @param $xmlUrl Url where XML data is available or string 283 * @param $stream=false Is the xml available as stream? 284 * @access public 285 */ 286 public function generateReport($xmlUrl, $stream=false) { 287 $this->logger->debug("XML Url: " . $xmlUrl, __FILE__, __LINE__); 288 $this->parseCoverageXml($xmlUrl, true); 289 $this->logger->debug("Coverage Data final: " . print_r($this->coverageData, true)); 290 parent::generateReport(); 291 } 292 293 /*}}}*/ 294 } 295 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Tue Dec 2 03:54:09 2008 | Cross-referenced by PHPXref 0.7 |