Пример #1
0
 /**
  * This validator method checks if srcid is a valid crash report ID or
  * debug info ID. 
  */
 public function checkSrcId()
 {
     if ($this->type == ProcessingError::TYPE_CRASH_REPORT_ERROR) {
         $crashReport = CrashReport::model()->find('id=' . $this->srcid);
         if ($crashReport === Null) {
             $this->addError('srcid', 'SrcID must be a valid crash report ID.');
             return false;
         }
     } else {
         if ($this->type == ProcessingError::TYPE_DEBUG_INFO_ERROR) {
             $debugInfo = DebugInfo::model()->find('id=' . $this->srcid);
             if ($debugInfo === Null) {
                 $this->addError('srcid', 'SrcID must be a valid debug info ID.');
                 return false;
             }
         }
     }
     return true;
 }
Пример #2
0
 /**
  * Returns the data model based on the primary key given in the GET variable.
  * If the data model is not found, an HTTP exception will be raised.
  * @param integer the ID of the model to be loaded
  */
 public function loadModel($id)
 {
     $model = CrashReport::model()->findByPk($id);
     if ($model === null) {
         throw new CHttpException(404, 'The requested page does not exist.');
     }
     return $model;
 }
Пример #3
0
 public function testGetCrashGroupTitle()
 {
     // Create new crash report
     $model = new CrashReport();
     $model->md5 = '123456789012345678';
     $model->project_id = 100;
     // invalid project id
     $model->status = CrashReport::STATUS_PROCESSED;
     $groupMD5 = '';
     $title = $model->getCrashGroupTitle($groupMD5);
     $this->assertTrue($title == 'Unknown Project');
     $this->assertTrue(strlen($groupMD5) != 0);
     $model->project_id = 1;
     // valid project id
     $groupMD5 = '';
     $title = $model->getCrashGroupTitle($groupMD5);
     $this->assertTrue($title == 'Reports without Exception Info');
     $this->assertTrue(strlen($groupMD5) != 0);
     // Find a pending crash report
     $model = CrashReport::model()->findByPk(1);
     $this->assertTrue($model != null);
     $groupMD5 = '';
     $title = $model->getCrashGroupTitle($groupMD5);
     $this->assertTrue($title == 'Unsorted Reports');
     $this->assertTrue(strlen($groupMD5) != 0);
     // Find an invalid crash report
     $model = CrashReport::model()->findByPk(5);
     $this->assertTrue($model != null);
     $groupMD5 = '';
     $title = $model->getCrashGroupTitle($groupMD5);
     $this->assertTrue($title == 'Invalid Reports');
     $this->assertTrue(strlen($groupMD5) != 0);
     // Find a processed crash report
     $model = CrashReport::model()->findByPk(4);
     $this->assertTrue($model != null);
     $groupMD5 = '';
     $title = $model->getCrashGroupTitle($groupMD5);
     $this->assertTrue($title == 'CrashRptd.dll! wmain() +0x2bd9 [crtex.c: 120]');
     $this->assertTrue(strlen($groupMD5) != 0);
     // Find another processed crash report
     $model = CrashReport::model()->findByPk(6);
     $this->assertTrue($model != null);
     $groupMD5 = '';
     $title = $model->getCrashGroupTitle($groupMD5);
     $this->assertTrue($title == 'CrashRpt.dll!+0xf');
     $this->assertTrue(strlen($groupMD5) != 0);
 }
Пример #4
0
 /**
  * Generates a crash report geographic location distribution graph for currently 
  * selected project and dumps it to stdout.
  * @param type $w Desired image width.
  * @param type $h Desired image height.
  * @throws CHttpException
  * @return void
  */
 public static function generateGeoLocationDistributionGraph($w, $h, $file = null)
 {
     if (!is_numeric($w) || $w <= 0 || $w > 1024) {
         throw new CHttpException(403, 'Invalid parameter');
     }
     if (!is_numeric($h) || $h <= 0 || $h > 960) {
         throw new CHttpException(403, 'Invalid parameter');
     }
     // Get current project info
     $curProjectId = Yii::app()->user->getCurProjectId();
     if ($curProjectId == false) {
         throw new CHttpException(403, 'Invalid parameter');
     }
     // Prepare data
     $criteria = new CDbCriteria();
     $criteria->select = 'geo_location, COUNT(*) as cnt';
     $criteria->group = 'geo_location';
     $criteria->compare('t.project_id', $curProjectId);
     $criteria->order = 'cnt DESC';
     $curVer = '(not set)';
     $versions = Yii::app()->user->getCurProjectVersions($curVer);
     if ($curVer != -1) {
         $criteria->compare('appversion_id', $curVer == 0 ? null : $curVer);
     }
     $data = array();
     $models = CrashReport::model()->findAll($criteria);
     $totalCount = 0;
     foreach ($models as $model) {
         $totalCount += $model->cnt;
         if ($model->geo_location === null) {
             if (isset($data[''])) {
                 $data[''] += $model->cnt;
             } else {
                 $data[''] = $model->cnt;
             }
         } else {
             $data[$model->geo_location] = $model->cnt;
         }
     }
     if ($file == null) {
         $fout = fopen('php://output', 'w');
     } else {
         $fout = fopen($file, 'wt');
     }
     fprintf($fout, '<div class="digest-pane-image" style="width:' . $w . 'px;min-height:' . $h . 'px;max-height:' . $h . 'px;overflow:hidden"><table id="geo-locations">');
     // Check the case when $data is empty.
     if (count($data) == 0) {
         fprintf($fout, '<tr><td><i>No data available</i></td></tr>');
     } else {
         foreach ($data as $name => $val) {
             $percent = 100 * $val / $totalCount;
             $percentStr = sprintf('%0.1f', $percent);
             $nameStr = '(not set)';
             if ($name != '') {
                 $nameStr = MiscHelpers::addEllipsis(CrashReport::geoIdToCountryName($name), 30);
             }
             fprintf($fout, '<tr><td>' . $nameStr . '</td><td>' . $percentStr . '%%</td></tr>');
         }
     }
     fprintf($fout, '</table></div>');
     if ($file != null) {
         fclose($fout);
     }
 }
Пример #5
0
 /**
  * Returns count of crash reports in this project. 
  * @param integer $totalFileSize On output, receives the total size in bytes of files.
  * @param integer $percentOfDiskQuota On output, receives percent of disk quota.
  * @param integer $appver Optional. If specified, count of files is calculated for the given version.
  * @return integer count of crash report files.
  */
 public function getCrashReportCount(&$totalFileSize, &$percentOfDiskQuota, $appver = Project::PROJ_VER_ALL)
 {
     // Find all crash reports belonging to this project and having
     // $appver application version.
     $criteria = new CDbCriteria();
     $criteria->compare('project_id', $this->id, false, 'AND');
     if ($appver != Project::PROJ_VER_ALL) {
         $criteria->compare('appversion_id', $appver, false, 'AND');
     }
     $crashReports = CrashReport::model()->findAll($criteria);
     // Calculate count of crash reports
     $count = CrashReport::model()->count($criteria);
     // Calculate total file size
     $totalFileSize = 0;
     foreach ($crashReports as $crashReport) {
         $totalFileSize += $crashReport->filesize;
     }
     // Calc percent of disk quota
     if ($this->crash_report_files_disc_quota <= 0) {
         // unlimited
         $percentOfDiskQuota = -1;
     } else {
         $percentOfDiskQuota = 100 * $totalFileSize / ($this->crash_report_files_disc_quota * 1024 * 1024);
     }
     // Return file count
     return $count;
 }
Пример #6
0
 /**
  * This method is executed before AR is saved to database.
  * In this method, we set some model attributes.
  * @return boolean True on success.
  */
 protected function beforeSave()
 {
     if (!parent::beforeSave()) {
         return false;
     }
     // Check if this is a new record.
     if ($this->isNewRecord) {
         // Set project id
         $this->project_id = Yii::app()->user->getCurProjectId();
         // Set project version
         $curVer = false;
         $versions = Yii::app()->user->getCurProjectVersions($curVer);
         if ($curVer != Project::PROJ_VER_ALL) {
             $this->appversion_id = $curVer;
         } else {
             // Project version '<all>' currently selected.
             // We have to determine bug version from associated
             // crash reports/collections.
             $numbers = MiscHelpers::splitNumberList($this->crashgroups);
             foreach ($numbers as $number) {
                 $crashGroup = CrashGroup::model()->findByPk($number);
                 if ($crashGroup === Null) {
                     throw new HttpException('Invalid crash group ID');
                 }
                 $curVer = $crashGroup->appversion_id;
                 break;
             }
             if ($curVer == -1) {
                 $numbers = MiscHelpers::splitNumberList($this->crashreports);
                 foreach ($numbers as $number) {
                     $crashReport = CrashReport::model()->findByPk($number);
                     if ($crashReport === Null) {
                         throw new HttpException('Invalid crash report ID');
                     }
                     $curVer = $crashReport->appversion_id;
                     break;
                 }
             }
             if ($curVer == -1) {
                 throw new CHttpException(403, 'Invalid request');
             }
             $this->appversion_id = $curVer;
         }
         // Set date created
         $this->date_created = time();
         // Set date last modified
         $this->date_last_modified = $this->date_created;
         // Set reported by
         $this->reported_by = Yii::app()->user->id;
         if ($this->assigned_to < 0) {
             unset($this->assigned_to);
         }
     } else {
         // Set date last modified
         $this->date_last_modified = time();
         if ($this->status > Bug::STATUS_OPEN_MAX) {
             $this->date_closed = $this->date_last_modified;
         } else {
             unset($this->date_closed);
         }
     }
     // Success.
     return true;
 }
Пример #7
0
 /**
  * Determines if a bug can be opened for this group. A bug can not be opened
  * if the crash group is empty or does not contain processed crash reports.
  * @return boolean true if a bug can be opened.
  */
 public function canOpenNewBug()
 {
     // Calculate count of processed reports in this group
     $criteria = new CDbCriteria();
     $criteria->compare('groupid', $this->id);
     $criteria->compare('status', CrashReport::STATUS_PROCESSED);
     $count = CrashReport::model()->count($criteria);
     if ($count == 0) {
         return false;
     }
     // No such reports
     // OK
     return true;
 }
Пример #8
0
 /**
  * This method finalizes the given operation, updates appropriate db tables
  * and removes temporary files.	 
  */
 public function finalizeOperation($op, $opStatus)
 {
     // Update operation db record.
     $op->status = $opStatus;
     $op->save();
     if ($op->optype == Operation::OPTYPE_PROCESS_CRASH_REPORT) {
         // Delete temporary files and directories
         $crashReportFileName = $op->operand1;
         $xmlFileName = $op->operand2;
         if ($opStatus != Operation::STATUS_SUCCEEDED) {
             // Set crash report record status to Invalid
             Yii::log('Setting crash report #' . $op->srcid . ' status to invalid ', 'error');
             $crashReport = CrashReport::model()->find('id=' . $op->srcid);
             if ($crashReport != null) {
                 $crashReport->status = DebugInfo::STATUS_INVALID;
                 $crashReport->save();
             }
         }
         // Delete temp XML file
         Yii::log('Deleting file ' . $xmlFileName, 'info');
         if (!@unlink($xmlFileName)) {
             // Couldn't delete file
             Yii::log('Error deleting file ' . $xmlFileName, 'error');
         }
     } else {
         if ($op->optype == Operation::OPTYPE_IMPORTPDB) {
             // Delete temporary files and directories
             $pdbFileName = $op->operand1;
             $xmlFileName = $op->operand2;
             if ($opStatus != Operation::STATUS_SUCCEEDED) {
                 // Set debug info record status to Invalid
                 Yii::log('Setting debug info #' . $op->srcid . ' status to invalid ', 'error');
                 $debugInfo = DebugInfo::model()->find('id=' . $op->srcid);
                 if ($debugInfo != null) {
                     $debugInfo->status = DebugInfo::STATUS_INVALID;
                     $debugInfo->save();
                 }
             }
             // Delete file
             Yii::log('Deleting file ' . $xmlFileName, 'info');
             if (!@unlink($xmlFileName)) {
                 // Couldn't delete file
                 Yii::log('Error deleting file ' . $xmlFileName, 'error');
             }
             // If operation has succeeded, we can remove original PDB file and
             // its parent directories, because the file was copied by daemon
             // to its persistent location.
             if ($op->status == Operation::STATUS_SUCCEEDED) {
                 // Delete file
                 Yii::log('Deleting file ' . $pdbFileName, 'info');
                 if (!@unlink($pdbFileName)) {
                     // Couldn't delete file
                     Yii::log('Error deleting file ' . $pdbFileName, 'error');
                 }
                 // Delete parent directory.
                 $parentDirName = dirname($pdbFileName);
                 Yii::log('Deleting directory ' . $parentDirName, 'info');
                 if (!@rmdir($parentDirName)) {
                     // Couldn't delete directory.
                     Yii::log('Error deleting directory ' . $parentDirName, 'error');
                 }
                 // Delete first-level parent directory.
                 $parentDirName = dirname($parentDirName);
                 Yii::log('Deleting directory ' . $parentDirName, 'info');
                 if (!@rmdir($parentDirName)) {
                     // Couldn't delete dir
                     Yii::log('Error deleting directory ' . $parentDirName, 'error');
                 }
             }
         }
     }
 }