Full Code of jenkinsci/performance-plugin for AI

master 09ca52b3370e cached
209 files
1.1 MB
311.5k tokens
1223 symbols
1 requests
Download .txt
Showing preview only (1,215K chars total). Download the full file or copy to clipboard to get everything.
Repository: jenkinsci/performance-plugin
Branch: master
Commit: 09ca52b3370e
Files: 209
Total size: 1.1 MB

Directory structure:
gitextract_iumnbdkn/

├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── cd.yaml
│       └── jenkins-security-scan.yml
├── .gitignore
├── .mvn/
│   ├── extensions.xml
│   └── maven.config
├── Jenkinsfile
├── LICENSE
├── README.md
├── docs/
│   ├── .gitkeep
│   ├── Changelog.md
│   ├── README.md
│   ├── Reporting.md
│   ├── RunTests.md
│   ├── _config.yml
│   └── stats.html
├── pom.xml
├── requirements.txt
└── src/
    ├── main/
    │   ├── java/
    │   │   └── hudson/
    │   │       └── plugins/
    │   │           └── performance/
    │   │               ├── PerformancePublisher.java
    │   │               ├── PerformanceReportMap.java
    │   │               ├── TrendReportGraphs.java
    │   │               ├── actions/
    │   │               │   ├── ExternalBuildReportAction.java
    │   │               │   ├── PerformanceBuildAction.java
    │   │               │   └── PerformanceProjectAction.java
    │   │               ├── build/
    │   │               │   └── PerformanceTestBuild.java
    │   │               ├── constraints/
    │   │               │   ├── AbsoluteConstraint.java
    │   │               │   ├── AbstractConstraint.java
    │   │               │   ├── ConstraintChecker.java
    │   │               │   ├── ConstraintEvaluation.java
    │   │               │   ├── ConstraintFactory.java
    │   │               │   ├── RelativeConstraint.java
    │   │               │   └── blocks/
    │   │               │       ├── PreviousResultsBlock.java
    │   │               │       └── TestCaseBlock.java
    │   │               ├── cookie/
    │   │               │   └── CookieHandler.java
    │   │               ├── data/
    │   │               │   ├── ConstraintSettings.java
    │   │               │   ├── HttpSample.java
    │   │               │   ├── PerformanceReportPosition.java
    │   │               │   ├── ReportValueSelector.java
    │   │               │   └── TaurusFinalStats.java
    │   │               ├── descriptors/
    │   │               │   ├── ConstraintDescriptor.java
    │   │               │   └── PerformanceReportParserDescriptor.java
    │   │               ├── details/
    │   │               │   ├── GraphConfigurationDetail.java
    │   │               │   ├── TestSuiteReportDetail.java
    │   │               │   └── TrendReportDetail.java
    │   │               ├── parsers/
    │   │               │   ├── AbstractParser.java
    │   │               │   ├── IagoParser.java
    │   │               │   ├── JMeterCsvParser.java
    │   │               │   ├── JMeterParser.java
    │   │               │   ├── JUnitParser.java
    │   │               │   ├── JmeterSummarizerParser.java
    │   │               │   ├── LoadRunnerParser.java
    │   │               │   ├── LocustParser.java
    │   │               │   ├── ParserDetector.java
    │   │               │   ├── ParserFactory.java
    │   │               │   ├── PerformanceReportParser.java
    │   │               │   ├── TaurusParser.java
    │   │               │   └── WrkSummarizerParser.java
    │   │               ├── reports/
    │   │               │   ├── AbstractReport.java
    │   │               │   ├── ConstraintReport.java
    │   │               │   ├── PerformanceReport.java
    │   │               │   ├── ThroughputReport.java
    │   │               │   └── UriReport.java
    │   │               ├── tools/
    │   │               │   └── SafeMaths.java
    │   │               └── workflow/
    │   │                   └── WorkflowActionsFactory.java
    │   ├── resources/
    │   │   ├── hudson/
    │   │   │   └── plugins/
    │   │   │       └── performance/
    │   │   │           ├── Messages.properties
    │   │   │           ├── Messages_es.properties
    │   │   │           ├── PerformancePublisher/
    │   │   │           │   ├── config.jelly
    │   │   │           │   ├── config.properties
    │   │   │           │   ├── config_es.properties
    │   │   │           │   ├── config_zh_TW.properties
    │   │   │           │   ├── help-errorUnstableResponseTimeThreshold.html
    │   │   │           │   ├── help-filterRegex.html
    │   │   │           │   ├── help-modeEvaluation.html
    │   │   │           │   ├── help-persistPerformanceChart.html
    │   │   │           │   ├── help-persistPerformanceCharts.html
    │   │   │           │   └── help-sourceDataFiles.html
    │   │   │           ├── PerformanceReportMap/
    │   │   │           │   ├── CVS/
    │   │   │           │   │   ├── Entries
    │   │   │           │   │   ├── Repository
    │   │   │           │   │   └── Root
    │   │   │           │   ├── index.jelly
    │   │   │           │   ├── index_es.properties
    │   │   │           │   └── index_fr.properties
    │   │   │           ├── TrendReportGraphs/
    │   │   │           │   ├── index.jelly
    │   │   │           │   └── index_es.properties
    │   │   │           ├── actions/
    │   │   │           │   └── PerformanceProjectAction/
    │   │   │           │       ├── floatingBox.jelly
    │   │   │           │       ├── floatingBox_es.properties
    │   │   │           │       ├── index.jelly
    │   │   │           │       ├── index_es.properties
    │   │   │           │       └── index_fr.properties
    │   │   │           ├── build/
    │   │   │           │   ├── PerformanceTestBuild/
    │   │   │           │   │   ├── config.jelly
    │   │   │           │   │   ├── config.properties
    │   │   │           │   │   └── help.html
    │   │   │           │   └── jenkins-report.yml
    │   │   │           ├── constraints/
    │   │   │           │   ├── AbsoluteConstraint/
    │   │   │           │   │   ├── config.jelly
    │   │   │           │   │   └── config.properties
    │   │   │           │   ├── AbstractConstraint/
    │   │   │           │   │   ├── help-relatedPerfReport.html
    │   │   │           │   │   └── help-testCase.html
    │   │   │           │   └── RelativeConstraint/
    │   │   │           │       ├── config.jelly
    │   │   │           │       ├── config.properties
    │   │   │           │       ├── help-previousResultsString.html
    │   │   │           │       ├── help-timeframeEndString.html
    │   │   │           │       └── help-timeframeStartString.html
    │   │   │           ├── details/
    │   │   │           │   ├── GraphConfigurationDetail/
    │   │   │           │   │   ├── CVS/
    │   │   │           │   │   │   ├── Entries
    │   │   │           │   │   │   ├── Repository
    │   │   │           │   │   │   └── Root
    │   │   │           │   │   ├── index.jelly
    │   │   │           │   │   ├── index.properties
    │   │   │           │   │   └── index_es.properties
    │   │   │           │   ├── TestSuiteReportDetail/
    │   │   │           │   │   └── index.jelly
    │   │   │           │   └── TrendReportDetail/
    │   │   │           │       ├── index.jelly
    │   │   │           │       └── index_es.properties
    │   │   │           ├── reports/
    │   │   │           │   └── UriReport/
    │   │   │           │       ├── index.jelly
    │   │   │           │       ├── index_es.properties
    │   │   │           │       └── index_fr.properties
    │   │   │           └── tags/
    │   │   │               ├── captionLine.jelly
    │   │   │               ├── captionLine_es.properties
    │   │   │               ├── captionLine_fr.properties
    │   │   │               ├── summaryTable.jelly
    │   │   │               ├── summaryTableSummarizer.jelly
    │   │   │               └── taglib
    │   │   ├── index.jelly
    │   │   └── lib/
    │   │       └── performance/
    │   │           ├── blockWrapper.jelly
    │   │           └── taglib
    │   ├── tools/
    │   │   ├── checkstyle.xml
    │   │   └── format.xml
    │   └── webapp/
    │       ├── css/
    │       │   └── style.css
    │       ├── help.html
    │       └── help_es.html
    └── test/
        ├── java/
        │   └── hudson/
        │       └── plugins/
        │           └── performance/
        │               ├── AbstractGraphGenerationTest.java
        │               ├── BaselineComparisonTest.java
        │               ├── PerformancePipelineTest.java
        │               ├── PerformancePublisherTest.java
        │               ├── PerformanceReportMapTest.java
        │               ├── TrendReportGraphsTest.java
        │               ├── actions/
        │               │   ├── ExternalBuildReportActionTest.java
        │               │   ├── PerformanceProjectActionGraphTest.java
        │               │   └── PerformanceProjectActionTest.java
        │               ├── build/
        │               │   └── PerformanceTestBuildTest.java
        │               ├── constraints/
        │               │   ├── ConstraintCheckerTest.java
        │               │   ├── ConstraintFactoryTest.java
        │               │   └── ConstraintTest.java
        │               ├── cookie/
        │               │   └── CookieHandlerTest.java
        │               ├── data/
        │               │   ├── PerformanceReportPositionTest.java
        │               │   └── ReportValueSelectorTest.java
        │               ├── descriptors/
        │               │   ├── ConstraintDescriptorTest.java
        │               │   └── PerformanceReportParserDescriptorTest.java
        │               ├── details/
        │               │   ├── GraphConfigurationDetailTest.java
        │               │   └── TestSuiteReportDetailTest.java
        │               ├── parsers/
        │               │   ├── AbstractParserTest.java
        │               │   ├── IagoParserTest.java
        │               │   ├── JMeterCsvParserTest.java
        │               │   ├── JMeterParserTest.java
        │               │   ├── JMeterTestHelper.java
        │               │   ├── JUnitParserTest.java
        │               │   ├── JmeterSummarizerParserTest.java
        │               │   ├── LoadRunnerParserTest.java
        │               │   ├── LocustParserTest.java
        │               │   ├── ParserDetectorTest.java
        │               │   ├── ParserFactoryTest.java
        │               │   ├── TaurusParserTest.java
        │               │   └── WrkSummarizerParserTest.java
        │               ├── reports/
        │               │   ├── ConstraintReportTest.java
        │               │   ├── PerformanceReportTest.java
        │               │   ├── ThroughputReportTest.java
        │               │   └── UriReportTest.java
        │               ├── tools/
        │               │   └── SafeMathsTest.java
        │               └── workflow/
        │                   └── WorkflowActionsFactoryTest.java
        └── resources/
            ├── IagoResults.log
            ├── JENKINS-16627_CSV_instead_of_XML.jtl
            ├── JMeterCsvResults.csv
            ├── JMeterCsvResults2.csv
            ├── JMeterCsvResults3.csv
            ├── JMeterPublisher.csv
            ├── JMeterPublisher_formatted_timeStamp.csv
            ├── JMeterResults.jtl
            ├── JMeterResultsMultiLevel.jtl
            ├── JMeterResultsMultiThread.jtl
            ├── JMeterResultsOneSample.jtl
            ├── JMeterResultsRandomUri.jtl
            ├── JMeterResultsTenSamples.jtl
            ├── JMeterResultsThreeSamples.jtl
            ├── TEST-JUnitResults-noTimeAttribute.xml
            ├── TEST-JUnitResults-relative-thrashould-2.xml
            ├── TEST-JUnitResults-relative-thrashould.xml
            ├── TEST-JUnitResults-success-failure-error.xml
            ├── TEST-JUnitResults.xml
            ├── TEST-results.xml
            ├── TaurusPreviousBuildReport.xml
            ├── TaurusXMLReport.xml
            ├── TaurusXmlWithDuration.xml
            ├── WrkResultsLong.wrk
            ├── WrkResultsQuick.wrk
            ├── WrkResultsWithErrors.wrk
            ├── WrkResultsWithLatencyFlag.wrk
            ├── aggregate-results.xml
            ├── constraint-test.xml
            ├── emptyfile.jtl
            ├── filewithtransactions.csv
            ├── jUnitIssue5571.xml
            ├── jmeter.log
            ├── lr-session.mdb
            ├── multiLineCSV.jtl
            ├── performanceTest.yml
            ├── performanceTestWithFailCriteria.yml
            ├── single_result/
            │   ├── nested/
            │   │   └── res.jtl
            │   └── res.csv
            ├── summary.log
            ├── test_results_stats.csv
            └── whitespace-followed-by-xml.jtl

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/dependabot.yml
================================================
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates

version: 2
updates:
- package-ecosystem: maven
  directory: /
  schedule:
    interval: monthly
- package-ecosystem: github-actions
  directory: /
  schedule:
    interval: monthly


================================================
FILE: .github/workflows/cd.yaml
================================================
# Note: additional setup is required, see https://www.jenkins.io/redirect/continuous-delivery-of-plugins

name: cd
on:
  workflow_dispatch:
  check_run:
    types:
      - completed

jobs:
  maven-cd:
    uses: jenkins-infra/github-reusable-workflows/.github/workflows/maven-cd.yml@v1
    secrets:
      MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
      MAVEN_TOKEN: ${{ secrets.MAVEN_TOKEN }}


================================================
FILE: .github/workflows/jenkins-security-scan.yml
================================================
name: Jenkins Security Scan

on:
  push:
    branches:
      - master
  pull_request:
    types: [ opened, synchronize, reopened ]
  workflow_dispatch:

permissions:
  security-events: write
  contents: read
  actions: read

jobs:
  security-scan:
    uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2
    with:
      java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate.
      # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default.


================================================
FILE: .gitignore
================================================
target
*.iml
*.ipr
*.iws
.idea/
.classpath
.project
.settings/
.vscode/
src/test/resources/*.serialized
/work/


================================================
FILE: .mvn/extensions.xml
================================================
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
  <extension>
    <groupId>io.jenkins.tools.incrementals</groupId>
    <artifactId>git-changelist-maven-extension</artifactId>
    <version>1.13</version>
  </extension>
</extensions>


================================================
FILE: .mvn/maven.config
================================================
-Pconsume-incrementals
-Pmight-produce-incrementals
-Dchangelist.format=%d.v%s

================================================
FILE: Jenkinsfile
================================================
properties([
    buildDiscarder(logRotator(numToKeepStr: '5')),
    disableConcurrentBuilds(abortPrevious: true)
])

node('linux-amd64') {
    stage('Checkout') {
        infra.checkoutSCM()
    }

    stage('Build') {
        withEnv(['PATH+LOCAL=/home/jenkins/.local/bin']) {
            sh 'pip install --upgrade pip'
            sh 'pip install -r requirements.txt'
            
            def args = ['clean', 'install', '-Dset.changelist']
            infra.runMaven(args, 25)
        }
    }

    stage('Archive') {
        junit '**/target/surefire-reports/TEST-*.xml'
        infra.prepareToPublishIncrementals()
    }
}

infra.maybePublishIncrementals()


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2019 Jenkins

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

================================================
FILE: README.md
================================================
# Performance Plugin for Jenkins CI


Links:
 - [Documentation](http://jenkinsci.github.io/performance-plugin/)
   - [Running Tests](http://jenkinsci.github.io/performance-plugin/RunTests.html)
   - [Performance Trend Reports](http://jenkinsci.github.io/performance-plugin/Reporting.html)
 - [Jenkins Plugins Entry](https://wiki.jenkins-ci.org/display/JENKINS/Performance+Plugin)
 - [Changelog](http://jenkinsci.github.io/performance-plugin/Changelog.html)
 
Example Report:
 ![](docs/report_seclevel.png)


================================================
FILE: docs/.gitkeep
================================================


================================================
FILE: docs/Changelog.md
================================================
<small>[<< Back to main page](./)</small>
# Changelog

## v3.20 (13th of July, 2021)
- FIX: compatibility with Jenkins 2.264+ (tables to div) [JENKINS-64990](https://issues.jenkins-ci.org/browse/JENKINS-64990)

## v3.19 (8th of March, 2021)
- ADD: Option to enable/disable trend graphs within Performance Report [JENKINS-64638](https://issues.jenkins-ci.org/browse/JENKINS-64638)
- ADD: Possibility yo explicitly set the PATH to `virtualenv`
- FIX: travis ci

## v3.18 (20th of July, 2020)
- ADD: Locust report files parser
- ADD: Response times scatter plot
- ADD: Percentile and throughput chart to URI report page
- ADD: Error chart to URI report page

## v3.17 (17th of June, 2019)
- FIX: Fix ineffective report cache [JENKINS-57997](https://issues.jenkins-ci.org/browse/JENKINS-57997)
- FIX: Remove redundant report loading

## v3.16 (28th of March, 2019)
- ADD: Add ability to select which transactions/samplers are included in report through regular expression. Developed by [Philippe M.](https://github.com/pmouawad) and sponsored by [Ubik Load Pack](https://ubikloadpack.com)
- FIX: Switch from table to entry [JENKINS-55787](https://issues.jenkins-ci.org/browse/JENKINS-55787)
- FIX: java 9 compatibility

## v3.15 (29th of January, 2019)
- ADD: network traffic when parsing JMeter CSV. Developed by [Philippe M.](https://github.com/pmouawad) and sponsored by [Ubik Load Pack](https://ubikloadpack.com) 

## v3.14 (14th of December, 2018)
- FIX: StackOverflowError for jobs with 2k+ builds

## v3.13 (1st of November, 2018)
- FIX: set default values for percentiles
- ADD: baseline build for Performance Trend

## v3.12 (11th of September, 2018)
- FIX: pass envVars from pipeline script to Taurus
- FIX: search report files using Ant pattern
- ADD: JUnit timestamp parsing
- ADD: a safe division where division by 0 can occur

## v3.11 (25th of July, 2018)
- ADD: write results xml file to disk for standard mode output
- FIX: Support [JEP-200](https://jenkins.io/blog/2018/01/13/jep-200/)

## v3.10 (1st of June, 2018)
- FIX: relative thresholds

## v3.9 (1st of June, 2018)
- FIX: parse Taurus tool parameters;
- FIX: hide Trend/URI graphs if report contains only summary info
- FIX: division by zero error

## v3.8 (13th of April, 2018)
- ADD: charts to `Performance report` page
- FIX: relative constraint failure on first build. Contributed by [Till Neunast](https://github.com/tilln)

## v3.7 (skipped)

## v3.6 (14th of March, 2018)
- Support [JEP-200](https://jenkins.io/blog/2018/01/13/jep-200/)
 
## v3.5 (29th of January, 2018)
- FIX: Display Performance Report Per Test Case
- FIX: NullPointerException in ConstraintFactory
- FIX: NumberFormatException in RelativeConstraint
- FIX: RelativeConstraint.tolerance and AbsoluteConstraint.value fields in UI
- ADD: move some options to Advanced
- ADD: choosing display percentiles

## v3.4 (12th of December, 2017)
- FEATURE: add LoadRunner parser. Contributed by [Till Neunast](https://github.com/tilln)
- FEATURE: add option to write a JUnit report file to the job's workspace
- FEATURE: add summary table of failed constraints for Publisher log in expert mode
- FEATURE: add Descriptor Symbols for nicer Constraints BuildStep syntax
- FEATURE: add 90th percentile difference in publisher summary table
- FIX: OutOfMemoryException when parsing huge XML report ([JENKINS-47808](https://issues.jenkins-ci.org/browse/JENKINS-47808)). Contributed by [Julien Coste](https://github.com/jcoste-orange)
- FIX: size column width logging of relative comparision results
- FIX: publisher JUnit output to Slave workspace

## v3.3 (21th of August, 2017)
- FEATURE: install 'bzt' from URL or path
- FEATURE: add option to exclude response time of errored samples ([JENKINS-45288](https://issues.jenkins-ci.org/browse/JENKINS-45288))
- FIX: summarizer parser for JMeter 3.2 
- FIX: does not present graphs while job running 
- FIX: wrong time values for uri reports 
- FIX: unused `failBuildIfNoResultFile` flag 
- FIX: always enabled `modePerformancePerTestCase` 
- FIX: remove unused `modeRelativeThresholds` flag ([JENKINS-39050](https://issues.jenkins-ci.org/browse/JENKINS-39050))
- FIX: wrong calculation of Average Throughput ([JENKINS-44410](https://issues.jenkins-ci.org/browse/JENKINS-44410))
- FIX: recognize JUnit file format which wrote as single line ([JENKINS-45723](https://issues.jenkins-ci.org/browse/JENKINS-45723))
- FIX: dependency that require code v2.62+
- FIX: show only chart legend ([JENKINS-45539](https://issues.jenkins-ci.org/browse/JENKINS-45539))
- FIX: virtualenv error in job which contains spaces in name
- FIX: publisher for more than one sourceDataFiles ([JENKINS-46046](https://issues.jenkins-ci.org/browse/JENKINS-46046)). Contributed by [Till Neunast](https://github.com/tilln)
- FIX: logging for expert criteria works with pipeline without throwing exceptions. Contributed by [Till Neunast](https://github.com/tilln)

## v3.2 (14th of July, 2017)
- FIX: Absolute path in Publisher ([JENKINS-45119](https://issues.jenkins-ci.org/browse/JENKINS-45119))
- FIX: Comparison to baseline
- FEATURE: Add `Always use virtualenv` option
- FIX: Changing build status with default comparison option
- FIX: Split params for build step
- FIX: Saving RelativeUnstableThresholdNegative. Contributed by [Märt Bakhoff](https://github.com/mbakhoff)
- FIX: add PerformanceProjectAction only to runs, which contain PerformanceBuildAction 

## v3.1 (2nd of June, 2017)
- FEATURE: Snippet Generator generates nice and simple pipeline scripts for Performance Test & Performance Publisher. Contributed by [Andrew Bayer](https://github.com/abayer)
- FEATURE: Add option to choose graphed metric. Contributed by [Märt Bakhoff](https://github.com/mbakhoff)
- FEATURE: Add option to choose bzt version
- FIX: Showing overall report link in pipeline mode

## v3.0

- FEATURE: add build step to run performance test
- FIX: compact table stats to fit into screen
- FIX: fix FileNotFound error
- FIX: use proper CSV reader to read multiline and quoted CSV values
- FIX: Pipeline Snippet Generator shows broken config

## v2.2
- FEATURE: make plugin to autodetect input file formats
- FEATURE: add "perfReport" Groovy command
- FIX: revive broken "constraints" gui, improve GUI display

## v2.1
- FEATURE: add support for Taurus Final Stats XML
- FIX: improve CPU and memory usage
- FIX: datetime format parsing and couple of NPEs

## v2.0
- FEATURE: Make it pipeline compatible 
- FIX: Testcase trend charts display the values for last sample

## v1.15
- FEATURE: Implemented absolute and relative constraints
- FIX: Sort correctly on date values
- FIX: Fix for uri column value not shown as link
- FIX: Use 0 for time when no value is provided in Junit test result
- FIX: Fix for Junit parser not handling errors
- FIX: Fix for wrong index when calculating 90Line
- FIX: Fix number format exception
- FIX: Fix for Jmeter summariser parser not showing correct data
- FIX: Fix for parsing jtl with CSV data

## v1.14
- FEATURE: Add checkbox in job config in order to choose build status when result performance file are not present
- IMPROVEMENT: Make csv fields case insensitive
- IMPROVEMENT: Cleaned up English localization
- IMPROVEMENT: Compatible with flexible publisher
- FIX: Rounding error on aggregated throughput
- FIX: Fix conversion failure with locale using comma as decimal separator

## v1.13
- FEATURE: Added variable checking and fail to filesystem check on files
- FIX: Allow parameter substitution in report files
- FIX: Add class name to URIs
- FIX: Many improvements in performance parsing files and caching results
- FIX: Compare only against last success builds

## v1.10
- FIX: Cache preprocessed JMeter Reports to avoid performance issues.
- FEATURE: Added comparison between builds
- FIX: UI bug always showing same values regardless of what was saved.
- FEATURE: Average response time thresholds per jtl file.
- FIX: Corrected a bug where the 'All URIs' was just displaying the last entry again.
- FEATURE: Added some useful metrics to the summary details table. JMeter sends size of the response which can be useful to calculate bandwidth usage for perf tests.

## v1.9
- FIX: don't use ; as separator in cookie value
- FEATURE: added csv parser
- FEATURE: added response time trend graph for selected build
- FEATURE: builds trends for responce time
- FEATURE: consider the time for each test case in a test suite
- FEATURE: simple cache added
- FEATURE: new response time graphs selected build and uri report
- FEATURE: new graphs for response time trends
- FEATURE: parse JMeter summarizer files

## v1.8
- FIX: parsing results of long running tests
- FIX: differences not shown for old builds
- FEATURE: more information columns in the report map
- CHANGES: use negative values to indicate no threshold (this allows to use 0% thresholds)
- FEATURE: graphs available on the reports
- FEATURE: url parameter (buildCount) to control the number of builds to display
- FEATURE: get a larger image when clicking on a graph

## v1.7
- FIX: Unstable test set final build incorrectly when a previous test failed.
- FIX: JENKINS-9655, didn't parse JUnit reports correctly (patch: Attila-Mihaly)

## v1.6
- Fix JMeter parser when nested xml tags are in the report.

## v1.5
- Now computes median and 90% Line in jmeter test results.

## v1.4
- Just a control version published after migrating the plugin to gitHub infrastructure.

## v1.3
- Formalized an extension point to define custom parsers so as it should be easier add new parsers.
- JMeter and JUnit parsers have been split in different classes.
- Added a new Trend report.
- Fixed an NPE when a build was failed (JENKINS-5224, JENKINS-6908)

## v1.2
- Support for Ant-FileSet pattern to search  report files.
- Improved css.
- Localized UI elements
- Added Spanish translation

## v1.0
- First release, moved code from JMeter plugin  v.0.3.0 to Performance v.1.0.
- Added ability to parse junit xml report files.


================================================
FILE: docs/README.md
================================================
# Performance Plugin for Jenkins 

## About

Performance Plugin allows you to [run performance tests](RunTests.md) as build step of your Jenkins job, or [build reports](Reporting.md) from pre-existing test result files. 

Here's how example trend report looks like:
![](report_seclevel.png)

## Running Tests

Running tests is done with Taurus Tool and explained in detail on dedicated **[Test Running](RunTests.md)** doc page.


## Building Reports

Report building supports many formats from popular testing tools and explained in detail on dedicated **[Reporting](Reporting.md)** doc page.


## Links

- [Test Running](RunTests.md)
- [Reporting](Reporting.md)
- [Changelog](Changelog.md)
- [Usage Stats](stats.html)
- [Jenkins Plugins Entry](https://wiki.jenkins-ci.org/display/JENKINS/Performance+Plugin)


## Troubleshooting



If you get the error `java.lang.NoClassDefFoundError: Could not initialize class org.jfree.chart.JFreeChart` when the plugin generates the charts, is because you have running an XServer in the jenkins machine. Set the property `-Djava.awt.headless=true` when starting your servlet container. Note that this normally does not happen when running the embedded servlet container Jenkins is packaged with (Jetty).

https://groups.google.com/forum/#!topic/jenkinsci-users/o_Dr7Tn0i3U

## Compiling
To use the latest plugin release, you need to download, compile and install by hand. To do it, you need git, maven and java installed in your computer.
```bash
$ git clone https://github.com/jenkinsci/performance-plugin.git performance
$ cd performance
$ mvn package
$ cp target/performance.hpi <path_to_jenkins>/data/plugins
```
Remember to restart jenkins in order to use reload the plugin.
You could read more about plugins reading these pages :
- http://wiki.jenkins-ci.org/display/JENKINS/Checking+out+existing+plugins
- http://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial
- http://wiki.jenkins-ci.org/display/JENKINS/Hosting+Plugins

================================================
FILE: docs/Reporting.md
================================================
<small>[<< Back to main page](./)</small>
# Performance Trend Reporting

## Features
Performance Report post-build step allows you to generate reports from popular testing tools. Jenkins will generate graphic charts with the trend report of performance and robustness.

It includes the feature of setting the final build status as good, unstable or failed, based on the reported error percentage.

Report formats supported:
- Taurus Tool's [Final Stats XML](http://gettaurus.org/docs/Reporting/?utm_source=jenkins&utm_medium=link&utm_campaign=wiki#BlazeMeter-Reporter) - through it, you can publish summaries from JMeter, Gatling, Grinder, Siege, ab, Selenium and many others
- [Apache JMeter](https://jmeter.apache.org/) CSV and XML format, also its Summarizer log output
- [JUnit](https://junit.org/junit5/) format (used by SoapUI for example)
- Twitter's [Iago](https://github.com/twitter/iago)
- [wrk](https://github.com/wg/wrk)
- [HPE LoadRunner](https://www.microfocus.com/en-us/products/loadrunner-load-testing/overview)

## Browsing Reports

As soon as you have configured Jenkins to run this post-build action and launched a first build, you'll notice that a new entry is appearing in the left pane: Performance Trend.

If you just have one report file, the graph of this reports will appear on the main page.

If you have more than one report file, you have to click on "Performance Trend" and the graphs will appear.

![](report_trend.jpg)


The link: Filter trend data in the Performance Trend Page, will permit you to configure the graphs. When you click on it, you obtain the graph configuration menu.

This configuration will be saved in a cookie named performance. The default configuration is: "Show all the builds".

![](report_filter.jpg)
         
         
The link Last report in the Performance Trend Page, give us the detailed information of each report for the last build.

You can access to the data of old builds pushing on the new menu entry of each build named Performance report.

![](report_single.jpg)


In the performance trend page, the links to Trend report shows a report with the history data of each build.


![](report_trend_table.jpg)


## Jenkins GUI Configuration

If you are using GUI to configure Jenkins jobs, start with adding "Publish Pefrormance test result report" item into your post-build actions:

![](report_step_choice.png)

Specify the report files into "Source data files" field, separate multiple entries with semicolon. Plugin will autodetect file format for each file. You can use Jenkins globs like `**/*.jtl`.

You can configure the error percentage thresholds and the relative percentage thresholds which would make the project unstable or failed or set them to `-1` to disable the feature:

![](report_constraints.png)

## Using from Pipeline Scripts

You can use Pipleline Script builder to build groovy script piece from GUI. Additinally, Performance Plugin offers "perfReport" Groovy command that allows shorthand use to simply build report, it will autodetect source file format:
 
### Minimal configuration 
```groovy
perfReport 'result.csv'
```

### More advanced configuration
```groovy
perfReport filterRegex: '', relativeFailedThresholdNegative: 1.2, relativeFailedThresholdPositive: 1.89, relativeUnstableThresholdNegative: 1.8, relativeUnstableThresholdPositive: 1.5, sourceDataFiles: 'results.csv'
```

### Minimal command for old-style invocation is this:

Minimal command for old-style invocation is this:

```groovy
performanceReport parsers: [[$class: 'JMeterParser', glob: 'result.xml']], relativeFailedThresholdNegative: 1.2, relativeFailedThresholdPositive: 1.89, relativeUnstableThresholdNegative: 1.8, relativeUnstableThresholdPositive: 1.5
```


================================================
FILE: docs/RunTests.md
================================================
<small>[<< Back to main page](./)</small>
# Running Performance Tests

## Features
Performance Plugin for Jenkins uses [Taurus Tool](http://gettaurus.org/?utm_source=jenkins&utm_medium=link&utm_campaign=run_doc_main) to execute load tests. Main benefit of Taurus is that it provides abstraction layer over popular Open Source tools, including: [Apache JMeter](http://gettaurus.org/docs/JMeter/?utm_source=jenkins&utm_medium=link&utm_campaign=run_doc_jmeter), [Gatling Tool](http://gettaurus.org/docs/Gatling.md?utm_source=jenkins&utm_medium=link&utm_campaign=run_doc_gatling), [Grinder](http://gettaurus.org/docs/Grinder.md?utm_source=jenkins&utm_medium=link&utm_campaign=run_doc_grinder), [Locust.io](http://gettaurus.org/docs/Locust.md?utm_source=jenkins&utm_medium=link&utm_campaign=run_doc_locust) and even [Selenium](http://gettaurus.org/docs/Selenium/?utm_source=jenkins&utm_medium=link&utm_campaign=run_doc_selenium). You can run any of these load injectors from Jenkins build step with minimal prerequisites.

_Prerequisites for Jenkins server: have Python 2.7+ installed together with one of [virtualenv](https://pypi.python.org/pypi/virtualenv) or [bzt](https://pypi.python.org/pypi/bzt) PyPi packages installed._

Internally, build step will run Taurus tool, doing some extra work around it:

- it will search for global `bzt` available, if none found it will try to use `virtualenv` to install one locally into workspace
- it will run `bzt` with provided configs and options
- it will set job status based on `bzt` exit code, making it unstable or failed 
- it will automatically generate [performance trend report](Reporting.md) after `bzt` finishes

Build step tries to minimally interfere with Taurus tool to let you use its full capabilities (Taurus is pretty feature-rich thing for running tests).

Test runner step works fine with Jenkins slaves, as well as with Pipeline syntax (see section below.)


## Jenkins GUI Configuration
If you are using GUI-based job configs for Jenkins, choose "Run Performance Test" step from "Add build step" menu:

![](run_step_choice.png)

In the field that appears, you can simply specify path to your JMeter test plan file. This is Taurus capability due to high popularity of JMeter:

![](run_jmeter.png)

If you want to use extended capabilities of Taurus, you can specify its config files and options in 'Taurus Tool parameters' field. Generally, value of that field is what will go into command line parameters of `bzt` program.

![](run_extended_config.png)

Clicking on "Advanced..." will open several options that can alter build step behavior:

- _Change working directory_ - set working directory in which test will be run, by default will be used build workspace
- _Change 'bzt' version_ - set `bzt` version that will be installed inside a `virtualenv`, by default will be installed the latest version. If version is URL or path to file then it will be installed 
- _Always use virtualenv_ - enable this flag if you want to install `bzt` into `virtualenv`
- _Automatically generate performance report_ - enabled by default, builds [performance trend report](Reporting.md) from Taurus execution results, you can turn it off if you don't need report
- _Mark build unstable/failed based on exit code_ - enabled by default, will mark build step failed if Taurus exit code is 1, and will mark it unstable if it's another non-zero exit code
- _Print debug output from all commands_ - enable this flag if you are experiencing `bzt` installation issues and want to get more debugging information into console log
- _Use '--system-site-packages' option for `virtualenv`_ - enabled by default, it speeds up automatic installation of `bzt` into workspace, advanced users might want to turn it off

## Using from Pipeline Scripts

Here's example pipeline script to use build step with `bzt` command that maps to Taurus Tool invocation.

```groovy
node {
    stage("clean") {
        cleanWs()   // requires workspace cleanup plugin to be installed
    }
    
    stage('get config file') {
            sh "wget https://raw.githubusercontent.com/Blazemeter/taurus/master/examples/jmeter/stepping.yml"
    }
    
    stage("run test") {
        bzt "stepping.yml"
    }
}
```

## Other Ways to Run Test in Jenkins (deprecated)

### Using jmeter in a 'MAVEN' project
Follow the instructions in this [article](http://www.theserverlabs.com/blog/?p=280&cpage=1)

### Using jmeter in an 'ANT' project
Although there are different ways to run jmeter tests, here is explained a method to run them using ant.

Once you have your build.xml ready to run jmeter, you can add your project to Jenkins as a Freestyle-project which uses ant, and configure it following the instructions above.

Finally run your project setting the property jmeter-home to the appropriate folder in your computer: `ant "-Djmeter-home=C:\jmeter" -f build.xml`

```xml
<project default="all">
  <!-- ant-jmeter.jar comes with jmeter, be sure this is the release you have -->
  <path id="ant.jmeter.classpath">
    <pathelement
       location="${jmeter-home}/extras/ant-jmeter-1.1.1.jar" />
  </path>
  <taskdef
    name="jmeter"
    classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"
    classpathref="ant.jmeter.classpath" />
  <target name="clean">
    <delete dir="results"/>
    <delete file="jmeter.log"/>
    <mkdir dir="results/jtl"/>
    <mkdir dir="results/html"/>
  </target>
  <target name="test" depends="clean">
    <jmeter
       jmeterhome="${jmeter-home}"
       resultlogdir="results/jtl">
      <testplans dir="test/jmeter" includes="*.jmx"/>
      <property name="jmeter.save.saveservice.output_format" value="xml"/>
    </jmeter>
  </target>
  <!-- This is not needed for the plugin, but it produces a nice html report
       which can be saved usin jenkins's archive artifact feature -->
  <target name="report" depends="test">
    <xslt
       basedir="results/jtl"
       destdir="results/html"
       includes="*.jtl"
       style="${jmeter-home}/extras/jmeter-results-detail-report_21.xsl"/>
  </target>
  <target name="all" depends="test, report"/>
</project>
```

================================================
FILE: docs/_config.yml
================================================
theme: jekyll-theme-cayman

================================================
FILE: docs/stats.html
================================================
<!DOCTYPE html>
<html lang="en-us">
<head>
    <meta charset="UTF-8">
    <title>Statistics</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="theme-color" content="#157878">
    <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
    <link rel="stylesheet"
          href="http://jenkinsci.github.io/performance-plugin/assets/css/style.css?v=ae639cea1586341f89b4711f8e51ffa156d402b6">

</head>
<body>
<section class="page-header">
    <h1 class="project-name">performance-plugin</h1>
    <h2 class="project-tagline">Performance Plugin for Jenkins CI</h2>

    <a href="https://github.com/jenkinsci/performance-plugin" class="btn">View on GitHub</a>


</section>

<section class="main-content">
    <small><a href="./">&lt;&lt; Back to main page</a></small>
    <h1 id="test">Usage Statistics</h1>

    <div id="installations" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
    <hr/>
    <div id="versions" style="min-width: 310px; height: 400px; margin: 0 auto"></div>


    <footer class="site-footer">

        <span class="site-footer-owner"><a href="https://github.com/jenkinsci/performance-plugin">performance-plugin</a> is maintained by <a
                href="https://github.com/jenkinsci">jenkinsci</a>.</span>

        <span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a>.</span>
    </footer>
</section>

<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<script>
    function values(dict) {
        var values = [];
        var keys = Object.keys(dict).sort();
        for (var k = 0; k < keys.length; k++) {
            values.push(dict[keys[k]]);
        }
        return values;
    }


    function installations(data) {
        var counts = [];
        var percents = [];
        for (var key1 in data.installations) {
            counts.push([parseInt(key1), data.installations[key1]])
        }

        for (var key2 in data.installationsPercentage) {
            percents.push([parseInt(key2), data.installationsPercentage[key2]])
        }

        return {
            series: [{
                name: 'Percentage',
                data: percents,
                yAxis: 1,
                color: "silver",
                dashStyle: "LongDash",
                lineWidth: 1
            },
                {
                    name: 'Count',
                    data: counts,
                    lineWidth: 3
                }],
            title: {
                text: 'Installations History'
            },
            xAxis: {
                type: "datetime"
            },
            yAxis: [{
                title: {
                    text: 'Installations count'
                },
                endOnTick: false,
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            }, {
                title: {
                    text: '% of Jenkins installations'
                },
                labels: {
                    formatter: function () {
                        return this.value + ' %';
                    }
                },
                endOnTick: false,
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }],
                opposite: true
            }],
            tooltip: {
                shared: true
            },
            legend: {
                layout: 'vertical',
                align: 'left',
                x: 120,
                verticalAlign: 'top',
                y: 50,
                floating: true,
                backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
            }
        };
    }

    function versions(data) {
        data = data.installationsPercentagePerVersion;

        var series = [];
        var sum = values(data).reduce(function (a, b) {
            return a + b;
        }, 0);

        var keys = Object.keys(data);
        keys.sort();

        var other = 0;
        for (var n = 0; n < keys.length; n++) {
            var ver = keys[n];
            var val = Math.round(1000 * data[ver] / sum) / 10;
            if (ver.indexOf('-') < 0 && val > 1) {
                series.push(['v ' + ver, val]);
            } else {
                other += val;
            }
        }

        if (other) {
            series.push(['Other', other]);
        }

        return {
            plotOptions: {
                series: {
                    animation: false
                }
            },
            chart: {
                type: 'column'
            },

            title: {
                text: 'Installations by Version'
            },
            xAxis: {
                type: 'category'
            },
            yAxis: {
                title: {
                    text: '% of known installations'
                },
                labels: {
                    formatter: function () {
                        return this.value + ' %';
                    }
                },
                endOnTick: false,
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '%'
            },
            legend: {
                enabled: false
            },
            series: [{
                name: 'Percentage',
                data: series
            }]
        };
    }


    $(document).ready(function () {
        $.getJSON("http://stats.jenkins.io/plugin-installation-trend/performance.stats.json").success(function (data) {
            $('#installations').highcharts(installations(data));
            $('#versions').highcharts(versions(data));
        }).fail(function () {
            alert("failed to get data")
        });
    });
</script>

</body>
</html>


================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.jenkins-ci.plugins</groupId>
        <artifactId>plugin</artifactId>
        <version>6.2153.vcf31911d10c4</version>
        <relativePath />
    </parent>

    <artifactId>performance</artifactId>
    <version>${changelist}</version>
    <packaging>hpi</packaging>

    <name>Performance Plugin</name>
    <description>This plugin allows tracking performance KPIs, based on results read from popular testing tools  (JMeter, JUnit, Taurus).</description>
    <url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>

    <developers>
        <developer>
            <id>undera</id>
            <name>Andrey Pokhilko (CA BlazeMeter)</name>
            <email>andrey@blazemeter.com</email>
        </developer>
        <developer>
            <id>artem_fedorov</id>
            <name>Artem Fedorov (CA BlazeMeter)</name>
            <email>artem.fedorov@blazemeter.com</email>
        </developer>
        <developer>
            <id>a_st</id>
            <name>Alexander Straube</name>
            <email>alexander.straube@gmail.com</email>
        </developer>
    </developers>

    <scm child.scm.connection.inherit.append.path="false"
        child.scm.developerConnection.inherit.append.path="false"
        child.scm.url.inherit.append.path="false">
        <connection>scm:git:https://github.com/${gitHubRepo}</connection>
        <developerConnection>scm:git:https://github.com/${gitHubRepo}</developerConnection>
        <tag>${scmTag}</tag>
        <url>https://github.com/${gitHubRepo}</url>
    </scm>

    <distributionManagement>
        <repository>
            <id>maven.jenkins-ci.org</id>
            <url>https://repo.jenkins-ci.org/releases</url>
        </repository>
    </distributionManagement>

    <properties>
        <changelist>999999-SNAPSHOT</changelist>
        <!-- https://www.jenkins.io/doc/developer/plugin-development/choosing-jenkins-baseline/ -->
        <jenkins.baseline>2.516</jenkins.baseline>
        <jenkins.version>${jenkins.baseline}.1</jenkins.version>
        <gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
        <hpi.bundledArtifacts>commons-csv,hsqldb,jackcess,plexus-utils,ucanaccess</hpi.bundledArtifacts>
        <hpi.strictBundledArtifacts>true</hpi.strictBundledArtifacts>
        <concurrency>2</concurrency>
        <!-- disable SpotBugs temporarily since there are 62 bugs -->
        <spotbugs.failOnError>false</spotbugs.failOnError>
        <ban-junit4-imports.skip>false</ban-junit4-imports.skip>
        <ban-commons-lang-2.skip>false</ban-commons-lang-2.skip>
    </properties>

    <repositories>
        <repository>
            <id>repo.jenkins-ci.org</id>
            <url>https://repo.jenkins-ci.org/public/</url>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>repo.jenkins-ci.org</id>
            <url>https://repo.jenkins-ci.org/public/</url>
        </pluginRepository>
    </pluginRepositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.jenkins.tools.bom</groupId>
                <artifactId>bom-${jenkins.baseline}.x</artifactId>
                <version>6210.v69ea_fd8a_f010</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-utils</artifactId>
            <version>4.0.3</version>
        </dependency>
        <dependency>
            <groupId>io.jenkins.plugins</groupId>
            <artifactId>gson-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-csv</artifactId>
            <version>1.14.1</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-codec</groupId>
                    <artifactId>commons-codec</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>commons-io</groupId>
                    <artifactId>commons-io</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.jenkins-ci.plugins.workflow</groupId>
            <artifactId>workflow-cps</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jenkins-ci.plugins.workflow</groupId>
            <artifactId>workflow-basic-steps</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jenkins-ci.plugins.workflow</groupId>
            <artifactId>workflow-job</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jenkins-ci.plugins.workflow</groupId>
            <artifactId>workflow-durable-task-step</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.sf.ucanaccess</groupId>
            <artifactId>ucanaccess</artifactId>
            <version>5.0.1</version>
        </dependency>
    </dependencies>
</project>


================================================
FILE: requirements.txt
================================================
virtualenv
bzt
urwid>=3.0.2,<4.0.0
apiritif

================================================
FILE: src/main/java/hudson/plugins/performance/PerformancePublisher.java
================================================
package hudson.plugins.performance;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jenkinsci.Symbol;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.init.InitMilestone;
import hudson.init.Initializer;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.Items;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.plugins.performance.actions.ExternalBuildReportAction;
import hudson.plugins.performance.actions.PerformanceBuildAction;
import hudson.plugins.performance.actions.PerformanceProjectAction;
import hudson.plugins.performance.constraints.AbstractConstraint;
import hudson.plugins.performance.constraints.ConstraintChecker;
import hudson.plugins.performance.constraints.ConstraintEvaluation;
import hudson.plugins.performance.constraints.ConstraintFactory;
import hudson.plugins.performance.constraints.blocks.PreviousResultsBlock;
import hudson.plugins.performance.constraints.blocks.TestCaseBlock;
import hudson.plugins.performance.cookie.CookieHandler;
import hudson.plugins.performance.data.ConstraintSettings;
import hudson.plugins.performance.data.HttpSample;
import hudson.plugins.performance.data.PerformanceReportPosition;
import hudson.plugins.performance.data.TaurusFinalStats;
import hudson.plugins.performance.descriptors.ConstraintDescriptor;
import hudson.plugins.performance.descriptors.PerformanceReportParserDescriptor;
import hudson.plugins.performance.details.GraphConfigurationDetail;
import hudson.plugins.performance.details.TestSuiteReportDetail;
import hudson.plugins.performance.details.TrendReportDetail;
import hudson.plugins.performance.parsers.AbstractParser;
import hudson.plugins.performance.parsers.IagoParser;
import hudson.plugins.performance.parsers.JMeterCsvParser;
import hudson.plugins.performance.parsers.JMeterParser;
import hudson.plugins.performance.parsers.JUnitParser;
import hudson.plugins.performance.parsers.JmeterSummarizerParser;
import hudson.plugins.performance.parsers.ParserFactory;
import hudson.plugins.performance.parsers.PerformanceReportParser;
import hudson.plugins.performance.parsers.TaurusParser;
import hudson.plugins.performance.parsers.WrkSummarizerParser;
import hudson.plugins.performance.reports.AbstractReport;
import hudson.plugins.performance.reports.ConstraintReport;
import hudson.plugins.performance.reports.PerformanceReport;
import hudson.plugins.performance.reports.ThroughputReport;
import hudson.plugins.performance.reports.UriReport;
import hudson.plugins.performance.tools.SafeMaths;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Publisher;
import hudson.tasks.Recorder;
import hudson.util.ListBoxModel;
import jenkins.tasks.SimpleBuildStep;

public class PerformancePublisher extends Recorder implements SimpleBuildStep {

    public static final double THRESHOLD_TOLERANCE = 0.0000000000000000000000000000000000000000000000000000000000000000000000000000001;
    private static final double DEFAULT_THRESHOLD = -1;

    private int errorFailedThreshold = -1;

    private int errorUnstableThreshold = -1;

    private String errorUnstableResponseTimeThreshold = "";

    private double relativeFailedThresholdPositive = DEFAULT_THRESHOLD;

    private double relativeFailedThresholdNegative = DEFAULT_THRESHOLD;

    private double relativeUnstableThresholdPositive = DEFAULT_THRESHOLD;

    private double relativeUnstableThresholdNegative = DEFAULT_THRESHOLD;

    private int nthBuildNumber = 0;

    private String configType = "ART";

    private String graphType = "ART";

    private boolean modeOfThreshold = false;

    private boolean failBuildIfNoResultFile = true;

    private boolean compareBuildPrevious = false;

    public static final String ART = "ART";

    public static final String MRT = "MRT";

    public static final String PRT = "PRT";

    public String optionType = "ART";

    private static final String ARCHIVE_DIRECTORY = "archive";

    private boolean modePerformancePerTestCase = false;

    /**
     * Exclude response time of errored samples
     */
    private boolean excludeResponseTime;

    /**
     * Show Trends mode.
     */
    private boolean showTrendGraphs;

    /**
     * @deprecated as of 1.3. for compatibility
     */
    private transient String filename; // NOSONAR On purpose keep of transient, we don't want to save it

    private boolean modeThroughput;

    /**
     * Performance evaluation mode. false = standard mode; true = expert mode
     */
    private boolean modeEvaluation = false;

    /**
     * Configured constraints
     */
    private List<? extends AbstractConstraint> constraints = Collections.emptyList();

    /**
     * Constraint settings
     */
    private boolean ignoreFailedBuilds;
    private boolean ignoreUnstableBuilds;
    private boolean persistConstraintLog;

    /**
     * @deprecated as of 2.2. for compatibility
     * Migrate into String reportFiles with autodetect parser type.
     * Now this param use for restore previous job configs in GUI mode.
     */
    @Deprecated
    private transient List<PerformanceReportParser> parsers; // NOSONAR On purpose keep of transient, we don't want to save it

    private String sourceDataFiles;
    private String filterRegex;

    /**
     * Optional filename indicating whether and where a JUnit compatible XML report should be written
     */
    private String junitOutput = "";

    /**
     * Percentiles that will be display in url tables
     * comma-separated
     */
    private String percentiles = AbstractReport.DEFAULT_PERCENTILES;


    /**
     * Base line build for create performance Trends
     * default '0' - is previous build
     */
    private int baselineBuild;

    /**
     * Legacy constructor used for internal references.
     */
    @Restricted(NoExternalUse.class)
    public PerformancePublisher(String sourceDataFiles,
                                int errorFailedThreshold,
                                int errorUnstableThreshold,
                                String errorUnstableResponseTimeThreshold,
                                double relativeFailedThresholdPositive,
                                double relativeFailedThresholdNegative,
                                double relativeUnstableThresholdPositive,
                                double relativeUnstableThresholdNegative,
                                int nthBuildNumber,
                                boolean modePerformancePerTestCase,
                                String configType,
                                boolean modeOfThreshold,
                                boolean failBuildIfNoResultFile,
                                boolean compareBuildPrevious,
                                boolean modeThroughput,
                                boolean showTrendGraphs,
                                /**
                                 * Deprecated. Now use for support previous pipeline jobs.
                                 */
                                List<PerformanceReportParser> parsers) {
        this.parsers = parsers;
        this.sourceDataFiles = sourceDataFiles;
        migrateParsers();

        this.errorFailedThreshold = errorFailedThreshold;
        this.errorUnstableThreshold = errorUnstableThreshold;
        this.errorUnstableResponseTimeThreshold = errorUnstableResponseTimeThreshold;
        this.showTrendGraphs = showTrendGraphs;

        this.relativeFailedThresholdPositive = relativeFailedThresholdPositive;
        this.relativeFailedThresholdNegative = relativeFailedThresholdNegative;
        this.relativeUnstableThresholdPositive = relativeUnstableThresholdPositive;
        this.relativeUnstableThresholdNegative = relativeUnstableThresholdNegative;

        this.nthBuildNumber = nthBuildNumber;
        this.configType = configType;
        this.optionType = configType;
        this.modeOfThreshold = modeOfThreshold;
        this.failBuildIfNoResultFile = failBuildIfNoResultFile;
        this.compareBuildPrevious = compareBuildPrevious;

        this.modePerformancePerTestCase = modePerformancePerTestCase;
        this.modeThroughput = modeThroughput;
    }

    @DataBoundConstructor
    public PerformancePublisher(String sourceDataFiles) {
        this.sourceDataFiles = sourceDataFiles;
    }

    public static File getPerformanceReport(Run<?, ?> build, String parserDisplayName,
                                            String performanceReportName) {
        return new File(build.getRootDir(), PerformanceReportMap.getPerformanceReportFileRelativePath(parserDisplayName,
                getPerformanceReportBuildFileName(performanceReportName)));
    }

    @Override
    public Action getProjectAction(AbstractProject<?, ?> project) {
        return new PerformanceProjectAction(project);
    }

    public BuildStepMonitor getRequiredMonitorService() {
        return BuildStepMonitor.NONE;
    }


    /**
     * <p>
     * Delete the date suffix appended to the Performance result files by the
     * Maven Performance plugin
     * </p>
     *
     * @return the name of the PerformanceReport in the Build
     */
    public static String getPerformanceReportBuildFileName(String performanceReportWorkspaceName) {
        String result = performanceReportWorkspaceName;
        if (performanceReportWorkspaceName != null) {
            Pattern p = Pattern.compile("-[0-9]*\\.xml");
            Matcher matcher = p.matcher(performanceReportWorkspaceName);
            if (matcher.find()) {
                result = matcher.replaceAll(".xml");
            }
        }
        return result;
    }

    /**
     * look for performance reports based in the configured parameter includes.
     * 'includes' is - an Ant-style pattern - a list of files and folders
     * separated by the characters ;:,
     */
    protected static List<FilePath> locatePerformanceReports(FilePath workspace, String includes)
            throws IOException, InterruptedException {

        // First use ant-style pattern
        /*
         * try { FilePath[] ret = workspace.list(includes); if (ret.length > 0) {
         * return Arrays.asList(ret); }
         */
        // Agoley : Possible fix, if we specify more than one result file pattern
        try {
            String[] parts = includes.split("\\s*[;:,]+\\s*");

            List<FilePath> files = new ArrayList<>();
            for (String path : parts) {
                FilePath[] ret = workspace.list(path);
                if (ret.length > 0) {
                    files.addAll(Arrays.asList(ret));
                }
            }
            if (!files.isEmpty())
                return files;

        } catch (IOException ignored) {
            // NOOP
        }

        // Agoley: seems like this block doesn't work
        // If it fails, do a legacy search
        ArrayList<FilePath> files = new ArrayList<>();
        String[] parts = includes.split("\\s*[;:,]+\\s*");
        for (String path : parts) {
            FilePath src = workspace.child(path);
            if (src.exists()) {
                if (src.isDirectory()) {
                    files.addAll(Arrays.asList(src.list("**/*")));
                } else {
                    files.add(src);
                }
            }
        }
        if (!files.isEmpty())
            return files;

        // give up and just try direct matching on string
        File directFile = new File(includes);
        if (directFile.exists())
            files.add(new FilePath(directFile));
        return files;
    }

    protected List<PerformanceReportParser> getParsers(Run<?, ?> build, FilePath workspace, PrintStream logger, EnvVars env) throws IOException, InterruptedException {
        final List<PerformanceReportParser> parsers = new ArrayList<>();
        if (sourceDataFiles != null) {
            for (String filePath : sourceDataFiles.split(";")) {
                if (!filePath.isEmpty()) {
                    try {
                        logger.println("Creating parser with percentiles:'" + percentiles + ",' filterRegex:" + filterRegex);
                        parsers.addAll(ParserFactory.getParser(build, workspace, logger, filePath, env, percentiles, filterRegex));
                    } catch (IOException ex) {
                        logger.println("Cannot detect file type because of error: " + ex.getMessage());
                    }
                }
            }
        }
        return parsers;
    }

    /**
     * Used to migrate from user selected parser to autodetected parser
     */
    private void migrateParsers() {
        if (parsers != null && !this.parsers.isEmpty()) {
            StringBuilder builder = new StringBuilder();
            for (PerformanceReportParser p : this.parsers) {
                builder.append(p.glob).append(';');
            }
            builder.setLength(builder.length() - 1);
            if (this.sourceDataFiles == null || this.sourceDataFiles.equals("")) {
                this.sourceDataFiles = builder.toString();
            } else {
                this.sourceDataFiles = this.sourceDataFiles + ";" + builder.toString();
            }
            this.parsers = null;
        }
    }

    /**
     * This method, invoked after object is resurrected from persistence
     */
    public Object readResolve() {
        // data format migration
        if (parsers == null)
            parsers = new ArrayList<>();
        if (filename != null) {
            parsers.add(new JMeterParser(filename, percentiles, filterRegex));
            filename = null;
        }
        // Migrate parsers to simple field sourceDataFiles.
        migrateParsers();
        return this;
    }


    @Override
    public void perform(@NonNull Run<?, ?> run, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull TaskListener listener)
            throws InterruptedException, IOException {
        run.setResult(Result.SUCCESS);

        final List<PerformanceReportParser> parsers = getParsers(run, workspace, listener.getLogger(), run.getEnvironment(listener));
        if (!parsers.isEmpty()) {
            prepareParsers(parsers);

            Collection<PerformanceReport> parsedReports = prepareEvaluation(run, workspace, listener, parsers);
            if (parsedReports == null) {
                return;
            }

            if (!modeEvaluation) {
                evaluateInStandardMode(run, workspace, parsedReports, listener, parsers);
                writeStandardResultsToXML(run, parsedReports);
            } else {
                evaluateInExpertMode(run, workspace, listener);
            }
        } else {
            if (failBuildIfNoResultFile) {
                run.setResult(Result.FAILURE);
            }
        }
    }

    /**
     * preparing evaluation - this is necessary regardless of the mode of
     * evaluation
     */
    public Collection<PerformanceReport> prepareEvaluation(Run<?, ?> run, FilePath workspace, TaskListener listener, List<PerformanceReportParser> parsers)
            throws IOException, InterruptedException {

        // add the report to the build object.
        PerformanceBuildAction a = new PerformanceBuildAction(run, listener.getLogger(), parsers);
        run.addAction(a);

        Collection<PerformanceReport> parsedReports = locatePerformanceReports(run, workspace, listener, parsers);
        if (parsedReports == null) {
            return Collections.emptyList();
        }

        addExternalReportActionsToBuild(run, parsers);

        for (PerformanceReport r : parsedReports) {
            r.setBuildAction(a);
        }

        return parsedReports;
    }

    private void addExternalReportActionsToBuild(Run<?, ?> run, List<PerformanceReportParser> parsers) {
        for (PerformanceReportParser parser : parsers) {
            if (parser.reportURL != null && !parser.reportURL.isEmpty()) {
                run.addAction(new ExternalBuildReportAction(parser.reportURL));
            }
        }
    }

    private Collection<PerformanceReport> locatePerformanceReports(Run<?, ?> run, FilePath workspace, TaskListener listener, List<PerformanceReportParser> parsers) throws IOException, InterruptedException {
        Collection<PerformanceReport> performanceReports = new ArrayList<>();
        PrintStream logger = listener.getLogger();
        EnvVars env = run.getEnvironment(listener);
        String glob;
        for (PerformanceReportParser parser : parsers) {
            glob = parser.glob;
            // Replace any runtime environment variables such as ${sample_var}
            glob = env.expand(glob);
            logger.println("Performance: Recording " + parser.getReportName() + " reports '" + glob + "'");

            List<FilePath> files = locatePerformanceReports(workspace, glob);
            if (files.isEmpty()) {
                Result result = run.getResult();
                if (result != null) {
                    if (result.isWorseThan(Result.UNSTABLE)) {
                        return Collections.emptyList();
                    }
                } else {
                    // Handle the situation when result is null
                    logger.println("Result is null");
                }

                if (failBuildIfNoResultFile) {
                    run.setResult(Result.FAILURE);
                }
                logger.println("Performance: no " + parser.getReportName() + " files matching '" + glob
                        + "' have been found. Has the report generated?. Setting Build to " + run.getResult());
                return Collections.emptyList();
            }

            logger.println("Performance: " + parser.getReportName() + " copying reports to master, files '" + files + "'");
            List<File> localReports = copyReportsToMaster(run, logger, files, parser.getDescriptor().getDisplayName());
            logger.println("Performance: " + parser.getReportName() + " parsing local reports '" + localReports
                    + "'");
            performanceReports.addAll(parser.parse(run, localReports, listener));
        }
        return performanceReports;
    }

    /**
     *
     */
    private void prepareParsers(Collection<PerformanceReportParser> performanceReportParsers) {
        for (PerformanceReportParser parser : performanceReportParsers) {
            parser.setExcludeResponseTime(excludeResponseTime);
            parser.setShowTrendGraphs(showTrendGraphs);
            parser.setBaselineBuild(baselineBuild);
        }
    }

    protected List<UriReport> getBuildUriReports(Run<?, ?> build, FilePath workspace, TaskListener listener,
                                                 List<PerformanceReportParser> parsers, boolean locatePerformanceReports)
            throws IOException, InterruptedException {

        List<UriReport> uriReports = new ArrayList<>();

        if (locatePerformanceReports) {
            Collection<PerformanceReport> performanceReports = locatePerformanceReports(build, workspace, listener, parsers);
            if (performanceReports == null) {
                return Collections.emptyList();
            }

            for (PerformanceReport r : performanceReports) {
                // URI list is the list of labels in the current JMeter results
                // file
                uriReports.addAll(r.getUriListOrdered());
            }
        } else {
            Set<PerformanceReport> parsedReports = new HashSet<>();

            for (PerformanceReportParser parser : parsers) {
                // add the report to the build object.
                List<File> localReports = getExistingReports(build, listener.getLogger(), parser.getDescriptor().getDisplayName());

                // For more than one parser of the same type, existing reports will be found multiple times, 
                // so we collect them in a Set to avoid duplicates (based on comparison by report filename).
                parsedReports.addAll(parser.parse(build, localReports, listener));
            }

            for (PerformanceReport r : parsedReports) {
                // uri list is the list of labels in the previous jmeter results
                // file
                uriReports.addAll(r.getUriListOrdered());
            }

        }
        return uriReports;
    }

    // for mode "standard evaluation"
    public void evaluateInStandardMode(Run<?, ?> run, FilePath workspace, Collection<PerformanceReport> parsedReports,
                                       TaskListener listener, List<PerformanceReportParser> parsers)
            throws IOException, InterruptedException {

        if (!modeOfThreshold) {
            compareWithAbsoluteThreshold(run, listener, parsedReports);
        } else {
            compareWithRelativeThreshold(run, workspace, listener, parsers);
        }
    }


    // For absolute error/unstable threshold..
    public void compareWithAbsoluteThreshold(Run<?, ?> run, TaskListener listener, Collection<PerformanceReport> parsedReports) {
        PrintStream logger = listener.getLogger();
        try {
            printInfoAboutErrorThreshold(logger);
            HashMap<String, String> responseTimeThresholdMap = getResponseTimeThresholdMap(logger);
            // add the report to the build object.
            // mark the build as unstable or failure depending on the outcome.
            for (PerformanceReport performanceReport : parsedReports) {
                analyzeErrorThreshold(run, performanceReport, responseTimeThresholdMap, logger);
                writeErrorThresholdReportInXML(run, performanceReport);
            }
        } catch (Exception e) {
            logger.println("ERROR: Exception while determining absolute error/unstable threshold evaluation");
            e.printStackTrace(logger);
        }
    }

    // analyze Unstable and Failed thresholds values and set build result to UNSTABLE or FAILURE if needed
    private void analyzeErrorThreshold(Run<?, ?> run, PerformanceReport performanceReport, HashMap<String, String> responseTimeThresholdMap, PrintStream logger) {
        Result result = Result.SUCCESS;
        double errorPercent = performanceReport.errorPercent();

        // check average response time values
        Result res = checkAverageResponseTime(performanceReport, responseTimeThresholdMap, logger);
        if (res != null) {
            result = res;
        }

        // check failed and unstable values
        if (errorFailedThreshold >= 0 && errorPercent - errorFailedThreshold > THRESHOLD_TOLERANCE) {
            result = Result.FAILURE;
        } else if (errorUnstableThreshold >= 0 && errorPercent - errorUnstableThreshold > THRESHOLD_TOLERANCE) {
            result = Result.UNSTABLE;
        }

        // set result. It'll be set only when result is worse
        run.setResult(result);

        logger.println("Performance: File " + performanceReport.getReportFileName() + " reported " + errorPercent
                + "% of errors [" + result + "]. Build status is: " + run.getResult());
    }

    // check average response time values
    private Result checkAverageResponseTime(PerformanceReport performanceReport, HashMap<String, String> responseTimeThresholdMap, PrintStream logger) {
        long average = performanceReport.getAverage();
        try {
            if ((responseTimeThresholdMap != null && responseTimeThresholdMap.get(performanceReport.getReportFileName()) != null) &&
                    (Long.parseLong(responseTimeThresholdMap.get(performanceReport.getReportFileName())) <= average)) {
                logger.println("UNSTABLE: " + performanceReport.getReportFileName() + " has exceeded the threshold of ["
                        + Long.parseLong(responseTimeThresholdMap.get(performanceReport.getReportFileName())) + "] with the time of ["
                        + Long.toString(average) + "]");
                return Result.UNSTABLE;
            }
        } catch (NumberFormatException nfe) {
            logger.println("ERROR: Threshold set to a non-number ["
                    + responseTimeThresholdMap.get(performanceReport.getReportFileName()) + "]");
            return Result.FAILURE;
        }
        return null;
    }

    // write 'standard mode' report in xml containing each of the populated columns otherwise found in the jelly output.
    // producing an on disk, machine parseable format allows for archiving and automation.
    private void writeStandardResultsToXML(Run<?, ?> run, Collection<PerformanceReport> parsedReports) throws IOException {
        File xmlDirectory = createArchiveDirectoryIfMissing(run);
        File xmlfile = new File(xmlDirectory, "standardResults.xml");
        try (OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(xmlfile), StandardCharsets.UTF_8);
                BufferedWriter bw = new BufferedWriter(fw)){
            
            String xml = new StringBuilder("<?xml version=\"1.0\"?>\n")
                    .append("<results>\n")
                    .append(appendStandardResultsStatsToXml(parsedReports))
                    .append("</results>\n").toString();

            bw.write(xml);
        }
    }

    private String appendStandardResultsStatsToXml(Collection<PerformanceReport> reports) {
        StringBuilder xmlSB = new StringBuilder();
        for (PerformanceReport perfReport : reports) {
            for (UriReport report : perfReport.getUriListOrdered()) {
                xmlSB.append("<api>\n\t");
                xmlSB.append("<uri>").append(report.getUri()).append("</uri>\n\t");
                xmlSB.append("<samples>").append(report.samplesCount()).append("</samples>\n\t");
                xmlSB.append("<average>").append(report.getAverage()).append("</average>\n\t");
                xmlSB.append("<min>").append(report.getMin()).append("</min>\n\t");
                xmlSB.append("<median>").append(report.getMedian()).append("</median>\n\t");
                xmlSB.append("<ninetieth>").append(report.get90Line()).append("</ninetieth>\n\t");
                xmlSB.append("<ninetyFifth>").append(report.get95Line()).append("</ninetyFifth>\n\t");
                xmlSB.append("<max>").append(report.getMax()).append("</max>\n\t");
                xmlSB.append("<httpCode>").append(report.getHttpCode()).append("</httpCode>\n\t");
                xmlSB.append("<errors>").append(report.errorPercent()).append("</errors>\n");
                xmlSB.append("</api>\n");
            }
        }
        return xmlSB.toString();
    }

    // write report in xml, when checked Error Threshold comparison
    private void writeErrorThresholdReportInXML(Run<?, ?> run, PerformanceReport performanceReport) throws IOException {
        File xmlDirectory = createArchiveDirectoryIfMissing(run);

        String glob = performanceReport.getReportFileName();
        String[] arr = glob.split("/");

        File xmlfile = new File(xmlDirectory, "/dashBoard_" + arr[arr.length - 1].split("\\.")[0] + ".xml");
        try (OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(xmlfile), StandardCharsets.UTF_8);
             BufferedWriter bw = new BufferedWriter(fw)) {
            String xml = "<?xml version=\"1.0\"?>\n";
            xml += "<results>\n";
            xml += "<absoluteDefinition>\n";
            xml += "\t<unstable>" + errorUnstableThreshold + "</unstable>\n";
            xml += "\t<failed>" + errorFailedThreshold + "</failed>\n";
            xml += "\t<calculated>" + performanceReport.errorPercent() + "</calculated>\n";
            xml += "</absoluteDefinition>\n";

            xml += appendStatsToXml(performanceReport.getUriListOrdered());

            xml += "</results>";

            bw.write(xml);
        }
    }

    private String appendStatsToXml(List<UriReport> reports) {
        final StringBuilder averageBuffer = new StringBuilder("<average>\n");
        final StringBuilder medianBuffer = new StringBuilder("<median>\n");
        final StringBuilder percentileBuffer = new StringBuilder("<percentile>\n");

        for (UriReport uriReport : reports) {
            averageBuffer.append("\t<").append(uriReport.getStaplerUri()).append(">\n");
            averageBuffer.append("\t\t<currentBuildAvg>").append(uriReport.getAverage()).append("</currentBuildAvg>\n");
            averageBuffer.append("\t</").append(uriReport.getStaplerUri()).append(">\n");

            medianBuffer.append("\t<").append(uriReport.getStaplerUri()).append(">\n");
            medianBuffer.append("\t\t<currentBuildMed>").append(uriReport.getMedian()).append("</currentBuildMed>\n");
            medianBuffer.append("\t</").append(uriReport.getStaplerUri()).append(">\n");

            percentileBuffer.append("\t<").append(uriReport.getStaplerUri()).append(">\n");
            percentileBuffer.append("\t\t<currentBuild90Line>").append(uriReport.get90Line()).append("</currentBuild90Line>\n");
            percentileBuffer.append("\t</").append(uriReport.getStaplerUri()).append(">\n");

            percentileBuffer.append("\t<").append(uriReport.getStaplerUri()).append(">\n");
            percentileBuffer.append("\t\t<currentBuild95Line>").append(uriReport.get95Line()).append("</currentBuild95Line>\n");
            percentileBuffer.append("\t</").append(uriReport.getStaplerUri()).append(">\n");

        }

        averageBuffer.append("</average>\n");
        medianBuffer.append("</median>\n");
        percentileBuffer.append("</percentile>\n");

        StringBuilder result = new StringBuilder();
        result.append(averageBuffer);
        result.append(medianBuffer);
        result.append(percentileBuffer);
        return result.toString();
    }


    private HashMap<String, String> getResponseTimeThresholdMap(PrintStream logger) {
        HashMap<String, String> responseTimeThresholdMap = null;
        if (!"".equals(this.errorUnstableResponseTimeThreshold) && this.errorUnstableResponseTimeThreshold != null) {

            responseTimeThresholdMap = new HashMap<>();
            String[] lines = this.errorUnstableResponseTimeThreshold.split("\n");

            for (String line : lines) {
                String[] components = line.split(":");
                if (components.length == 2) {
                    logger.println("Setting threshold: " + components[0] + ":" + components[1]);
                    responseTimeThresholdMap.put(components[0], components[1]);
                }
            }
        }
        return responseTimeThresholdMap;
    }


    // For relative comparisons between builds...
    public void compareWithRelativeThreshold(Run<?, ?> run, FilePath workspace, TaskListener listener, List<PerformanceReportParser> parsers)
            throws IOException, InterruptedException {
        PrintStream logger = listener.getLogger();
        try {
            printInfoAboutRelativeThreshold(logger);

            List<UriReport> currentUriReports = getBuildUriReports(run, workspace, listener, parsers, true);
            if (currentUriReports == null) {
                return;
            }

            StringBuilder averageBuffer = null;
            StringBuilder medianBuffer = null;
            StringBuilder percentileBuffer = null;

            // getting previous build/nth previous build..
            Run<?, ?> buildForComparison = compareBuildPrevious ? run.getPreviousSuccessfulBuild() : getnthBuild(run);

            if (buildForComparison != null) {
                logger.print("\nComparison build no. - " + buildForComparison.number + " and " + run.number + " using ");

                int maxUriColumnWidth = 0;
                for (UriReport report : currentUriReports) {
                    maxUriColumnWidth = Math.max(report.getStaplerUri().length(), maxUriColumnWidth);
                }

                printInfoAboutCompareBasedOn(logger, "%-" + maxUriColumnWidth + "s%20s%20s%20s%20s");

                compareUriReports(run,
                        currentUriReports,
                        // getting files related to the previous build selected
                        getBuildUriReports(buildForComparison, workspace, listener, parsers, false),
                        logger,
                        // open xml tags
                        (averageBuffer = new StringBuilder("<average>\n")),
                        (medianBuffer = new StringBuilder("<median>\n")),
                        (percentileBuffer = new StringBuilder("<percentile>\n")),
                        "%1$-" + maxUriColumnWidth + "s%2$20d%3$20d%4$20.0f%5$19.2f%%"
                );

                // close xml tags
                averageBuffer.append("</average>\n");
                medianBuffer.append("</median>\n");
                percentileBuffer.append("</percentile>");
            }

            writeRelativeThresholdReportInXML(run, averageBuffer, medianBuffer, percentileBuffer);


        } catch (Exception e) {
            logger.println("ERROR: Exception while determining relative comparison between builds");
            e.printStackTrace(logger);
        }

    }


    // Comparing both builds based on either average, median or 90
    // percentile response time...
    private void compareUriReports(Run<?, ?> run, List<UriReport> currentUriReports, List<UriReport> reportsForComparison, PrintStream logger,
                                   StringBuilder averageBuffer, StringBuilder medianBuffer, StringBuilder percentileBuffer, String logFormat) {

        // comparing the labels and calculating the differences...
        for (UriReport reportForComparison : reportsForComparison) {
            for (UriReport currentUriReport : currentUriReports) {
                if (reportForComparison.getStaplerUri().equalsIgnoreCase(currentUriReport.getStaplerUri())) {

                    appendRelativeInfoAboutAverage(currentUriReport, reportForComparison, averageBuffer);
                    appendRelativeInfoAboutMedian(currentUriReport, reportForComparison, medianBuffer);
                    appendRelativeInfoAbout90Line(currentUriReport, reportForComparison, percentileBuffer);

                    calculateBuildStatus(run, logger, reportForComparison.getStaplerUri(),
                            calculateRelativeDiffInPercent(currentUriReport, reportForComparison, logger, logFormat));
                }
            }
        }
    }

    // setting the build status based on the differences
    // calculated...
    private void calculateBuildStatus(Run<?, ?> run, PrintStream logger, String staplerUri, double relativeDiffPercent) {
        Result result = null;
        if (relativeDiffPercent < 0) {
            if (calculateRelativeFailedThresholdNegative(relativeDiffPercent)) {
                result = Result.FAILURE;
            } else if (calculateRelativeUnstableThresholdNegative(relativeDiffPercent)) {
                result = Result.UNSTABLE;
            }
        } else if (relativeDiffPercent >= 0) {
            if (calculateRelativeFailedThresholdPositive(relativeDiffPercent)) {
                result = Result.FAILURE;
            } else if (calculateRelativeUnstableThresholdPositive(relativeDiffPercent)) {
                result = Result.UNSTABLE;
            }
        }

        if (result != null) {
            // set result. It'll be set only when result is worse
            run.setResult(result);
            logger.print(
                    (result == Result.FAILURE) ?
                            "\nThe label \"" + staplerUri + "\"" + " caused the build to fail\n" :
                            "\nThe label \"" + staplerUri + "\"" + " made the build unstable\n"
            );
        }
    }

    private double calculateDiffInPercents(double value1, double value2) {
        return Math.round(SafeMaths.safeDivide(value1 * 100, value2) * 100) / 100d;
    }

    private boolean calculateRelativeFailedThresholdNegative(double relativeDiffPercent) {
        return (relativeFailedThresholdNegative >= 0
                && Math.abs(relativeDiffPercent) - relativeFailedThresholdNegative > THRESHOLD_TOLERANCE);
    }

    private boolean calculateRelativeUnstableThresholdNegative(double relativeDiffPercent) {
        return (relativeUnstableThresholdNegative >= 0
                && Math.abs(relativeDiffPercent) - relativeUnstableThresholdNegative > THRESHOLD_TOLERANCE);
    }

    private boolean calculateRelativeFailedThresholdPositive(double relativeDiffPercent) {
        return (relativeFailedThresholdPositive >= 0
                && Math.abs(relativeDiffPercent) - relativeFailedThresholdPositive > THRESHOLD_TOLERANCE);
    }

    private boolean calculateRelativeUnstableThresholdPositive(double relativeDiffPercent) {
        return (relativeUnstableThresholdPositive >= 0
                && Math.abs(relativeDiffPercent) - relativeUnstableThresholdPositive > THRESHOLD_TOLERANCE);
    }

    private double calculateRelativeDiffInPercent(UriReport currentReport, UriReport reportForComparison, PrintStream logger, String logFormat) {
        double relativeDiff;
        double relativeDiffPercent = 0;

        if (configType.equalsIgnoreCase("ART")) {
            relativeDiff = (double) currentReport.getAverage() - reportForComparison.getAverage();
            relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.getAverage());

            logger.println(String.format(logFormat, reportForComparison.getStaplerUri(),
                    reportForComparison.getAverage(), currentReport.getAverage(),
                    relativeDiff, relativeDiffPercent));

        } else if (configType.equalsIgnoreCase("MRT")) {
            relativeDiff = (double) currentReport.getMedian() - reportForComparison.getMedian();
            relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.getMedian());

            logger.println(String.format(logFormat, reportForComparison.getStaplerUri(),
                    reportForComparison.getMedian(), currentReport.getMedian(),
                    relativeDiff, relativeDiffPercent));

        } else if (configType.equalsIgnoreCase("PRT")) {
            relativeDiff = (double) currentReport.get90Line() - reportForComparison.get90Line();
            relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.get90Line());

            logger.println(String.format(logFormat, reportForComparison.getStaplerUri(),
                    reportForComparison.get90Line(), currentReport.get90Line(),
                    relativeDiff, relativeDiffPercent));
        }
        return relativeDiffPercent;
    }

    private void writeRelativeThresholdReportInXML(Run<?, ?> run, StringBuilder averageBuffer,
                                                   StringBuilder medianBuffer, StringBuilder percentileBuffer) throws IOException {
        File xmlDirectory = createArchiveDirectoryIfMissing(run);

        File xmlfile = new File(xmlDirectory, "dashBoard_results.xml");
        try (OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(xmlfile), StandardCharsets.UTF_8);
             BufferedWriter bw = new BufferedWriter(fw)) {

            String buildNo = "\t<buildNum>" + (compareBuildPrevious ? "previous" : nthBuildNumber) + "</buildNum>\n";

            String unstable = "\t<unstable>\n";
            unstable += "\t\t<negative>" + relativeUnstableThresholdNegative + "</negative>\n";
            unstable += "\t\t<positive>" + relativeUnstableThresholdPositive + "</positive>\n";
            unstable += "\t</unstable>\n";

            String failed = "\t<failed>\n";
            failed += "\t\t<negative>" + relativeFailedThresholdNegative + "</negative>\n";
            failed += "\t\t<positive>" + relativeFailedThresholdPositive + "</positive>\n";
            failed += "\t</failed>\n";

            String relative = "<relativeDefinition>\n";
            relative += buildNo + unstable + failed;
            relative += "</relativeDefinition>";

            bw.write("<?xml version=\"1.0\"?>\n");
            bw.write("<results>\n");
            bw.write(relative + "\n");

            if (averageBuffer != null) {
                bw.write(averageBuffer.toString());
            }

            if (medianBuffer != null) {
                bw.write(medianBuffer.toString());
            }

            if (percentileBuffer != null) {
                bw.write(percentileBuffer.toString());
            }

            bw.write("</results>");
        }
    }

    private File createArchiveDirectoryIfMissing(Run<?, ?> run) {
        File xmlDirectory = new File(run.getRootDir(), ARCHIVE_DIRECTORY);
        if (!xmlDirectory.exists() && !xmlDirectory.mkdirs()) {
            throw new IllegalStateException("Could not create archive directory " + xmlDirectory.getAbsolutePath());
        }
        return xmlDirectory;
    }


    private void appendRelativeInfoAboutAverage(UriReport currentReport, UriReport reportForComparison, StringBuilder averageBuffer) {
        double relativeDiff = (double) currentReport.getAverage() - reportForComparison.getAverage();
        double relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.getAverage());

        averageBuffer.append("\t<").append(currentReport.getStaplerUri()).append(">\n");
        averageBuffer.append("\t\t<previousBuildAvg>").append(reportForComparison.getAverage()).append("</previousBuildAvg>\n");
        averageBuffer.append("\t\t<currentBuildAvg>").append(currentReport.getAverage()).append("</currentBuildAvg>\n");
        averageBuffer.append("\t\t<relativeDiff>").append(relativeDiff).append("</relativeDiff>\n");
        averageBuffer.append("\t\t<relativeDiffPercent>").append(relativeDiffPercent).append("</relativeDiffPercent>\n");
        averageBuffer.append("\t</").append(currentReport.getStaplerUri()).append(">\n");
    }

    private void appendRelativeInfoAboutMedian(UriReport currentReport, UriReport reportForComparison, StringBuilder medianBuffer) {
        double relativeDiff = (double) currentReport.getMedian() - reportForComparison.getMedian();
        double relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.getMedian());

        medianBuffer.append("\t<").append(currentReport.getStaplerUri()).append(">\n");
        medianBuffer.append("\t\t<previousBuildMed>").append(reportForComparison.getMedian()).append("</previousBuildMed>\n");
        medianBuffer.append("\t\t<currentBuildMed>").append(currentReport.getMedian()).append("</currentBuildMed>\n");
        medianBuffer.append("\t\t<relativeDiff>").append(relativeDiff).append("</relativeDiff>\n");
        medianBuffer.append("\t\t<relativeDiffPercent>").append(relativeDiffPercent).append("</relativeDiffPercent>\n");
        medianBuffer.append("\t</").append(currentReport.getStaplerUri()).append(">\n");
    }

    private void appendRelativeInfoAbout90Line(UriReport currentReport, UriReport reportForComparison, StringBuilder percentileBuffer) {
        double relativeDiff = (double) currentReport.get90Line() - reportForComparison.get90Line();
        double relativeDiffPercent = calculateDiffInPercents(relativeDiff, reportForComparison.get90Line());

        percentileBuffer.append("\t<").append(currentReport.getStaplerUri()).append(">\n");
        percentileBuffer.append("\t\t<previousBuild90Line>").append(reportForComparison.get90Line()).append("</previousBuild90Line>\n");
        percentileBuffer.append("\t\t<currentBuild90Line>").append(currentReport.get90Line()).append("</currentBuild90Line>\n");
        percentileBuffer.append("\t\t<relativeDiff>").append(relativeDiff).append("</relativeDiff>\n");
        percentileBuffer.append("\t\t<relativeDiffPercent>").append(relativeDiffPercent).append("</relativeDiffPercent>\n");
        percentileBuffer.append("\t</").append(currentReport.getStaplerUri()).append(">\n");
    }

    // Print information about Unstable & Failed Threshold
    private void printInfoAboutErrorThreshold(PrintStream logger) {
        logger.println(
                (errorUnstableThreshold >= 0 && errorUnstableThreshold <= 100) ?
                        "Performance: Percentage of errors greater or equal than " + errorUnstableThreshold
                                + "% sets the build as " + Result.UNSTABLE.toString().toLowerCase() :
                        "Performance: No threshold configured for making the test " + Result.UNSTABLE.toString().toLowerCase()
        );

        logger.println(
                (errorFailedThreshold >= 0 && errorFailedThreshold <= 100) ?
                        "Performance: Percentage of errors greater or equal than " + errorFailedThreshold
                                + "% sets the build as " + Result.FAILURE.toString().toLowerCase() :
                        "Performance: No threshold configured for making the test " + Result.FAILURE.toString().toLowerCase()
        );
    }

    // Print information about Relative Threshold
    private void printInfoAboutRelativeThreshold(PrintStream logger) {
        if (relativeFailedThresholdNegative >= 0) {
            logger.printf("Performance: Percentage of relative difference less than -%s %% sets the build as [%s]%n",
                    relativeFailedThresholdNegative, Result.FAILURE.toString());
        }

        if (relativeFailedThresholdPositive >= 0) {
            logger.printf("Performance: Percentage of relative difference more than %s %% sets the build as [%s]%n",
                    relativeFailedThresholdPositive, Result.FAILURE.toString());
        }

        if (relativeUnstableThresholdNegative >= 0) {
            logger.printf("Performance: Percentage of relative difference less than -%s %% sets the build as [%s]%n",
                    relativeUnstableThresholdNegative, Result.UNSTABLE.toString());
        }

        if (relativeUnstableThresholdPositive >= 0) {
            logger.printf("Performance: Percentage of relative difference more than %s %% sets the build as [%s]%n",
                    relativeUnstableThresholdPositive, Result.UNSTABLE.toString());
        }
    }


    private void printInfoAboutCompareBasedOn(PrintStream logger, String logFormat) {
        if (configType.equalsIgnoreCase("ART")) {
            logger.println("Average response time\n\n");
            logger.println(String.format(logFormat,
                    "URI", "PrevBuildURIAvg", "CurrentBuildURIAvg", "RelativeDiff", "RelativeDiff(%)"));
        } else if (configType.equalsIgnoreCase("MRT")) {
            logger.println("Median response time\n\n");
            logger.println(String.format(logFormat,
                    "URI", "PrevBuildURIMed", "CurrentBuildURIMed", "RelativeDiff", "RelativeDiff(%)"));
        } else if (configType.equalsIgnoreCase("PRT")) {
            logger.println("90 Percentile response time\n\n");
            logger.println(String.format(logFormat,
                    "URI", "PrevBuildURI90%", "CurrentBuildURI90%", "RelativeDiff", "RelativeDiff(%)"));
        }
    }

    /*
     * For mode "expert evaluation"
     */
    public void evaluateInExpertMode(Run<?, ?> run, FilePath workspace, TaskListener listener) throws IOException, InterruptedException {
        PrintStream logger = listener.getLogger();
        ConstraintFactory factory = new ConstraintFactory();
        ConstraintSettings settings = new ConstraintSettings(listener, ignoreFailedBuilds, ignoreUnstableBuilds,
                persistConstraintLog, getBaselineBuild());
        ConstraintChecker checker = new ConstraintChecker(settings, run.getParent().getBuilds());
        ArrayList<ConstraintEvaluation> ceList = new ArrayList<>();
        try {
            ceList = checker.checkAllConstraints(factory.createConstraintClones(run, constraints));
        } catch (Exception e) {
            e.printStackTrace(logger);
        }
      /*
       * Create Report of evaluated constraints
       */
        ConstraintReport cr = new ConstraintReport(ceList, run.getParent().getBuilds().iterator().next(), persistConstraintLog);
        logger.print(cr.getLoggerMsg());
        /*
         * Determine build result
         */
        run.setResult(cr.getBuildResult());

        /*
         * Write JUnit report back to workspace, for other post-build actions to pick up
         */
        if (junitOutput != null && !junitOutput.isEmpty()) {
            listener.getLogger().println("Performance: Generating JUnit output: " + junitOutput);
            FilePath output = new FilePath(workspace, junitOutput);
            FilePath parent = output.getParent();
            if (parent != null) {
                parent.mkdirs();
            } else {
                // Handle the situation when parent is null
                listener.getLogger().println("Failed to create parent dirs because the path is null.");
            }
            try {
                String junitReport = cr.getJunitReport();
                if (junitReport != null) {
                    output.write(junitReport, null);
                } else {
                    listener.getLogger().println("Failed to write JUnit file because junitreport is null.");
                }
            }
            catch (IOException ex) {
                listener.getLogger().println("Failed to write JUnit file: "+ex.getMessage());
            }
        }
    }

    private List<File> copyReportsToMaster(Run<?, ?> build, PrintStream logger, List<FilePath> files,
                                           String parserDisplayName) throws IOException, InterruptedException {
        List<File> localReports = new ArrayList<>();
        for (FilePath src : files) {
            final File localReport = getPerformanceReport(build, parserDisplayName, src.getName());
            if (src.isDirectory()) {
                logger.println("Performance: File '" + src.getName() + "' is a directory, not a Performance Report");
                continue;
            }
            src.copyTo(new FilePath(localReport));
            localReports.add(localReport);
        }
        return localReports;
    }


    public int getErrorFailedThreshold() {
        return errorFailedThreshold;
    }

    @DataBoundSetter
    public void setErrorFailedThreshold(int errorFailedThreshold) {
        this.errorFailedThreshold = (errorFailedThreshold == -1) ? (-1) : Math.max(0, Math.min(errorFailedThreshold, 100));
    }

    public int getErrorUnstableThreshold() {
        return errorUnstableThreshold;
    }

    @DataBoundSetter
    public void setErrorUnstableThreshold(int errorUnstableThreshold) {
        this.errorUnstableThreshold = (errorUnstableThreshold == -1) ? (-1) : Math.max(0, Math.min(errorUnstableThreshold, 100));
    }

    public String getErrorUnstableResponseTimeThreshold() {
        return this.errorUnstableResponseTimeThreshold;
    }

    @DataBoundSetter
    public void setErrorUnstableResponseTimeThreshold(String errorUnstableResponseTimeThreshold) {
        this.errorUnstableResponseTimeThreshold = errorUnstableResponseTimeThreshold;
    }

    public boolean isModePerformancePerTestCase() {
        return modePerformancePerTestCase;
    }

    @DataBoundSetter
    public void setModePerformancePerTestCase(boolean modePerformancePerTestCase) {
        this.modePerformancePerTestCase = modePerformancePerTestCase;
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public boolean isFailBuildIfNoResultFile() {
        return failBuildIfNoResultFile;
    }

    @DataBoundSetter
    public void setFailBuildIfNoResultFile(boolean failBuildIfNoResultFile) {
        this.failBuildIfNoResultFile = failBuildIfNoResultFile;
    }

    public boolean isART() {
        return configType.compareToIgnoreCase(PerformancePublisher.ART) == 0;
    }

    public boolean isMRT() {
        return configType.compareToIgnoreCase(PerformancePublisher.MRT) == 0;
    }

    public boolean isPRT() {
        return configType.compareToIgnoreCase(PerformancePublisher.PRT) == 0;
    }

    public static File[] getPerformanceReportDirectory(Run<?, ?> build, String parserDisplayName,
                                                       PrintStream logger) {
        File folder = new File(build.getRootDir(), PerformanceReportMap.getPerformanceReportFileRelativePath(parserDisplayName, ""));
        return folder.listFiles();
    }

    /**
     * Gets the Build object entered in the text box "Compare with nth Build"
     *
     * @param build, listener
     * @return build object
     */

    // @psingh5 -
    public Run<?, ?> getnthBuild(Run<?, ?> build) {
        Run<?, ?> nthBuild = build;

        int nextBuildNumber = build.number - nthBuildNumber;

        for (int i = 1; i <= nextBuildNumber; i++) {
            nthBuild = nthBuild.getPreviousBuild();
            if (nthBuild == null)
                return null;
        }
        return (nthBuildNumber == 0) ? null : nthBuild;
    }

    private List<File> getExistingReports(Run<?, ?> build, PrintStream logger, String parserDisplayName) {
        List<File> localReports = new ArrayList<>();
        final File[] localReport = getPerformanceReportDirectory(build, parserDisplayName, logger);

        for (int i = 0; i < localReport.length; i++) {

            String name = localReport[i].getName();
            String[] arr = name.split("\\.");

            // skip the serialized jmeter report file
            if (arr[arr.length - 1].equalsIgnoreCase("serialized"))
                continue;

            localReports.add(localReport[i]);
        }
        return localReports;
    }

    public double getRelativeFailedThresholdPositive() {
        return relativeFailedThresholdPositive;
    }

    public double getRelativeFailedThresholdNegative() {
        return relativeFailedThresholdNegative;
    }

    @DataBoundSetter
    public void setRelativeFailedThresholdPositive(double relativeFailedThresholdPositive) {
        this.relativeFailedThresholdPositive = relativeFailedThresholdPositive;
    }

    @DataBoundSetter
    public void setRelativeFailedThresholdNegative(double relativeFailedThresholdNegative) {
        this.relativeFailedThresholdNegative = relativeFailedThresholdNegative;
    }

    public double getRelativeUnstableThresholdPositive() {
        return relativeUnstableThresholdPositive;
    }

    public double getRelativeUnstableThresholdNegative() {
        return relativeUnstableThresholdNegative;
    }

    @DataBoundSetter
    public void setRelativeUnstableThresholdPositive(double relativeUnstableThresholdPositive) {
        this.relativeUnstableThresholdPositive = relativeUnstableThresholdPositive;
    }

    @DataBoundSetter
    public void setRelativeUnstableThresholdNegative(double relativeUnstableThresholdNegative) {
        this.relativeUnstableThresholdNegative = relativeUnstableThresholdNegative;
    }

    public int getNthBuildNumber() {
        return nthBuildNumber;
    }

    @DataBoundSetter
    public void setNthBuildNumber(int nthBuildNumber) {
        this.nthBuildNumber = Math.max(0, Math.min(nthBuildNumber, Integer.MAX_VALUE));
    }

    public String getConfigType() {
        return configType;
    }

    @DataBoundSetter
    public void setConfigType(String configType) {
        this.configType = configType;
    }

    public String getGraphType() {
        return graphType;
    }

    @DataBoundSetter
    public void setGraphType(String graphType) {
        this.graphType = graphType;
    }

    public boolean getModeOfThreshold() {
        return modeOfThreshold;
    }

    @DataBoundSetter
    public void setModeOfThreshold(boolean modeOfThreshold) {
        this.modeOfThreshold = modeOfThreshold;
    }

    public boolean getCompareBuildPrevious() {
        return compareBuildPrevious;
    }

    @DataBoundSetter
    public void setCompareBuildPrevious(boolean compareBuildPrevious) {
        this.compareBuildPrevious = compareBuildPrevious;
    }

    public boolean isModeThroughput() {
        return modeThroughput;
    }

    @DataBoundSetter
    public void setModeThroughput(boolean modeThroughput) {
        this.modeThroughput = modeThroughput;
    }

    public List<? extends AbstractConstraint> getConstraints() {
        return constraints;
    }

    @DataBoundSetter
    public void setConstraints(List<? extends AbstractConstraint> constraints) {
        this.constraints = constraints;
    }

    @DataBoundSetter
    public void setIgnoreFailedBuilds(boolean ignoreFailedBuilds) {
        this.ignoreFailedBuilds = ignoreFailedBuilds;
    }

    public boolean isIgnoreFailedBuilds() {
        return ignoreFailedBuilds;
    }

    @DataBoundSetter
    public void setIgnoreUnstableBuilds(boolean ignoreUnstableBuilds) {
        this.ignoreUnstableBuilds = ignoreUnstableBuilds;
    }

    public boolean isIgnoreUnstableBuilds() {
        return ignoreUnstableBuilds;
    }

    public boolean isPersistConstraintLog() {
        return persistConstraintLog;
    }

    @DataBoundSetter
    public void setPersistConstraintLog(boolean persistConstraintLog) {
        this.persistConstraintLog = persistConstraintLog;
    }

    public boolean isModeEvaluation() {
        return modeEvaluation;
    }

    @DataBoundSetter
    public void setModeEvaluation(boolean modeEvaluation) {
        this.modeEvaluation = modeEvaluation;
    }

    @DataBoundSetter
    public void setShowTrendGraphs(boolean showTrendGraphs) {
        this.showTrendGraphs = showTrendGraphs;
    }

    public boolean isShowTrendGraphs() {
        return showTrendGraphs;
    }

    public boolean getShowTrendGraphs() {
        return showTrendGraphs;
    }

    public String getSourceDataFiles() {
        return sourceDataFiles;
    }

    public void setSourceDataFiles(String sourceDataFiles) {
        this.sourceDataFiles = sourceDataFiles;
    }

    public List<PerformanceReportParser> getParsers() {
        return parsers;
    }

    @DataBoundSetter
    public void setParsers(List<PerformanceReportParser> parsers) {
        this.parsers = parsers;
        migrateParsers();
    }

    public boolean isExcludeResponseTime() {
        return excludeResponseTime;
    }

    @DataBoundSetter
    public void setExcludeResponseTime(boolean excludeResponseTime) {
        this.excludeResponseTime = excludeResponseTime;
    }

    public String getJunitOutput() {
        return junitOutput;
    }

    @DataBoundSetter
    public void setJunitOutput(String junitOutput) {
        this.junitOutput = junitOutput;
    }

    public String getPercentiles() {
        return percentiles;
    }

    @DataBoundSetter
    public void setPercentiles(String percentiles) {
        this.percentiles = percentiles;
    }


    public int getBaselineBuild() {
        return baselineBuild;
    }

    @DataBoundSetter
    public void setBaselineBuild(int baselineBuild) {
        this.baselineBuild = baselineBuild;
    }

    /**
     * Mapping classes after refactoring for backward compatibility.
     */
    @Initializer(before = InitMilestone.PLUGINS_STARTED)
    public static void addAliases() {
        // Items.XSTREAM2 is used for serializing project configuration,
        // and Run.XSTREAM2 is used for serializing build and its associated Actions.

        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceBuildAction", PerformanceBuildAction.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceProjectAction", PerformanceProjectAction.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.ExternalBuildReport", ExternalBuildReportAction.class);

        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.PreviousResultsBlock", PreviousResultsBlock.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.TestCaseBlock", TestCaseBlock.class);

        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.CookieHandler", CookieHandler.class);

        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.ConstraintSettings", ConstraintSettings.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.HttpSample", HttpSample.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceReportPosition", PerformanceReportPosition.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.TaurusStatusReport", TaurusFinalStats.class);

        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.ConstraintDescriptor", ConstraintDescriptor.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceReportParserDescriptor", PerformanceReportParserDescriptor.class);

        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.GraphConfigurationDetail", GraphConfigurationDetail.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.TestSuiteReportDetail", TestSuiteReportDetail.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.TrendReportDetail", TrendReportDetail.class);

        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.AbstractParser", AbstractParser.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.IagoParser", IagoParser.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.JMeterCsvParser", JMeterCsvParser.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.JMeterParser", JMeterParser.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.JmeterSummarizerParser", JmeterSummarizerParser.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.JUnitParser", JUnitParser.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceReportParser", PerformanceReportParser.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.TaurusParser", TaurusParser.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.WrkSummarizerParser", WrkSummarizerParser.class);

        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.reports.throughput.ThroughputReport", ThroughputReport.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.reports.ThroughputReport", ThroughputReport.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.AbstractReport", AbstractReport.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.ConstraintReport", ConstraintReport.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceReport", PerformanceReport.class);
        Items.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.UriReport", UriReport.class);

        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceBuildAction", PerformanceBuildAction.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceProjectAction", PerformanceProjectAction.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.ExternalBuildReport", ExternalBuildReportAction.class);

        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.PreviousResultsBlock", PreviousResultsBlock.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.TestCaseBlock", TestCaseBlock.class);

        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.CookieHandler", CookieHandler.class);

        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.ConstraintSettings", ConstraintSettings.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.HttpSample", HttpSample.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceReportPosition", PerformanceReportPosition.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.TaurusStatusReport", TaurusFinalStats.class);

        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.ConstraintDescriptor", ConstraintDescriptor.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceReportParserDescriptor", PerformanceReportParserDescriptor.class);

        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.GraphConfigurationDetail", GraphConfigurationDetail.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.TestSuiteReportDetail", TestSuiteReportDetail.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.TrendReportDetail", TrendReportDetail.class);

        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.AbstractParser", AbstractParser.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.IagoParser", IagoParser.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.JMeterCsvParser", JMeterCsvParser.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.JMeterParser", JMeterParser.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.JmeterSummarizerParser", JmeterSummarizerParser.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.JUnitParser", JUnitParser.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceReportParser", PerformanceReportParser.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.TaurusParser", TaurusParser.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.WrkSummarizerParser", WrkSummarizerParser.class);

        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.reports.throughput.ThroughputReport", ThroughputReport.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.reports.ThroughputReport", ThroughputReport.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.AbstractReport", AbstractReport.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.constraints.ConstraintReport", ConstraintReport.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.PerformanceReport", PerformanceReport.class);
        Run.XSTREAM2.addCompatibilityAlias("hudson.plugins.performance.UriReport", UriReport.class);
    }

    @Symbol({"perfReport", "performanceReport"})
    @Extension
    public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
        @Override
        public String getDisplayName() {
            return Messages.Publisher_DisplayName();
        }

        @Override
        public String getHelpFile() {
            return "/plugin/performance/help.html";
        }

        public List<PerformanceReportParserDescriptor> getParserDescriptors() {
            return PerformanceReportParserDescriptor.all();
        }

        public List<ConstraintDescriptor> getConstraintDescriptors() {
            return ConstraintDescriptor.all();
        }

        @Override
        public boolean isApplicable(Class<? extends AbstractProject> jobType) {
            return true;
        }

        /**
         * Populate the comparison type dynamically based on the user selection from
         * the previous time
         *
         * @return the name of the option selected in the previous run
         */
        public ListBoxModel doFillConfigTypeItems() {
            return getResponseTimeOptions();
        }

        public ListBoxModel doFillGraphTypeItems() {
            return getResponseTimeOptions();
        }

        private ListBoxModel getResponseTimeOptions() {
            ListBoxModel items = new ListBoxModel();
            items.add("Average Response Time", "ART");
            items.add("Median Response Time", "MRT");
            items.add("Percentile Response Time", "PRT");
            return items;
        }
    }

    /**
     * @return the filterRegex
     */
    public String getFilterRegex() {
        return filterRegex;
    }

    /**
     * @param filterRegex the filterRegex to set
     */
    @DataBoundSetter
    public void setFilterRegex(String filterRegex) {
        this.filterRegex = filterRegex;
    }
}



================================================
FILE: src/main/java/hudson/plugins/performance/PerformanceReportMap.java
================================================
package hudson.plugins.performance;

import hudson.model.AbstractProject;
import hudson.model.Describable;
import hudson.model.Job;
import hudson.model.ModelObject;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.plugins.performance.actions.PerformanceBuildAction;
import hudson.plugins.performance.actions.PerformanceProjectAction;
import hudson.plugins.performance.data.ReportValueSelector;
import hudson.plugins.performance.details.GraphConfigurationDetail;
import hudson.plugins.performance.parsers.JMeterParser;
import hudson.plugins.performance.parsers.PerformanceReportParser;
import hudson.plugins.performance.reports.AbstractReport;
import hudson.plugins.performance.reports.PerformanceReport;
import hudson.plugins.performance.data.PerformanceReportPosition;
import hudson.plugins.performance.reports.ThroughputReport;
import hudson.plugins.performance.reports.UriReport;
import hudson.util.ChartUtil;
import hudson.util.ChartUtil.NumberOnlyBuildLabel;
import hudson.util.DataSetBuilder;
import hudson.util.Graph;

import org.jfree.chart.JFreeChart;
import org.jfree.data.category.CategoryDataset;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * Root object of a performance report.
 */
public class PerformanceReportMap implements ModelObject {

    /**
     * The {@link PerformanceBuildAction} that this report belongs to.
     */
    private transient PerformanceBuildAction buildAction;
    /**
     * {@link PerformanceReport}s are keyed by
     * {@link PerformanceReport#reportFileName}
     * <p>
     * Test names are arbitrary human-readable and URL-safe string that identifies
     * an individual report.
     */
    private Map<String, PerformanceReport> performanceReportMap = new LinkedHashMap<>();
    private static final String PERFORMANCE_REPORTS_DIRECTORY = "performance-reports";
    private static final String PLUGIN_NAME = "performance";
    private static final String TRENDREPORT_LINK = "trendReport";

    public PerformanceReportMap(final PerformanceBuildAction buildAction,
                                TaskListener listener) throws IOException {
        this(buildAction, listener, true);
    }

    /**
     * Parses the reports and build a {@link PerformanceReportMap}.
     *
     * @throws IOException If a report fails to parse.
     */
    public PerformanceReportMap(final PerformanceBuildAction buildAction,
                         TaskListener listener, boolean isTopLevel) throws IOException {
        this.buildAction = buildAction;
        parseReports(getBuild(), listener, new PerformanceReportCollector() {

            public void addAll(Collection<PerformanceReport> reports) {
                for (PerformanceReport r : reports) {
                    r.setBuildAction(buildAction);
                    performanceReportMap.put(r.getReportFileName(), r);
                }
            }
        }, null);

        if (isTopLevel) {
            addPreviousBuildReports();
        }
    }



    private void addAll(Collection<PerformanceReport> reports) {
        for (PerformanceReport r : reports) {
            r.setBuildAction(buildAction);
            performanceReportMap.put(r.getReportFileName(), r);
        }
    }

    public Run<?, ?> getBuild() {
        return buildAction.getBuild();
    }

    PerformanceBuildAction getBuildAction() {
        return buildAction;
    }

    public String getDisplayName() {
        return Messages.Report_DisplayName();
    }

    public List<PerformanceReport> getPerformanceListOrdered() {
        List<PerformanceReport> listPerformance = new ArrayList<PerformanceReport>(
                getPerformanceReportMap().values());
        Collections.sort(listPerformance);
        return listPerformance;
    }

    protected PerformancePublisher getPublisher() {
        if (buildAction != null) {
            Run<?, ?> build = buildAction.getBuild();
            if (build != null) {
                Job<?, ?> job = build.getParent();
                if (job instanceof AbstractProject) {
                    AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;
                    Describable<?> describable = project.getPublishersList().get(PerformancePublisher.class);
                    return (describable != null) ? (PerformancePublisher) describable : null;
                }
            }
        }
        return null;
    }

    public boolean ifModeThroughputUsed() {
        PerformancePublisher publisher = getPublisher();
        return publisher == null || publisher.isModeThroughput();
    }

    public boolean ifShowTrendGraphsUsed() {
        PerformancePublisher publisher = getPublisher();
        return publisher == null || publisher.isShowTrendGraphs();
    }

    public boolean ifModePerformancePerTestCaseUsed() {
        PerformancePublisher publisher = getPublisher();
        return publisher == null || publisher.isModePerformancePerTestCase();
    }

    public Map<String, PerformanceReport> getPerformanceReportMap() {
        return performanceReportMap;
    }

    /**
     * <p>
     * Give the Performance report with the parameter for name in Bean
     * </p>
     *
     * @param performanceReportName
     * @return
     */
    public PerformanceReport getPerformanceReport(String performanceReportName) {
        return performanceReportMap.get(performanceReportName);
    }

    /**
     * Get a URI report within a Performance report file
     *
     * @param uriReport "Performance report file name";"URI name"
     * @return
     */
    public UriReport getUriReport(String uriReport) {
        if (uriReport != null) {
            String uriReportDecoded;
            try {
                uriReportDecoded = URLDecoder
                        .decode(uriReport.replace(UriReport.END_PERFORMANCE_PARAMETER, ""),
                                "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return null;
            }
            StringTokenizer st = new StringTokenizer(uriReportDecoded,
                    GraphConfigurationDetail.SEPARATOR);
            return getPerformanceReportMap().get(st.nextToken()).getUriReportMap()
                    .get(st.nextToken());
        } else {
            return null;
        }
    }

    public String getUrlName() {
        return PLUGIN_NAME;
    }

    public void setBuildAction(PerformanceBuildAction buildAction) {
        this.buildAction = buildAction;
    }

    public void setPerformanceReportMap(
            Map<String, PerformanceReport> performanceReportMap) {
        this.performanceReportMap = performanceReportMap;
    }

    public static String getPerformanceReportFileRelativePath(
            String parserDisplayName, String reportFileName) {
        return getRelativePath(parserDisplayName, reportFileName);
    }

    public static String getPerformanceReportDirRelativePath() {
        return getRelativePath();
    }

    private static String getRelativePath(String... suffixes) {
        StringBuilder sb = new StringBuilder(100);
        sb.append(PERFORMANCE_REPORTS_DIRECTORY);
        for (String suffix : suffixes) {
            sb.append(File.separator).append(suffix);
        }
        return sb.toString();
    }

    /**
     * <p>
     * Verify if the PerformanceReport exist the performanceReportName must to be
     * like it is in the build
     * </p>
     *
     * @param performanceReportName
     * @return boolean
     */
    public boolean isFailed(String performanceReportName) {
        return getPerformanceReport(performanceReportName) == null;
    }

    public void doRespondingTimeGraph(StaplerRequest request,
                                      StaplerResponse response) throws IOException {
        String parameter = request.getParameter("performanceReportPosition");
        Run<?, ?> previousBuild = getBuild();
        final Map<Run<?, ?>, Map<String, PerformanceReport>> buildReports = getBuildReports(parameter, previousBuild);
        // Now we should have the data necessary to generate the graphs!
        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<String, NumberOnlyBuildLabel>();
        ReportValueSelector valueSelector = ReportValueSelector.get(getBuild().getParent());
        String keyLabel = getKeyLabel(valueSelector.getGraphType());
        for (Map.Entry<Run<?, ?>, Map<String, PerformanceReport>> entry : buildReports.entrySet()) {
            NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(entry.getKey());
            PerformanceReport report = entry.getValue().get(parameter);
            dataSetBuilder.add(valueSelector.getValue(report),
                    keyLabel, label);
        }
        String legendLimit = request.getParameter("legendLimit");
        int limit = (legendLimit != null && !legendLimit.isEmpty()) ? Integer.parseInt(legendLimit) : Integer.MAX_VALUE;
        new Graph(-1, 400, 200) {
            @Override
            protected JFreeChart createGraph() {
                return createRespondingTimeChart(dataSetBuilder.build(), limit);
            }
        }.doPng(request, response);
    }

    public void doThroughputGraph(StaplerRequest request, StaplerResponse response) throws IOException {
        String parameter = request.getParameter("performanceReportPosition");
        if (parameter == null) {
            return;
        }

        if (ChartUtil.awtProblemCause != null) {
            // not available. send out error message
            response.sendRedirect2(request.getContextPath() + "/images/headless.png");
            return;
        }

        final DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<>();
        List<? extends Run<?, ?>> builds = buildAction.getBuild().getParent().getBuilds();

        for (final Run<?, ?> build : builds) {
                final PerformanceBuildAction performanceBuildAction = build.getAction(PerformanceBuildAction.class);
                if (performanceBuildAction == null) {
                    continue;
                }

                final PerformanceReport performanceReport = performanceBuildAction
                        .getPerformanceReportMap().getPerformanceReport(parameter);
                if (performanceReport == null) {
                    continue;
                }

                final ThroughputReport throughputReport = new ThroughputReport(performanceReport);
                final NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);
                dataSetBuilder.add(throughputReport.get(), Messages.ProjectAction_RequestsPerSeconds(), label);
        }

        new Graph(-1, 400, 200) {
            @Override
            protected JFreeChart createGraph() {
                return createThroughputChart((dataSetBuilder.build()));
            }
        }.doPng(request, response);
    }

    protected JFreeChart createThroughputChart(CategoryDataset dataset) {
        return PerformanceProjectAction.createThroughputChart(dataset);
    }


    public void doRespondingTimeGraphPerTestCaseMode(
            StaplerRequest request, StaplerResponse response) throws IOException {
        final String performanceReportNameFile = request.getParameter("performanceReportPosition");
        if (performanceReportNameFile == null) {
            return;
        }

        if (ChartUtil.awtProblemCause != null) {
            // not available. send out error message
            response.sendRedirect2(request.getContextPath() + "/images/headless.png");
            return;
        }

        final DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<>();
        List<? extends Run<?, ?>> builds = buildAction.getBuild().getParent().getBuilds();

        ReportValueSelector valueSelector = ReportValueSelector.get(getPublisher());


        for (Run<?, ?> build : builds) {
                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);

            final PerformanceBuildAction performanceBuildAction = build.getAction(PerformanceBuildAction.class);
            if (performanceBuildAction == null) {
                continue;
            }

            final PerformanceReport performanceReport = performanceBuildAction
                    .getPerformanceReportMap().getPerformanceReport(performanceReportNameFile);
            if (performanceReport == null) {
                continue;
            }

            List<UriReport> uriListOrdered = performanceReport.getUriListOrdered();
            for (UriReport uriReport : uriListOrdered) {
                dataSetBuilder.add(valueSelector.getValue(uriReport), uriReport.getUri(), label);
            }
        }

        String legendLimit = request.getParameter("legendLimit");
        int limit = (legendLimit != null && !legendLimit.isEmpty()) ? Integer.parseInt(legendLimit) : Integer.MAX_VALUE;
        new Graph(-1, 600, 200) {
            @Override
            protected JFreeChart createGraph() {
                return createRespondingTimeChart(dataSetBuilder.build(), limit);
            }
        }.doPng(request, response);
    }

    public void doErrorsGraph(StaplerRequest request, StaplerResponse response)
            throws IOException {
        final String performanceReportNameFile = request.getParameter("performanceReportPosition");
        if (performanceReportNameFile == null) {
            return;
        }

        if (ChartUtil.awtProblemCause != null) {
            // not available. send out error message
            response.sendRedirect2(request.getContextPath() + "/images/headless.png");
            return;
        }
        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilderErrors = new DataSetBuilder<String, NumberOnlyBuildLabel>();
        List<? extends Run<?, ?>> builds = buildAction.getBuild().getParent().getBuilds();

        for (Run<?, ?> currentBuild : builds) {
                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(currentBuild);
                PerformanceBuildAction performanceBuildAction = currentBuild
                        .getAction(PerformanceBuildAction.class);

                if (performanceBuildAction == null) {
                    continue;
                }
                PerformanceReport performanceReport = performanceBuildAction
                        .getPerformanceReportMap().getPerformanceReport(
                                performanceReportNameFile);
                if (performanceReport == null) {
                    continue;
                }

                dataSetBuilderErrors.add(performanceReport.errorPercent(),
                        Messages.ProjectAction_Errors(), label);
        }
        new Graph(-1, 400, 200) {
            @Override
            protected JFreeChart createGraph() {
                return createErrorsChart(dataSetBuilderErrors.build());
            }
        }.doPng(request, response);
    }

    protected JFreeChart createErrorsChart(CategoryDataset dataset) {
        return PerformanceProjectAction.createErrorsChart(dataset);
    }


    protected JFreeChart createRespondingTimeChart(CategoryDataset dataset, int legendLimit) {
        return PerformanceProjectAction.doCreateRespondingTimeChart(dataset, legendLimit);
    }

    private String getKeyLabel(String configType) {
        if (configType.equals(PerformancePublisher.MRT))
            return Messages.ProjectAction_Median();
        if (configType.equals(PerformancePublisher.PRT))
            return Messages.ProjectAction_Line90();
        return Messages.ProjectAction_Average();
    }

    private Map<Run<?, ?>, Map<String, PerformanceReport>> getBuildReports(String parameter, Run<?, ?> previousBuild) throws IOException {
        final Map<Run<?, ?>, Map<String, PerformanceReport>> buildReports = new LinkedHashMap<Run<?, ?>, Map<String, PerformanceReport>>();
        while (previousBuild != null) {
            final Run<?, ?> currentBuild = previousBuild;
            parseReports(currentBuild, TaskListener.NULL,
                    new PerformanceReportCollector() {

                        public void addAll(Collection<PerformanceReport> parse) {
                            for (PerformanceReport performanceReport : parse) {
                                if (buildReports.get(currentBuild) == null) {
                                    Map<String, PerformanceReport> map = new LinkedHashMap<String, PerformanceReport>();
                                    buildReports.put(currentBuild, map);
                                }
                                buildReports.get(currentBuild).put(
                                        performanceReport.getReportFileName(), performanceReport);
                            }
                        }
                    }, parameter);
            previousBuild = previousBuild.getPreviousCompletedBuild();
        }

        return buildReports;
    }

    public void doSummarizerGraph(StaplerRequest request, StaplerResponse response)
            throws IOException {
        String parameter = request.getParameter("performanceReportPosition");
        Run<?, ?> previousBuild = getBuild();
        Map<Run<?, ?>, Map<String, PerformanceReport>> buildReports = getBuildReports(parameter, previousBuild);
        DataSetBuilder<NumberOnlyBuildLabel, String> dataSetBuilderSummarizer = new DataSetBuilder<NumberOnlyBuildLabel, String>();
        ReportValueSelector valueSelector = ReportValueSelector.get(getBuild().getParent());
        for (Map.Entry<Run<?, ?>, Map<String, PerformanceReport>> entry : buildReports.entrySet()) {
            NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(entry.getKey());
            PerformanceReport report = entry.getValue().get(parameter);

            // Now we should have the data necessary to generate the graphs!
            for (Map.Entry<String, UriReport> secondEntry : report.getUriReportMap().entrySet()) {
                long methodValue = valueSelector.getValue(secondEntry.getValue());
                dataSetBuilderSummarizer.add(methodValue, label, secondEntry.getKey());
            }
        }

        new Graph(-1, 400, 200) {
            @Override
            protected JFreeChart createGraph() {
                return createSummarizerChart(dataSetBuilderSummarizer.build());
            }
        }.doPng(request, response);
    }

    protected JFreeChart createSummarizerChart(CategoryDataset dataset) {
        return PerformanceProjectAction.doCreateSummarizerChart(dataset, "ms", Messages.ProjectAction_RespondingTime());
    }

    protected void parseReports(Run<?, ?> build, TaskListener listener,
                              PerformanceReportCollector collector, final String filename)
            throws IOException {
        File repo = new File(build.getRootDir(),
                PerformanceReportMap.getPerformanceReportDirRelativePath());

        // files directly under the directory are for JMeter, for compatibility
        // reasons.
        File[] files = repo.listFiles(new FileFilter() {

            public boolean accept(File f) {
                return !f.isDirectory() && !f.getName().endsWith(".serialized");
            }
        });
        // this may fail, if the build itself failed, we need to recover gracefully
        if (files != null) {
            addAll(new JMeterParser("", AbstractReport.DEFAULT_PERCENTILES).parse(build, Arrays.asList(files), listener));
        }

        // otherwise subdirectory name designates the parser ID.
        File[] dirs = repo.listFiles(new FileFilter() {

            public boolean accept(File f) {
                return f.isDirectory();
            }
        });
        // this may fail, if the build itself failed, we need to recover gracefully
        if (dirs != null) {
            for (File dir : dirs) {
                PerformanceReportParser p = buildAction.getParserByDisplayName(dir
                        .getName());
                if (p != null) {
                    File[] listFiles = dir.listFiles(new FilenameFilter() {

                        public boolean accept(File dir, String name) {
                            if (filename == null && !name.endsWith(".serialized")) {
                                return true;
                            }
                            if (name.equals(filename)) {
                                return true;
                            }
                            return false;
                        }
                    });
                    if (listener != null && listener.getLogger() != null) {
                        try {
                            collector.addAll(p.parse(build, Arrays.asList(listFiles), listener));
                        } catch (IOException ex) {
                            listener.getLogger().println("Unable to process directory '" + dir + "'.");
                            ex.printStackTrace(listener.getLogger());
                        }
                    } else {
                        // Handle the situation when listener or its logger is null
                    }
                }
            }
        }

        //addPreviousBuildReports();
    }

    private void addPreviousBuildReports() {
        for (Map.Entry<String, PerformanceReport> item : getPerformanceReportMap().entrySet()) {
            PerformanceReport curReport = item.getValue();
            int baselineBuild = curReport.getBaselineBuild();
            PerformanceReport reportForCompare = (baselineBuild == 0) ?
                    getPerformanceReportForBuild(getBuild().getPreviousCompletedBuild(), item.getKey()) :
                    getPerformanceReportForBuild(getBuild(baselineBuild), item.getKey());
            if (reportForCompare != null) {
                curReport.setLastBuildReport(reportForCompare);
            }
        }
    }

    protected PerformanceReportMap getReportMap(Run<?, ?> build) {
        if (build == null) {
            return null;
        }

        PerformanceBuildAction action = build.getAction(PerformanceBuildAction.class);
        if (action == null) {
            return null;
        }

        return action.getPerformanceReportMap(false);
    }

    protected PerformanceReport getPerformanceReportForBuild(Run<?, ?> build, String key) {
        PerformanceReportMap reportMap = getReportMap(build);
        if (reportMap == null) {
            return null;
        }

        return reportMap.getPerformanceReportMap().get(key);
    }

    protected Run<?, ?> getBuild(int buildNumber) {
        Run<?, ?> r = getBuild();
        while (r != null && buildNumber != r.getNumber()) {
            r = r.getPreviousBuild();
        }
        return r;
    }

    protected interface PerformanceReportCollector {

        void addAll(Collection<PerformanceReport> parse);
    }

    public Object getDynamic(final String link, final StaplerRequest request,
                             final StaplerRequest response) {
        if (TRENDREPORT_LINK.equals(link)) {
            return createTrendReportGraphs(request);
        } else {
            return null;
        }
    }

    public Object createTrendReportGraphs(final StaplerRequest request) {
        String filename = getTrendReportFilename(request);
        PerformanceReport report = performanceReportMap.get(filename);
        Run<?, ?> build = getBuild();
        if (build == null) {
            // Handle the situation when build is null
            return null;
        }

        TrendReportGraphs trendReport = new TrendReportGraphs(build.getParent(),
                build, request, filename, report);

        return trendReport;
    }

    private String getTrendReportFilename(final StaplerRequest request) {
        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();
        request.bindParameters(performanceReportPosition);
        return performanceReportPosition.getPerformanceReportPosition();
    }
}


================================================
FILE: src/main/java/hudson/plugins/performance/TrendReportGraphs.java
================================================
package hudson.plugins.performance;

import hudson.model.Job;
import hudson.model.ModelObject;
import hudson.model.Run;
import hudson.plugins.performance.actions.PerformanceBuildAction;
import hudson.plugins.performance.reports.PerformanceReport;
import hudson.plugins.performance.data.PerformanceReportPosition;
import hudson.plugins.performance.reports.UriReport;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import java.io.IOException;
import java.util.ArrayList;

public class TrendReportGraphs implements ModelObject {

    private Run<?, ?> build;
    private String filename;
    private PerformanceReport performanceReport;
    private Job<?, ?> project;

    public TrendReportGraphs(final Job<?, ?> project,
                             final Run<?, ?> build, final StaplerRequest request,
                             String filename, PerformanceReport performanceReport) {
        this.build = build;
        this.filename = filename;
        this.performanceReport = performanceReport;
        this.project = project;
    }

    private UriReport getUriReportForRequest(StaplerRequest request) {

        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();
        request.bindParameters(performanceReportPosition);

        PerformanceBuildAction performanceBuildAction = build
                .getAction(PerformanceBuildAction.class);

        if (performanceBuildAction != null && performanceReport != null) {
            String uri = performanceReportPosition.getSummarizerTrendUri();
            if (uri != null) {
                return performanceReport.getUriReportMap().get(uri);
            }
        }
        return null;
    }

    public void doRespondingTimeGraph(StaplerRequest request,
                                      StaplerResponse response) throws IOException {
        UriReport uriReport = getUriReportForRequest(request);
        if (uriReport != null) {
            uriReport.doSummarizerTrendGraph(request, response);
        }
    }

    public void doPercentileGraph(StaplerRequest request,
                                  StaplerResponse response) throws IOException {
        UriReport uriReport = getUriReportForRequest(request);
        if (uriReport != null) {
            uriReport.doPercentileGraph(request, response);
        }
    }

    public void doThroughputGraph(StaplerRequest request,
                                  StaplerResponse response) throws IOException {
        UriReport uriReport = getUriReportForRequest(request);
        if (uriReport != null) {
            uriReport.doThroughputGraph(request, response);
        }
    }

    public void doErrorGraph(StaplerRequest request,
                                  StaplerResponse response) throws IOException {
        UriReport uriReport = getUriReportForRequest(request);
        if (uriReport != null) {
            uriReport.doErrorGraph(request, response);
        }
    }

    public ArrayList<String> getUris() {
        ArrayList<String> uriList = new ArrayList<>();
        PerformanceReport report = getPerformanceReport();

        if (report != null) {
            uriList.addAll(report.getUriReportMap().keySet());
        }
        return uriList;
    }

    public UriReport getUriReport(String uri) {
        if (performanceReport != null) {
            return performanceReport.getUriReportMap().get(uri);
        } else {
            return build.getAction(PerformanceBuildAction.class)
                    .getPerformanceReportMap().getUriReport(uri);
        }
    }

    public String getDisplayName() {
        return Messages.TrendReportDetail_DisplayName();
    }

    public String getFilename() {
        return filename;
    }

    public Job<?, ?> getProject() {
        return project;
    }

    public Run<?, ?> getBuild() {
        return build;
    }

    public boolean hasSamples(String uri) {
        UriReport report = getUriReport(uri);
        return report != null && report.hasSamples();
    }

    public PerformanceReport getPerformanceReport() {
        return performanceReport;
    }

}

================================================
FILE: src/main/java/hudson/plugins/performance/actions/ExternalBuildReportAction.java
================================================
package hudson.plugins.performance.actions;


import hudson.model.Action;
import org.kohsuke.stapler.StaplerProxy;

public class ExternalBuildReportAction implements Action, StaplerProxy {
    private final String reportURL;

    public ExternalBuildReportAction(String reportURL) {
        this.reportURL = reportURL;
    }

    @Override
    public String getIconFileName() {
        return "graph.gif";
    }

    @Override
    public String getDisplayName() {
        return "View External Report";
    }

    @Override
    public String getUrlName() {
        return reportURL;
    }

    @Override
    public Object getTarget() {
        return null;
    }

}


================================================
FILE: src/main/java/hudson/plugins/performance/actions/PerformanceBuildAction.java
================================================
package hudson.plugins.performance.actions;

import hudson.model.Action;
import hudson.model.Run;
import hudson.plugins.performance.Messages;
import hudson.plugins.performance.PerformanceReportMap;
import hudson.plugins.performance.parsers.PerformanceReportParser;
import hudson.util.StreamTaskListener;
import org.kohsuke.stapler.StaplerProxy;

import java.io.IOException;
import java.io.PrintStream;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PerformanceBuildAction implements Action, StaplerProxy {
    private final Run<?, ?> build;

    /**
     * Configured parsers used to parse reports in this build.
     * For compatibility reasons, this can be null.
     */
    private final List<PerformanceReportParser> parsers;

    private transient final PrintStream hudsonConsoleWriter;

    private transient WeakReference<PerformanceReportMap> performanceReportMap;

    private static final Logger logger = Logger.getLogger(PerformanceBuildAction.class.getName());


    public PerformanceBuildAction(Run<?, ?> pBuild, PrintStream logger,
                                  List<PerformanceReportParser> parsers) {
        build = pBuild;
        hudsonConsoleWriter = logger;
        this.parsers = parsers;
    }

    public PerformanceReportParser getParserByDisplayName(String displayName) {
        if (parsers != null)
            for (PerformanceReportParser parser : parsers)
                if (parser.getDescriptor().getDisplayName().equals(displayName))
                    return parser;
        return null;
    }

    public String getDisplayName() {
        return Messages.BuildAction_DisplayName();
    }

    public String getIconFileName() {
        return "graph.gif";
    }

    public String getUrlName() {
        return "performance";
    }

    public PerformanceReportMap getTarget() {
        return getPerformanceReportMap(true);
    }

    public Run<?, ?> getBuild() {
        return build;
    }

    public PrintStream getHudsonConsoleWriter() {
        return hudsonConsoleWriter;
    }

    public synchronized PerformanceReportMap getPerformanceReportMap() {
        return getPerformanceReportMap(true);
    }

    public synchronized PerformanceReportMap getPerformanceReportMap(boolean isInitNextLevel) {
        PerformanceReportMap reportMap = null;
        synchronized(this) {
            WeakReference<PerformanceReportMap> wr = this.performanceReportMap;
            if (wr != null) {
                reportMap = wr.get();
                if (reportMap != null) {
                    return reportMap;
                }
            }
        }
        try {
            reportMap = new PerformanceReportMap(this, StreamTaskListener.fromStderr(), isInitNextLevel);
        } catch (IOException e) {
            logger.log(Level.SEVERE, "Error creating new PerformanceReportMap()", e);
        }
        this.performanceReportMap = new WeakReference<>(reportMap);
        return reportMap;
    }

    public synchronized void setPerformanceReportMap(WeakReference<PerformanceReportMap> performanceReportMap) {
        synchronized(this) {
            this.performanceReportMap = performanceReportMap;
        }
    }
}


================================================
FILE: src/main/java/hudson/plugins/performance/actions/PerformanceProjectAction.java
================================================
package hudson.plugins.performance.actions;

import java.awt.BasicStroke;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.chart.renderer.xy.XYDotRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.xy.IntervalXYDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.FilePath;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.Job;
import hudson.model.Run;
import hudson.plugins.performance.Messages;
import hudson.plugins.performance.PerformancePublisher;
import hudson.plugins.performance.PerformanceReportMap;
import hudson.plugins.performance.data.PerformanceReportPosition;
import hudson.plugins.performance.data.ReportValueSelector;
import hudson.plugins.performance.details.GraphConfigurationDetail;
import hudson.plugins.performance.details.TestSuiteReportDetail;
import hudson.plugins.performance.details.TrendReportDetail;
import hudson.plugins.performance.reports.PerformanceReport;
import hudson.plugins.performance.reports.ThroughputReport;
import hudson.plugins.performance.reports.UriReport;
import hudson.util.ChartUtil;
import hudson.util.ChartUtil.NumberOnlyBuildLabel;
import hudson.util.ColorPalette;
import hudson.util.DataSetBuilder;
import hudson.util.Graph;
import hudson.util.ShiftedCategoryAxis;

public class PerformanceProjectAction implements Action {

    private static final String CONFIGURE_LINK = "configure";
    private static final String TRENDREPORT_LINK = "trendReport";
    private static final String TESTSUITE_LINK = "testsuiteReport";

    private static final String PLUGIN_NAME = "performance";

    @SuppressWarnings("unused")
    private static final long serialVersionUID = 1L;

    /**
     * Logger.
     */
    private static final Logger LOGGER = Logger
            .getLogger(PerformanceProjectAction.class.getName());

    public final Job<?, ?> job;

    private List<String> performanceReportList;

    public String getDisplayName() {
        return Messages.ProjectAction_DisplayName();
    }

    public String getIconFileName() {
        return "graph.gif";
    }

    public String getUrlName() {
        return PLUGIN_NAME;
    }

    public PerformanceProjectAction(Job<?, ?> job) {
        this.job = job;
    }

    public static JFreeChart createErrorsChart(CategoryDataset dataset) {

        final JFreeChart chart = ChartFactory.createLineChart(
                Messages.ProjectAction_PercentageOfErrors(), // chart title
                null, // unused
                "%", // range axis label
                dataset, // data
                PlotOrientation.VERTICAL, // orientation
                true, // include legend
                true, // tooltips
                false // urls
        );

        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...

        final LegendTitle legend = chart.getLegend();
        legend.setPosition(RectangleEdge.BOTTOM);

        chart.setBackgroundPaint(Color.WHITE);

        final CategoryPlot plot = chart.getCategoryPlot();

        // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
        plot.setBackgroundPaint(Color.WHITE);
        plot.setOutlinePaint(null);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.BLACK);

        CategoryAxis domainAxis = new ShiftedCategoryAxis(null);
        plot.setDomainAxis(domainAxis);
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
        domainAxis.setLowerMargin(0.0);
        domainAxis.setUpperMargin(0.0);
        domainAxis.setCategoryMargin(0.0);

        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        rangeAxis.setUpperBound(100);
        rangeAxis.setLowerBound(0);

        final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot
                .getRenderer();
        renderer.setBaseStroke(new BasicStroke(4.0f));
        ColorPalette.apply(renderer);

        // crop extra space around the graph
        plot.setInsets(new RectangleInsets(5.0, 0, 0, 5.0));

        return chart;
    }

    public static JFreeChart doCreateRespondingTimeChart(CategoryDataset dataset, int legendLimit) {

        final JFreeChart chart = ChartFactory.createLineChart(
                Messages.ProjectAction_RespondingTime(), // charttitle
                null, // unused
                "ms", // range axis label
                dataset, // data
                PlotOrientation.VERTICAL, // orientation
                true, // include legend
                true, // tooltips
                false // urls
        );
        final LegendTitle legend = chart.getLegend();
        legend.setPosition(RectangleEdge.BOTTOM);
        if (dataset.getRowCount() > legendLimit) {
            chart.removeLegend();
        }

        chart.setBackgroundPaint(Color.WHITE);

        final CategoryPlot plot = chart.getCategoryPlot();

        // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
        plot.setBackgroundPaint(Color.WHITE);
        plot.setOutlinePaint(null);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.BLACK);

        CategoryAxis domainAxis = new ShiftedCategoryAxis(null);
        plot.setDomainAxis(domainAxis);
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
        domainAxis.setLowerMargin(0.0);
        domainAxis.setUpperMargin(0.0);
        domainAxis.setCategoryMargin(0.0);

        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

        final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot
                .getRenderer();
        renderer.setBaseStroke(new BasicStroke(4.0f));
        ColorPalette.apply(renderer);

        // crop extra space around the graph
        plot.setInsets(new RectangleInsets(5.0, 0, 0, 5.0));

        return chart;
    }

    public static JFreeChart createThroughputChart(final CategoryDataset dataset) {

        final JFreeChart chart = ChartFactory.createLineChart(
                Messages.ProjectAction_Throughput(), // chart title
                null, // unused
                Messages.ProjectAction_RequestsPerSeconds(), // range axis label
                dataset, // data
                PlotOrientation.VERTICAL, // orientation
                true, // include legend
                true, // tooltips
                false // urls
        );

        final LegendTitle legend = chart.getLegend();
        legend.setPosition(RectangleEdge.BOTTOM);

        chart.setBackgroundPaint(Color.WHITE);

        final CategoryPlot plot = chart.getCategoryPlot();

        plot.setBackgroundPaint(Color.WHITE);
        plot.setOutlinePaint(null);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.BLACK);

        CategoryAxis domainAxis = new ShiftedCategoryAxis(null);
        plot.setDomainAxis(domainAxis);
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
        domainAxis.setLowerMargin(0.0);
        domainAxis.setUpperMargin(0.0);
        domainAxis.setCategoryMargin(0.0);

        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

        final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
        renderer.setBaseStroke(new BasicStroke(4.0f));
        ColorPalette.apply(renderer);

        // crop extra space around the graph
        plot.setInsets(new RectangleInsets(5.0, 0, 0, 5.0));

        return chart;
    }

    public static JFreeChart doCreateSummarizerChart(CategoryDataset dataset,
                                                     String yAxis, String chartTitle) {

        final JFreeChart chart = ChartFactory.createBarChart(chartTitle, // chart
                // title
                null, // unused
                yAxis, // range axis label
                dataset, // data
                PlotOrientation.VERTICAL, // orientation
                true, // include legend
                true, // tooltips
                true // urls
        );

        chart.setBackgroundPaint(Color.WHITE);

        final CategoryPlot plot = chart.getCategoryPlot();

        plot.setBackgroundPaint(Color.WHITE);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.BLACK);

        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);

        final BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setDrawBarOutline(false);
        renderer.setBaseStroke(new BasicStroke(4.0f));
        renderer.setItemMargin(0);
        renderer.setMaximumBarWidth(0.05);

        return chart;
    }

    public static JFreeChart createSummarizerTrend(
            ArrayList<XYDataset> dataset, String uri) {

        final JFreeChart chart = ChartFactory.createTimeSeriesChart(uri, Messages.TrendReportDetail_Time(),
                Messages.TrendReportDetail_ResponseTime(), dataset.get(0), true, true, false);
        chart.setBackgroundPaint(Color.WHITE);

        final XYPlot plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.WHITE);
        plot.setDomainGridlinePaint(Color.BLACK);
        plot.setRangeGridlinePaint(Color.BLACK);

        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(true);

        /*
         * final NumberAxis axis2 = new NumberAxis("Errors"); axis2.isAutoRange();
         * axis2.setLowerBound(0); plot.setRangeAxis(1, axis2); plot.setDataset(1,
         * dataset.get(1)); plot.mapDatasetToRangeAxis(1, 1);
         *
         * final StandardXYItemRenderer renderer2 = new StandardXYItemRenderer();
         * renderer2.setSeriesPaint(0, Color.black); plot.setRenderer(1, renderer2);
         */
        final DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setDateFormatOverride(new SimpleDateFormat("HH:mm:ss"));

        final XYDotRenderer renderer = new XYDotRenderer(); // scatter plot
        plot.setRenderer(renderer);
        renderer.setDotWidth(2);
        renderer.setDotHeight(2);
        renderer.setSeriesPaint(0, ColorPalette.RED);

        return chart;
    }

    public static JFreeChart createUriPercentileChart(XYDataset dataset, String uri) {
        final JFreeChart chart = ChartFactory.createXYLineChart(uri, Messages.TrendReportDetail_Percent(),
                Messages.TrendReportDetail_ResponseTime(), dataset,
                PlotOrientation.VERTICAL, true, true, false);
        chart.setBackgroundPaint(Color.WHITE);

        final XYPlot plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.WHITE);
        plot.setDomainGridlinePaint(Color.BLACK);
        plot.setRangeGridlinePaint(Color.BLACK);

        // Exclude zeroes to make sure y-axis aligns with response time auto range:
        final NumberAxis yaxis = (NumberAxis) plot.getRangeAxis();
        yaxis.setAutoRange(true);
        yaxis.setAutoRangeIncludesZero(false);

        final NumberAxis xaxis = (NumberAxis) plot.getDomainAxis();
        xaxis.setRange(0, 100); // avoid auto margin

        final XYItemRenderer renderer = plot.getRenderer();
        renderer.setSeriesPaint(0, ColorPalette.RED);

        return chart;
    }

    public static JFreeChart createUriThroughputChart(IntervalXYDataset dataset, String uri) {
        final JFreeChart chart = ChartFactory.createXYBarChart(uri, Messages.TrendReportDetail_Time(), true,
                Messages.TrendReportDetail_RequestsPerMinute(), dataset,
                PlotOrientation.VERTICAL, true, true, false);
        chart.setBackgroundPaint(Color.WHITE);

        final XYPlot plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.WHITE);
        plot.setDomainGridlinePaint(Color.BLACK);
        plot.setRangeGridlinePaint(Color.BLACK);

        final DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setDateFormatOverride(new SimpleDateFormat("HH:mm:ss"));

        final XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer();
        // As of Jenkins v2.198 jfreechart v1.0.19 paints bars with a gradient by
        // default
        // which can't be turned off in v1.0.9 the plugin is compiled against
        // so instead use a red outline and fill with white:
        renderer.setSeriesPaint(0, Color.WHITE);
        renderer.setDrawBarOutline(true);
        renderer.setSeriesOutlinePaint(0, ColorPalette.RED);

        return chart;
    }

    private String getPerformanceReportNameFile(StaplerRequest request) {
        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();
        request.bindParameters(performanceReportPosition);
        return getPerformanceReportNameFile(performanceReportPosition);
    }

    private String getPerformanceReportNameFile(final PerformanceReportPosition performanceReportPosition) {
        String performanceReportNameFile = performanceReportPosition.getPerformanceReportPosition();
        if (performanceReportNameFile == null && getPerformanceReportList().size() == 1) {
            performanceReportNameFile = getPerformanceReportList().get(0);
        }
        return performanceReportNameFile;
    }

    public void doErrorsGraph(StaplerRequest request, StaplerResponse response)
            throws IOException {
        final String performanceReportNameFile = getPerformanceReportNameFile(request);
        if (performanceReportNameFile == null) {
            return;
        }

        if (ChartUtil.awtProblemCause != null) {
            // not available. send out error message
            response.sendRedirect2(request.getContextPath() + "/images/headless.png");
            return;
        }
        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilderErrors = new DataSetBuilder<>();
        List<? extends Run<?, ?>> builds = getJob().getBuilds();
        Range buildsLimits = getFirstAndLastBuild(request, builds);

        int nbBuildsToAnalyze = builds.size();
        for (Run<?, ?> currentBuild : builds) {
            if (buildsLimits.in(nbBuildsToAnalyze)) {

                if (!buildsLimits.includedByStep(currentBuild.number)) {
                    continue;
                }

                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(currentBuild);
                PerformanceBuildAction performanceBuildAction = currentBuild
                        .getAction(PerformanceBuildAction.class);
                if (performanceBuildAction == null) {
                    continue;
                }
                PerformanceReport performanceReport = performanceBuildAction
                        .getPerformanceReportMap().getPerformanceReport(
                                performanceReportNameFile);
                if (performanceReport == null) {
                    nbBuildsToAnalyze--;
                    continue;
                }
                dataSetBuilderErrors.add(performanceReport.errorPercent(),
                        Messages.ProjectAction_Errors(), label);
            }
            nbBuildsToAnalyze--;
        }

        new Graph(-1, 400, 200) {
            @Override
            protected JFreeChart createGraph() {
                return createErrorsGraph(dataSetBuilderErrors.build());
            }
        }.doPng(request, response);
    }

    protected JFreeChart createErrorsGraph(CategoryDataset dataset) {
        return createErrorsChart(dataset);
    }

    public void doRespondingTimeGraphPerTestCaseMode(
            StaplerRequest request, StaplerResponse response) throws IOException {
        final String performanceReportNameFile = getPerformanceReportNameFile(request);
        if (performanceReportNameFile == null) {
            return;
        }

        if (ChartUtil.awtProblemCause != null) {
            // not available. send out error message
            response.sendRedirect2(request.getContextPath() + "/images/headless.png");
            return;
        }
        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<>();
        ReportValueSelector valueSelector = ReportValueSelector.get(getJob());
        List<? extends Run<?, ?>> builds = getJob().getBuilds();
        Range buildsLimits = getFirstAndLastBuild(request, builds);

        int nbBuildsToAnalyze = builds.size();

        for (Run<?, ?> build : builds) {
            if (buildsLimits.in(nbBuildsToAnalyze)) {
                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);

                if (!buildsLimits.includedByStep(build.number)) {
                    continue;
                }
                PerformanceReport performanceReport = getPerformanceReport(build, performanceReportNameFile);
                if (performanceReport == null) {
                    nbBuildsToAnalyze--;
                    continue;
                }

                List<UriReport> uriListOrdered = performanceReport.getUriListOrdered();
                for (UriReport uriReport : uriListOrdered) {
                    dataSetBuilder.add(valueSelector.getValue(uriReport), uriReport.getUri(), label);
                }
            }
            nbBuildsToAnalyze--;
        }
        String legendLimit = request.getParameter("legendLimit");
        int limit = (legendLimit != null && !legendLimit.isEmpty()) ? Integer.parseInt(legendLimit) : Integer.MAX_VALUE;

        new Graph(-1, 600, 200) {
            @Override
            protected JFreeChart createGraph() {
                return createRespondingTimeChart(dataSetBuilder.build(), limit);
            }
        }.doPng(request, response);
    }

    protected PerformanceReport getPerformanceReport(Run<?, ?> build, String reportFileName) {
        PerformanceBuildAction performanceBuildAction = build.getAction(PerformanceBuildAction.class);
        if (performanceBuildAction == null) {
            return null;
        }
        return performanceBuildAction
                .getPerformanceReportMap()
                .getPerformanceReport(reportFileName);
    }

    protected JFreeChart createRespondingTimeChart(CategoryDataset dataset, int legendLimit) {
        return doCreateRespondingTimeChart(dataset, legendLimit);
    }

    public void doRespondingTimeGraph(StaplerRequest request, StaplerResponse response) throws IOException {
        final String performanceReportNameFile = getPerformanceReportNameFile(request);
        if (performanceReportNameFile == null) {
            return;
        }

        if (ChartUtil.awtProblemCause != null) {
            // not available. send out error message
            response.sendRedirect2(request.getContextPath() + "/images/headless.png");
            return;
        }
        DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilderAverage = new DataSetBuilder<>();
        List<? extends Run<?, ?>> builds = getJob().getBuilds();
        Range buildsLimits = getFirstAndLastBuild(request, builds);

        int nbBuildsToAnalyze = builds.size();
        for (Run<?, ?> build : builds) {
            if (buildsLimits.in(nbBuildsToAnalyze)) {

                if (!buildsLimits.includedByStep(build.number)) {
                    continue;
                }

                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);
                PerformanceBuildAction performanceBuildAction = build
                        .getAction(PerformanceBuildAction.class);
                if (performanceBuildAction == null) {
                    continue;
                }
                PerformanceReport performanceReport = performanceBuildAction
                        .getPerformanceReportMap().getPerformanceReport(
                                performanceReportNameFile);
                if (performanceReport == null) {
                    nbBuildsToAnalyze--;
                    continue;
                }
                dataSetBuilderAverage.add(performanceReport.getMedian(),
                        Messages.ProjectAction_Median(), label);
                dataSetBuilderAverage.add(performanceReport.getAverage(),
                        Messages.ProjectAction_Average(), label);
                dataSetBuilderAverage.add(performanceReport.get90Line(),
                        Messages.ProjectAction_Line90(), label);
                dataSetBuilderAverage.add(performanceReport.get95Line(),
                        Messages.ProjectAction_Line95(), label);
            }
            nbBuildsToAnalyze--;
        }

        String legendLimit = request.getParameter("legendLimit");
        int limit = (legendLimit != null && !legendLimit.isEmpty()) ? Integer.parseInt(legendLimit) : Integer.MAX_VALUE;

        new Graph(-1, 400, 200) {
            @Override
            protected JFreeChart createGraph() {
                return createRespondingTimeChart(dataSetBuilderAverage.build(), limit);
            }
        }.doPng(request, response);
    }

    public void doThroughputGraph(final StaplerRequest request, final StaplerResponse response) throws IOException {
        final String performanceReportNameFile = getPerformanceReportNameFile(request);
        if (performanceReportNameFile == null) {
            return;
        }

        if (ChartUtil.awtProblemCause != null) {
            // not available. send out error message
            response.sendRedirect2(request.getContextPath() + "/images/headless.png");
            return;
        }

        final DataSetBuilder<String, NumberOnlyBuildLabel> dataSetBuilder = new DataSetBuilder<>();
        final List<? extends Run<?, ?>> builds = getJob().getBuilds();
        final Range buildsLimits = getFirstAndLastBuild(request, builds);

        int nbBuildsToAnalyze = builds.size();
        for (final Run<?, ?> build : builds) {
            if (buildsLimits.in(nbBuildsToAnalyze)) {

                if (!buildsLimits.includedByStep(build.number)) {
                    continue;
                }

                final PerformanceBuildAction performanceBuildAction = build.getAction(PerformanceBuildAction.class);
                if (performanceBuildAction == null) {
                    continue;
                }

                final PerformanceReport performanceReport = performanceBuildAction
                        .getPerformanceReportMap().getPerformanceReport(performanceReportNameFile);
                if (performanceReport == null) {
                    nbBuildsToAnalyze--;
                    continue;
                }

                final ThroughputReport throughputReport = new ThroughputReport(performanceReport);
                final NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(build);
                dataSetBuilder.add(throughputReport.get(), Messages.ProjectAction_RequestsPerSeconds(), label);
            }
            nbBuildsToAnalyze--;
        }

        new Graph(-1, 400, 200) {
            @Override
            protected JFreeChart createGraph() {
                return createThroughputGraph(dataSetBuilder.build());
            }
        }.doPng(request, response);
    }

    protected JFreeChart createThroughputGraph(CategoryDataset dataset) {
        return createThroughputChart(dataset);
    }

    public void doSummarizerGraph(StaplerRequest request, StaplerResponse response) throws IOException {
        final PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();
        request.bindParameters(performanceReportPosition);
        final String performanceReportNameFile = getPerformanceReportNameFile(performanceReportPosition);

        if (ChartUtil.awtProblemCause != null) {
            // not available. send out error message
            // response.sendRedirect2(request.getContextPath() +
            // "/images/headless.png");
            return;
        }
        DataSetBuilder<NumberOnlyBuildLabel, String> dataSetBuilderSummarizer = new DataSetBuilder<>();
        DataSetBuilder<NumberOnlyBuildLabel, String> dataSetBuilderSummarizerErrors = new DataSetBuilder<>();
        ReportValueSelector valueSelector = ReportValueSelector.get(getJob());

        List<?> builds = getJob().getBuilds();
        Range buildsLimits = getFirstAndLastBuild(request, builds);

        int nbBuildsToAnalyze = builds.size();
        for (Object build : builds) {
            Run<?, ?> currentBuild = (Run<?, ?>) build;
            if (buildsLimits.in(nbBuildsToAnalyze)) {
                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(currentBuild);
                PerformanceReport performanceReport = getPerformanceReport(currentBuild, performanceReportNameFile);
                if (performanceReport == null) {
                    nbBuildsToAnalyze--;
                    continue;
                }

                for (Map.Entry<String, UriReport> entry : performanceReport.getUriReportMap().entrySet()) {
                    long methodValue = valueSelector.getValue(entry.getValue());
                    float methodErrors = entry.getValue().getSummarizerErrors();
                    dataSetBuilderSummarizer.add(methodValue, label, entry.getKey());
                    dataSetBuilderSummarizerErrors.add(methodErrors, label, entry.getKey());
                }
            }
            nbBuildsToAnalyze--;
        }

        String summarizerReportType = performanceReportPosition
                .getSummarizerReportType();

        if (summarizerReportType != null) {
            new Graph(-1, 400, 200) {
                @Override
                protected JFreeChart createGraph() {
                    return createSummarizerChart(dataSetBuilderSummarizerErrors.build(), "%",
                            Messages.ProjectAction_PercentageOfErrors());
                }
            }.doPng(request, response);
        } else {
            new Graph(-1, 400, 200) {
                @Override
                protected JFreeChart createGraph() {
                    return createSummarizerChart(dataSetBuilderSummarizer.build(), "ms",
                            Messages.ProjectAction_RespondingTime());
                }
            }.doPng(request, response);
        }
    }

    protected JFreeChart createSummarizerChart(CategoryDataset dataset, String yAxis, String chartTitle) {
        return doCreateSummarizerChart(dataset, yAxis, chartTitle);
    }

    /**
     * <p>
     * give a list of two Integer : the smallest build to use and the biggest.
     * </p>
     *
     * @param request
     * @param builds
     * @return outList
     */
    private Range getFirstAndLastBuild(StaplerRequest request, List<?> builds) {
        GraphConfigurationDetail graphConf = (GraphConfigurationDetail) createUserConfiguration(request);

        if (graphConf.isNone()) {
            return all(builds);
        }

        if (graphConf.isBuildCount()) {
            if (graphConf.getBuildCount() <= 0) {
                return all(builds);
            } else {
                int first = builds.size() - graphConf.getBuildCount();
                return new Range(first > 0 ? first + 1 : 1, builds.size());
            }
        } else if (graphConf.isBuildNth()) {
            if (graphConf.getBuildStep() <= 0) {
                return all(builds);
            } else {
                return new Range(1, builds.size(), graphConf.getBuildStep());
            }
        } else if (graphConf.isDate()) {
            if (graphConf.isDefaultDates()) {
                return all(builds);
            } else {
                int firstBuild = -1;
                int lastBuild = -1;
                int var = builds.size();
                GregorianCalendar firstDate = null;
                GregorianCalendar lastDate = null;
                try {
                    firstDate = GraphConfigurationDetail
                            .getGregorianCalendarFromString(graphConf.getFirstDayCount());
                    lastDate = GraphConfigurationDetail
                            .getGregorianCalendarFromString(graphConf.getLastDayCount());
                    lastDate.set(GregorianCalendar.HOUR_OF_DAY, 23);
                    lastDate.set(GregorianCalendar.MINUTE, 59);
                    lastDate.set(GregorianCalendar.SECOND, 59);
                    for (Object build : builds) {
                        Run<?, ?> currentBuild = (Run<?, ?>) build;
                        GregorianCalendar buildDate = new GregorianCalendar();
                        buildDate.setTime(currentBuild.getTimestamp().getTime());
                        if (firstDate.getTime().before(buildDate.getTime())) {
                            firstBuild = var;
                        }
                        if (lastBuild < 0 && lastDate.getTime().after(buildDate.getTime())) {
                            lastBuild = var;
                        }
                        var--;
                    }
                    return new Range(firstBuild, lastBuild);
                } catch (ParseException e) {
                    LOGGER
                            .log(Level.SEVERE, "Error during the manage of the Calendar", e);
                }
            }
        }
        throw new IllegalArgumentException("unsupported configType + "
                + graphConf.getConfigType());
    }

    public Range all(List<?> builds) {
        return new Range(1, builds.size());
    }

    public Job<?, ?> getJob() {
        return job;
    }

    public final Run<?, ?> getSomeBuildWithWorkspace() {
        byte cnt = 0;
        for (Run<?, ?> run = job.getLastBuild(); cnt < 5 && run != null; run = run.getPreviousBuild()) {
            if (!run.isBuilding()) {
                if (run instanceof AbstractBuild) {
                    FilePath ws = ((AbstractBuild<?, ?>) run).getWorkspace();
                    if (ws != null) {
                        return run;
                    }
                } else {
                    return run;
                }
            }
            cnt++;
        }
        return null;
    }

    @NonNull
    public List<String> getPerformanceReportList() {
        this.performanceReportList = new ArrayList<>(0);
        if (null == this.job) {
            return performanceReportList;
        }

        if (null == getSomeBuildWithWorkspace()) {
            return performanceReportList;
        }
        File file = new File(getSomeBuildWithWorkspace().getRootDir(),
                PerformanceReportMap.getPerformanceReportDirRelativePath());
        if (!file.isDirectory()) {
            return performanceReportList;
        }
        File[] files = file.listFiles();

        if (files != null) {
            for (File entry : files) {
                if (entry.isDirectory()) {
                    File[] entryFiles = entry.listFiles();
                    if (entryFiles != null) {
                        for (File e : Objects.requireNonNull(entryFiles)) {
                            if (!e.getName().endsWith(".serialized") && !e.getName().endsWith(".serialized-v2")) {
                                this.performanceReportList.add(e.getName());
                            }
                        }
                    }

                } else {
                    if (!entry.getName().endsWith(".serialized") && !entry.getName().endsWith(".serialized-v2")) {
                        this.performanceReportList.add(entry.getName());
                    }
                }

            }

        } else {
            // Handle the situation when files is null
            return performanceReportList;
        }

        Collections.sort(performanceReportList);

        return this.performanceReportList;
    }

    public void setPerformanceReportList(List<String> performanceReportList) {
        this.performanceReportList = performanceReportList;
    }

    public boolean isTrendVisibleOnProjectDashboard() {
        return getPerformanceReportList().size() == 1;
    }

    /**
     * Returns the graph configuration for this project.
     *
     * @param link     not used
     * @param request  Stapler request
     * @param response Stapler response
     * @return the dynamic result of the analysis (detail page).
     */
    public Object getDynamic(final String link, final StaplerRequest request,
                             final StaplerResponse response) {
        if (CONFIGURE_LINK.equals(link)) {
            return createUserConfiguration(request);
        } else if (TRENDREPORT_LINK.equals(link)) {
            return createTrendReport(request);
        } else if (TESTSUITE_LINK.equals(link)) {
            return createTestsuiteReport(request);
        } else {
            return null;
        }
    }

    /**
     * Creates a view to configure the trend graph for the current user.
     *
     * @param request Stapler request
     * @return a view to configure the trend graph for the current user
     */
    private Object createUserConfiguration(final StaplerRequest request) {
        return new GraphConfigurationDetail(job, PLUGIN_NAME, request);
    }

    /**
     * Creates a view to configure the trend graph for the current user.
     *
     * @param request Stapler request
     * @return a view to configure the trend graph for the current user
     */
    private Object createTrendReport(final StaplerRequest request) {
        String filename = getTrendReportFilename(request);
        CategoryDataset dataSet = getTrendReportData(request, filename).build();
        return new TrendReportDetail(job, PLUGIN_NAME, request, filename, dataSet);
    }

    private Object createTestsuiteReport(final StaplerRequest request) {
        String filename = getTestSuiteReportFilename(request);
        Range buildsLimits = getFirstAndLastBuild(request, getJob().getBuilds());
        return new TestSuiteReportDetail(job, filename, buildsLimits);
    }

    private String getTrendReportFilename(final StaplerRequest request) {
        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();
        request.bindParameters(performanceReportPosition);
        return performanceReportPosition.getPerformanceReportPosition();
    }

    private String getTestSuiteReportFilename(final StaplerRequest request) {
        PerformanceReportPosition performanceReportPosition = new PerformanceReportPosition();
        request.bindParameters(performanceReportPosition);
        return performanceReportPosition.getPerformanceReportPosition();
    }

    private DataSetBuilder<String, NumberOnlyBuildLabel> getTrendReportData(final StaplerRequest request,
                                                                            String performanceReportNameFile) {

        DataSetBuilder<String, NumberOnlyBuildLabel> dataSet = new DataSetBuilder<>();
        List<? extends Run<?, ?>> builds = getJob().getBuilds();
        Range buildsLimits = getFirstAndLastBuild(request, builds);

        int nbBuildsToAnalyze = builds.size();
        for (Run<?, ?> currentBuild : builds) {
            if (buildsLimits.in(nbBuildsToAnalyze)) {
                NumberOnlyBuildLabel label = new NumberOnlyBuildLabel(currentBuild);
                PerformanceBuildAction performanceBuildAction = currentBuild
                        .getAction(PerformanceBuildAction.class);
                if (performanceBuildAction == null) {
                    continue;
                }
                PerformanceReport report = null;
                report = performanceBuildAction.getPerformanceReportMap()
                        .getPerformanceReport(performanceReportNameFile);
                if (report == null) {
                    nbBuildsToAnalyze--;
                    continue;
                }
                dataSet.add(report.getAverage(),
                        Messages.ProjectAction_Average(), label);
                Map<Double, Long> percentilesValues = report.getPercentilesValues();

                for (Map.Entry<Double, Long> entry : percentilesValues.entrySet()) {
                    dataSet.add(entry.getValue(),
                            report.getPercentileLabel(entry.getKey()), label);
                }

                dataSet.add(Math.round(report.errorPercent()),
                        Messages.ProjectAction_PercentageOfErrors(), label);
                dataSet.add(report.countErrors(),
                        Messages.ProjectAction_Errors(), label);
                dataSet.add(report.getTotalTrafficInKb(),
                        Messages.ProjectAction_TotalTrafficKB(), label);
                dataSet.add(report.getAverageSizeInKb(),
                        Messages.ProjectAction_AverageKB(), label);
            }
            nbBuildsToAnalyze--;
        }
        return dataSet;
    }

    public boolean ifSummarizerParserUsed(String filename) {

        return this.getJob().getBuilds().getLastBuild()
                .getAction(PerformanceBuildAction.class).getPerformanceReportMap()
                .getPerformanceReport(filename).ifSummarizerParserUsed(filename);
    }

    public boolean ifModePerformancePerTestCaseUsed() {
        if (this.job instanceof AbstractProject) {
            AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;
            PerformancePublisher publisher = (PerformancePublisher) project.getPublishersList()
                    .get(PerformancePublisher.class);
            return publisher != null && publisher.isModePerformancePerTestCase();
        } else {
            return true;
        }
    }

    public boolean ifModeThroughputUsed() {
        if (this.job instanceof AbstractProject) {
            AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;
            PerformancePublisher publisher = (PerformancePublisher) project.getPublishersList()
                    .get(PerformancePublisher.class);
            return publisher == null || publisher.isModeThroughput();
        } else {
            return true;
        }
    }

    public static class Range {

        public int first;

        public int last;

        public int step;

        public Range(int first, int last) {
            this.first = first;
            this.last = last;
            this.step = 1;
        }

        public Range(int first, int last, int step) {
            this(first, last);
            this.step = step;
        }

        public boolean in(int nbBuildsToAnalyze) {
            return nbBuildsToAnalyze <= last && first <= nbBuildsToAnalyze;
        }

        public boolean includedByStep(int buildNumber) {
            return (buildNumber % step == 0);
        }
    }
}


================================================
FILE: src/main/java/hudson/plugins/performance/build/PerformanceTestBuild.java
================================================
package hudson.plugins.performance.build;

import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Functions;
import hudson.Launcher;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.plugins.performance.Messages;
import hudson.plugins.performance.PerformancePublisher;
import hudson.plugins.performance.actions.PerformanceProjectAction;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import jenkins.tasks.SimpleBuildStep;
import org.apache.commons.io.output.NullOutputStream;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import edu.umd.cs.findbugs.annotations.NonNull;

import java.io.*;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.InvalidPathException;
import java.util.*;
import java.util.logging.Logger;

/**
 * "Build step" for running performance test
 */
public class PerformanceTestBuild extends Builder implements SimpleBuildStep {
    public static final Logger LOGGER = Logger.getLogger(PerformanceTestBuild.class.getName());

    protected final static String PERFORMANCE_TEST_COMMAND = "bzt";
    protected final static String VIRTUALENV_COMMAND = "virtualenv";
    protected final static String HELP_OPTION = "--help";
    protected final static String VIRTUALENV_PATH_UNIX = "/taurus-venv/bin/";
    protected final static String VIRTUALENV_PATH_WINDOWS = "\\taurus-venv\\Scripts\\";

    final static String[] CHECK_BZT_COMMAND = new String[]{PERFORMANCE_TEST_COMMAND, HELP_OPTION};
    final static String[] CHECK_VIRTUALENV_COMMAND = new String[]{VIRTUALENV_COMMAND, HELP_OPTION};

    final static String[] CREATE_LOCAL_PYTHON_COMMAND_WITH_SYSTEM_PACKAGES_OPTION =
            new String[]{VIRTUALENV_COMMAND, "--clear", "--system-site-packages", "taurus-venv"};
    final static String[] CREATE_LOCAL_PYTHON_COMMAND = new String[]{VIRTUALENV_COMMAND, "--clear", "taurus-venv"};

    protected final static String DEFAULT_CONFIG_FILE = "jenkins-report.yml";


    @Symbol({"bzt","performanceTest"})
    @Extension
    public static class Descriptor extends BuildStepDescriptor<Builder> {

        @Override
        public boolean isApplicable(Class<? extends AbstractProject> jobType) {
            return true;
        }

        @Override
        public String getDisplayName() {
            return Messages.PerformanceTest_Name();
        }
    }


    private String params;
    private boolean printDebugOutput = false;
    private boolean alwaysUseVirtualenv = false;
    private boolean useSystemSitePackages = true;
    private boolean generatePerformanceTrend = true;
    private boolean useBztExitCode = true;
    private String bztVersion = "";
    private String workingDirectory = "";
    private String virtualEnvCommand = "";
    /**
     * Use 'workingDirectory' for set bzt working directory
     */
    @Deprecated
    private transient String workspace = "";

    @DataBoundConstructor
    public PerformanceTestBuild(String params) {
        this.params = params;
    }

    /**
     * This method, invoked after object is resurrected from persistence
     */
    public Object readResolve() {
        if (workspace != null && !workspace.isEmpty()) {
            workingDirectory = workspace;
            workspace = "";
        }
        return this;
    }


    @Override
    public Action getProjectAction(AbstractProject<?, ?> project) {
        return generatePerformanceTrend  ? new PerformanceProjectAction(project) : null;
    }


    @Override
    public void perform(@NonNull Run<?, ?> run, @NonNull FilePath workspace, @NonNull Launcher launcher, @NonNull TaskListener listener) throws InterruptedException, IOException {
        PrintStream logger = listener.getLogger();
        EnvVars envVars = run.getEnvironment(listener);
        addPipelineEnvVars(run, envVars);

        FilePath virtualenvWorkspace;
        try {
            virtualenvWorkspace = getVirtualenvWorkspace(run, workspace, logger);
        } catch (Exception ex) {
            logger.println("[ERROR] Performance test: " + ex.getMessage());
            run.setResult(Result.FAILURE);
            return;
        }

        boolean isVirtualenvInstallation = false;
        if ((!alwaysUseVirtualenv && isGlobalBztInstalled(workspace, logger, launcher, envVars)) ||
                (isVirtualenvInstallation = installBztAndCheck(virtualenvWorkspace, logger, launcher, envVars))) {


            FilePath bztWorkingDirectory = getBztWorkingDirectory(workspace);
            try {
                bztWorkingDirectory.mkdirs();
            } catch (IOException ex) {
                logger.println("Performance test: Cannot create working directory because of error: " + ex.getMessage());
                run.setResult(Result.FAILURE);
                return;
            }

            int testExitCode = runPerformanceTest(bztWorkingDirectory, virtualenvWorkspace, logger, launcher, envVars, isVirtualenvInstallation);

            run.setResult(useBztExitCode ?
                    getBztJobResult(testExitCode) :
                    getJobResult(testExitCode)
            );
            Result result = run.getResult();
            if (generatePerformanceTrend && result != null && Result.FAILURE.isWorseThan(result)) {
                generatePerformanceTrend(bztWorkingDirectory.getRemote(), run, workspace, launcher, listener);
            }

            return;
        }

        run.setResult(Result.FAILURE);
    }

    private void addPipelineEnvVars(Run<?, ?> run, EnvVars envVars) {
        if (run.getClass().getCanonicalName().startsWith("org.jenkinsci.plugins.workflow")) {
            List<? extends Action> allActions = run.getAllActions();
            if (!allActions.isEmpty()) {
                for (Action action : allActions) {
                    if ("org.jenkinsci.plugins.workflow.cps.EnvActionImpl".equals(action.getClass().getCanonicalName())) {
                        addEnvVars(action, envVars);
                    }
                }
            }
        }
    }

    private void addEnvVars(Action action, EnvVars envVars) {
        try {
            Class<? extends Action> actionClass = action.getClass();
            Method method = actionClass.getMethod("getOverriddenEnvironment");
            Map<String, String> map = (Map<String, String>) method.invoke(action);
            envVars.overrideAll(map);
        } catch (Throwable ex) {
            LOGGER.warning("Failed to add envVars from action: " + action.getClass());
        }
    }

    private FilePath getVirtualenvWorkspace(Run<?, ?> run, FilePath workspace, PrintStream logger) throws Exception {
        return workspace.getRemote().contains(" ") ?
                createTemporaryWorkspace(run, workspace, logger) :
                workspace;
    }

    private FilePath createTemporaryWorkspace(Run<?, ?> run, FilePath workspace, PrintStream logger) throws Exception {
        logger.println("[WARNING] Performance test: Job workspace contains spaces in path. Virtualenv does not support such path. Creating temporary workspace for virtualenv.");
        File baseTmpDir = new File(System.getProperty("java.io.tmpdir"));
        if (baseTmpDir.getAbsolutePath().contains(" ")) {
            logger.println("[WARNING] Performance test: Temporary folder contains spaces in path.");
            throw new InvalidPathException(baseTmpDir.getAbsolutePath(), "Virtualenv cannot be installed in workspace that contains spaces in path.");
        }
        File tempDir = new File(baseTmpDir.getAbsolutePath(), "perf-test-virtualenv-workspace-" + configJobName(run.getParent().getName()));
        FilePath tempWorkspace = new FilePath(workspace.getChannel(), tempDir.getAbsolutePath());
        tempWorkspace.mkdirs();
        return tempWorkspace;
    }

    private String configJobName(String displayName) {
        return displayName.replaceAll(" ", "-");
    }

    protected FilePath getBztWorkingDirectory(FilePath jobWorkspace) {
        return (workingDirectory != null && !workingDirectory.isEmpty()) ?
                (isAbsoluteFilePath() ?
                        // absolute workspace
                        new FilePath(jobWorkspace.getChannel(), workingDirectory) :
                        //relative workspace
                        new FilePath(jobWorkspace, workingDirectory)
                ) :
                jobWorkspace;
    }

    private boolean isAbsoluteFilePath() {
        return new File(workingDirectory).isAbsolute();
    }

    protected void generatePerformanceTrend(String path, Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener) throws IOException, InterruptedException {
        new PerformancePublisher(path + "/aggregate-results.xml", -1, -1, "", 0, 0, 0, 0, 0, false, "", false, false, false, false,true, null).
                perform(run, workspace, launcher, listener);
    }

    private boolean installBztAndCheck(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {
        return installBzt(workspace, logger, launcher, envVars) &&
                isVirtualenvBztInstalled(workspace, logger, launcher, envVars);
    }

    private boolean installBzt(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {
        return isVirtualenvInstalled(workspace, logger, launcher, envVars) &&
                createVirtualenvAndInstallBzt(workspace, logger, launcher, envVars);
    }

    private boolean createVirtualenvAndInstallBzt(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {
        return createIsolatedPython(workspace, logger, launcher, envVars) &&
                installBztInVirtualenv(workspace, logger, launcher, envVars);
    }

    // Step 1.1: Check bzt using "bzt --help".
    private boolean isGlobalBztInstalled(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {
        logger.println("Performance test: Checking global bzt installation...");
        boolean result = isSuccessCode(runCmd(CHECK_BZT_COMMAND, workspace, NullOutputStream.NULL_OUTPUT_STREAM, launcher, envVars));
        logger.println(result ?
                "Performance test: Found global bzt installation." :
                "Performance test: You don't have global bzt installed on this Jenkins host. Installing it globally will speed up job. Run 'sudo pip install bzt' to install it."
        );
        return result;
    }

    // Step 1.2: If bzt not installed check virtualenv using "virtualenv --help".
    private boolean isVirtualenvInstalled(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {
        logger.println("Performance test: Checking virtualenv tool availability...");
        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        boolean result = isSuccessCode(runCmd(CHECK_VIRTUALENV_COMMAND, workspace, outputStream, launcher, envVars));
        logger.println(result ?
                "Performance test: Found virtualenv tool." :
                "Performance test: No virtualenv found on this Jenkins host. Install it with 'sudo pip install virtualenv'."
        );
        if (!result || printDebugOutput) {
            logger.write(outputStream.toByteArray());
        }
        return result;
    }

    // Step 1.3: Create local python using "virtualenv --clear taurus-venv".
    private boolean createIsolatedPython(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {
        logger.println("Performance test: Creating virtualev at 'taurus-venv'...");
        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        boolean result = isSuccessCode(runCmd(useSystemSitePackages ?
                        CREATE_LOCAL_PYTHON_COMMAND_WITH_SYSTEM_PACKAGES_OPTION :
                        CREATE_LOCAL_PYTHON_COMMAND,
                workspace, outputStream, launcher, envVars));
        logger.println(result ?
                "Performance test: Done creating virtualenv." :
                "Performance test: Failed to create virtualenv at 'taurus-venv'"
        );
        if (!result || printDebugOutput) {
            logger.write(outputStream.toByteArray());
        }
        return result;
    }

    // Step 1.4: Install bzt in virtualenv using "taurus-venv/bin/pip install bzt".
    private boolean installBztInVirtualenv(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {
        logger.println("Performance test: Installing bzt into 'taurus-venv'");
        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        boolean result = isSuccessCode(runCmd(getBztInstallCommand(workspace), workspace, outputStream, launcher, envVars));
        logger.println(result ?
                "Performance test: bzt installed successfully." :
                "Performance test: Failed to install bzt into 'taurus-venv'"
        );
        if (!result || printDebugOutput) {
            logger.write(outputStream.toByteArray());
        }
        return result;
    }

    // Step 1.5: Check bzt using "taurus-venv/bin/bzt --help"
    private boolean isVirtualenvBztInstalled(FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars) throws InterruptedException, IOException {
        logger.println("Performance test: Checking installed bzt...");
        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        boolean result = isSuccessCode(runCmd(getBztCheckCommand(workspace), workspace, outputStream, launcher, envVars));
        logger.println(result ?
                "Performance test: bzt is operational." :
                "Performance test: Failed to run bzt inside virtualenv."
        );
        if (!result || printDebugOutput) {
            logger.write(outputStream.toByteArray());
        }
        return result;
    }

    // Step 2: Run performance test.
    private int runPerformanceTest(FilePath bztWorkingDirectory, FilePath workspace, PrintStream logger, Launcher launcher, EnvVars envVars, boolean isVirtualenvInstallation) throws InterruptedException, IOException {
        final List<String> testCommand = new ArrayList<>();

        testCommand.add((isVirtualenvInstallation ? getVirtualenvPath(workspace) : "") + PERFORMANCE_TEST_COMMAND);
        String[] parsedParams;
        try {
            parsedParams = CommandLineUtils.translateCommandline(envVars.expand(this.params));
        } catch (Exception e) {
            logger.println("Failed parse Taurus parameters");
            e.printStackTrace(logger);
            return 1;
        }

        for (String param : parsedParams) {
            if (!param.isEmpty()) {
                testCommand.add(param);
            }
        }

        if (generatePerformanceTrend) {
            testCommand.add(extractDefaultReportToWorkingDirectory(bztWorkingDirectory));
        }

        logger.println("Performance test: run " + Arrays.toString(testCommand.toArray()));
        return runCmd(testCommand.toArray(new String[testCommand.size()]), bztWorkingDirectory, logger, launcher, envVars);
    }

    public boolean isSuccessCode(int code) {
        return code == 0;
    }

    public Result getJobResult(int code) {
        if (code == 0) {
            return Result.SUCCESS;
        } else {
            return Result.FAILURE;
        }
    }


    public Result getBztJobResult(int code) {
        if (code == 0) {
            return Result.SUCCESS;
        } else if (code == 1) {
            return Result.FAILURE;
        } else {
            return Result.UNSTABLE;
        }
    }

    private String getVirtualenvPath(FilePath workspace) {
        return workspace.getRemote() + (Functions.isWindows() ?
                VIRTUALENV_PATH_WINDOWS :
                VIRTUALENV_PATH_UNIX);
    }

    // return bzt install command
    private String[] getBztInstallCommand(FilePath workspace) throws IOException, InterruptedException {
        return new String[]{
                g
Download .txt
gitextract_iumnbdkn/

├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── cd.yaml
│       └── jenkins-security-scan.yml
├── .gitignore
├── .mvn/
│   ├── extensions.xml
│   └── maven.config
├── Jenkinsfile
├── LICENSE
├── README.md
├── docs/
│   ├── .gitkeep
│   ├── Changelog.md
│   ├── README.md
│   ├── Reporting.md
│   ├── RunTests.md
│   ├── _config.yml
│   └── stats.html
├── pom.xml
├── requirements.txt
└── src/
    ├── main/
    │   ├── java/
    │   │   └── hudson/
    │   │       └── plugins/
    │   │           └── performance/
    │   │               ├── PerformancePublisher.java
    │   │               ├── PerformanceReportMap.java
    │   │               ├── TrendReportGraphs.java
    │   │               ├── actions/
    │   │               │   ├── ExternalBuildReportAction.java
    │   │               │   ├── PerformanceBuildAction.java
    │   │               │   └── PerformanceProjectAction.java
    │   │               ├── build/
    │   │               │   └── PerformanceTestBuild.java
    │   │               ├── constraints/
    │   │               │   ├── AbsoluteConstraint.java
    │   │               │   ├── AbstractConstraint.java
    │   │               │   ├── ConstraintChecker.java
    │   │               │   ├── ConstraintEvaluation.java
    │   │               │   ├── ConstraintFactory.java
    │   │               │   ├── RelativeConstraint.java
    │   │               │   └── blocks/
    │   │               │       ├── PreviousResultsBlock.java
    │   │               │       └── TestCaseBlock.java
    │   │               ├── cookie/
    │   │               │   └── CookieHandler.java
    │   │               ├── data/
    │   │               │   ├── ConstraintSettings.java
    │   │               │   ├── HttpSample.java
    │   │               │   ├── PerformanceReportPosition.java
    │   │               │   ├── ReportValueSelector.java
    │   │               │   └── TaurusFinalStats.java
    │   │               ├── descriptors/
    │   │               │   ├── ConstraintDescriptor.java
    │   │               │   └── PerformanceReportParserDescriptor.java
    │   │               ├── details/
    │   │               │   ├── GraphConfigurationDetail.java
    │   │               │   ├── TestSuiteReportDetail.java
    │   │               │   └── TrendReportDetail.java
    │   │               ├── parsers/
    │   │               │   ├── AbstractParser.java
    │   │               │   ├── IagoParser.java
    │   │               │   ├── JMeterCsvParser.java
    │   │               │   ├── JMeterParser.java
    │   │               │   ├── JUnitParser.java
    │   │               │   ├── JmeterSummarizerParser.java
    │   │               │   ├── LoadRunnerParser.java
    │   │               │   ├── LocustParser.java
    │   │               │   ├── ParserDetector.java
    │   │               │   ├── ParserFactory.java
    │   │               │   ├── PerformanceReportParser.java
    │   │               │   ├── TaurusParser.java
    │   │               │   └── WrkSummarizerParser.java
    │   │               ├── reports/
    │   │               │   ├── AbstractReport.java
    │   │               │   ├── ConstraintReport.java
    │   │               │   ├── PerformanceReport.java
    │   │               │   ├── ThroughputReport.java
    │   │               │   └── UriReport.java
    │   │               ├── tools/
    │   │               │   └── SafeMaths.java
    │   │               └── workflow/
    │   │                   └── WorkflowActionsFactory.java
    │   ├── resources/
    │   │   ├── hudson/
    │   │   │   └── plugins/
    │   │   │       └── performance/
    │   │   │           ├── Messages.properties
    │   │   │           ├── Messages_es.properties
    │   │   │           ├── PerformancePublisher/
    │   │   │           │   ├── config.jelly
    │   │   │           │   ├── config.properties
    │   │   │           │   ├── config_es.properties
    │   │   │           │   ├── config_zh_TW.properties
    │   │   │           │   ├── help-errorUnstableResponseTimeThreshold.html
    │   │   │           │   ├── help-filterRegex.html
    │   │   │           │   ├── help-modeEvaluation.html
    │   │   │           │   ├── help-persistPerformanceChart.html
    │   │   │           │   ├── help-persistPerformanceCharts.html
    │   │   │           │   └── help-sourceDataFiles.html
    │   │   │           ├── PerformanceReportMap/
    │   │   │           │   ├── CVS/
    │   │   │           │   │   ├── Entries
    │   │   │           │   │   ├── Repository
    │   │   │           │   │   └── Root
    │   │   │           │   ├── index.jelly
    │   │   │           │   ├── index_es.properties
    │   │   │           │   └── index_fr.properties
    │   │   │           ├── TrendReportGraphs/
    │   │   │           │   ├── index.jelly
    │   │   │           │   └── index_es.properties
    │   │   │           ├── actions/
    │   │   │           │   └── PerformanceProjectAction/
    │   │   │           │       ├── floatingBox.jelly
    │   │   │           │       ├── floatingBox_es.properties
    │   │   │           │       ├── index.jelly
    │   │   │           │       ├── index_es.properties
    │   │   │           │       └── index_fr.properties
    │   │   │           ├── build/
    │   │   │           │   ├── PerformanceTestBuild/
    │   │   │           │   │   ├── config.jelly
    │   │   │           │   │   ├── config.properties
    │   │   │           │   │   └── help.html
    │   │   │           │   └── jenkins-report.yml
    │   │   │           ├── constraints/
    │   │   │           │   ├── AbsoluteConstraint/
    │   │   │           │   │   ├── config.jelly
    │   │   │           │   │   └── config.properties
    │   │   │           │   ├── AbstractConstraint/
    │   │   │           │   │   ├── help-relatedPerfReport.html
    │   │   │           │   │   └── help-testCase.html
    │   │   │           │   └── RelativeConstraint/
    │   │   │           │       ├── config.jelly
    │   │   │           │       ├── config.properties
    │   │   │           │       ├── help-previousResultsString.html
    │   │   │           │       ├── help-timeframeEndString.html
    │   │   │           │       └── help-timeframeStartString.html
    │   │   │           ├── details/
    │   │   │           │   ├── GraphConfigurationDetail/
    │   │   │           │   │   ├── CVS/
    │   │   │           │   │   │   ├── Entries
    │   │   │           │   │   │   ├── Repository
    │   │   │           │   │   │   └── Root
    │   │   │           │   │   ├── index.jelly
    │   │   │           │   │   ├── index.properties
    │   │   │           │   │   └── index_es.properties
    │   │   │           │   ├── TestSuiteReportDetail/
    │   │   │           │   │   └── index.jelly
    │   │   │           │   └── TrendReportDetail/
    │   │   │           │       ├── index.jelly
    │   │   │           │       └── index_es.properties
    │   │   │           ├── reports/
    │   │   │           │   └── UriReport/
    │   │   │           │       ├── index.jelly
    │   │   │           │       ├── index_es.properties
    │   │   │           │       └── index_fr.properties
    │   │   │           └── tags/
    │   │   │               ├── captionLine.jelly
    │   │   │               ├── captionLine_es.properties
    │   │   │               ├── captionLine_fr.properties
    │   │   │               ├── summaryTable.jelly
    │   │   │               ├── summaryTableSummarizer.jelly
    │   │   │               └── taglib
    │   │   ├── index.jelly
    │   │   └── lib/
    │   │       └── performance/
    │   │           ├── blockWrapper.jelly
    │   │           └── taglib
    │   ├── tools/
    │   │   ├── checkstyle.xml
    │   │   └── format.xml
    │   └── webapp/
    │       ├── css/
    │       │   └── style.css
    │       ├── help.html
    │       └── help_es.html
    └── test/
        ├── java/
        │   └── hudson/
        │       └── plugins/
        │           └── performance/
        │               ├── AbstractGraphGenerationTest.java
        │               ├── BaselineComparisonTest.java
        │               ├── PerformancePipelineTest.java
        │               ├── PerformancePublisherTest.java
        │               ├── PerformanceReportMapTest.java
        │               ├── TrendReportGraphsTest.java
        │               ├── actions/
        │               │   ├── ExternalBuildReportActionTest.java
        │               │   ├── PerformanceProjectActionGraphTest.java
        │               │   └── PerformanceProjectActionTest.java
        │               ├── build/
        │               │   └── PerformanceTestBuildTest.java
        │               ├── constraints/
        │               │   ├── ConstraintCheckerTest.java
        │               │   ├── ConstraintFactoryTest.java
        │               │   └── ConstraintTest.java
        │               ├── cookie/
        │               │   └── CookieHandlerTest.java
        │               ├── data/
        │               │   ├── PerformanceReportPositionTest.java
        │               │   └── ReportValueSelectorTest.java
        │               ├── descriptors/
        │               │   ├── ConstraintDescriptorTest.java
        │               │   └── PerformanceReportParserDescriptorTest.java
        │               ├── details/
        │               │   ├── GraphConfigurationDetailTest.java
        │               │   └── TestSuiteReportDetailTest.java
        │               ├── parsers/
        │               │   ├── AbstractParserTest.java
        │               │   ├── IagoParserTest.java
        │               │   ├── JMeterCsvParserTest.java
        │               │   ├── JMeterParserTest.java
        │               │   ├── JMeterTestHelper.java
        │               │   ├── JUnitParserTest.java
        │               │   ├── JmeterSummarizerParserTest.java
        │               │   ├── LoadRunnerParserTest.java
        │               │   ├── LocustParserTest.java
        │               │   ├── ParserDetectorTest.java
        │               │   ├── ParserFactoryTest.java
        │               │   ├── TaurusParserTest.java
        │               │   └── WrkSummarizerParserTest.java
        │               ├── reports/
        │               │   ├── ConstraintReportTest.java
        │               │   ├── PerformanceReportTest.java
        │               │   ├── ThroughputReportTest.java
        │               │   └── UriReportTest.java
        │               ├── tools/
        │               │   └── SafeMathsTest.java
        │               └── workflow/
        │                   └── WorkflowActionsFactoryTest.java
        └── resources/
            ├── IagoResults.log
            ├── JENKINS-16627_CSV_instead_of_XML.jtl
            ├── JMeterCsvResults.csv
            ├── JMeterCsvResults2.csv
            ├── JMeterCsvResults3.csv
            ├── JMeterPublisher.csv
            ├── JMeterPublisher_formatted_timeStamp.csv
            ├── JMeterResults.jtl
            ├── JMeterResultsMultiLevel.jtl
            ├── JMeterResultsMultiThread.jtl
            ├── JMeterResultsOneSample.jtl
            ├── JMeterResultsRandomUri.jtl
            ├── JMeterResultsTenSamples.jtl
            ├── JMeterResultsThreeSamples.jtl
            ├── TEST-JUnitResults-noTimeAttribute.xml
            ├── TEST-JUnitResults-relative-thrashould-2.xml
            ├── TEST-JUnitResults-relative-thrashould.xml
            ├── TEST-JUnitResults-success-failure-error.xml
            ├── TEST-JUnitResults.xml
            ├── TEST-results.xml
            ├── TaurusPreviousBuildReport.xml
            ├── TaurusXMLReport.xml
            ├── TaurusXmlWithDuration.xml
            ├── WrkResultsLong.wrk
            ├── WrkResultsQuick.wrk
            ├── WrkResultsWithErrors.wrk
            ├── WrkResultsWithLatencyFlag.wrk
            ├── aggregate-results.xml
            ├── constraint-test.xml
            ├── emptyfile.jtl
            ├── filewithtransactions.csv
            ├── jUnitIssue5571.xml
            ├── jmeter.log
            ├── lr-session.mdb
            ├── multiLineCSV.jtl
            ├── performanceTest.yml
            ├── performanceTestWithFailCriteria.yml
            ├── single_result/
            │   ├── nested/
            │   │   └── res.jtl
            │   └── res.csv
            ├── summary.log
            ├── test_results_stats.csv
            └── whitespace-followed-by-xml.jtl
Download .txt
SYMBOL INDEX (1223 symbols across 85 files)

FILE: src/main/java/hudson/plugins/performance/PerformancePublisher.java
  class PerformancePublisher (line 82) | public class PerformancePublisher extends Recorder implements SimpleBuil...
    method PerformancePublisher (line 191) | @Restricted(NoExternalUse.class)
    method PerformancePublisher (line 237) | @DataBoundConstructor
    method getPerformanceReport (line 242) | public static File getPerformanceReport(Run<?, ?> build, String parser...
    method getProjectAction (line 248) | @Override
    method getRequiredMonitorService (line 253) | public BuildStepMonitor getRequiredMonitorService() {
    method getPerformanceReportBuildFileName (line 266) | public static String getPerformanceReportBuildFileName(String performa...
    method locatePerformanceReports (line 283) | protected static List<FilePath> locatePerformanceReports(FilePath work...
    method getParsers (line 333) | protected List<PerformanceReportParser> getParsers(Run<?, ?> build, Fi...
    method migrateParsers (line 353) | private void migrateParsers() {
    method readResolve (line 372) | public Object readResolve() {
    method perform (line 386) | @Override
    method prepareEvaluation (line 417) | public Collection<PerformanceReport> prepareEvaluation(Run<?, ?> run, ...
    method addExternalReportActionsToBuild (line 438) | private void addExternalReportActionsToBuild(Run<?, ?> run, List<Perfo...
    method locatePerformanceReports (line 446) | private Collection<PerformanceReport> locatePerformanceReports(Run<?, ...
    method prepareParsers (line 489) | private void prepareParsers(Collection<PerformanceReportParser> perfor...
    method getBuildUriReports (line 497) | protected List<UriReport> getBuildUriReports(Run<?, ?> build, FilePath...
    method evaluateInStandardMode (line 537) | public void evaluateInStandardMode(Run<?, ?> run, FilePath workspace, ...
    method compareWithAbsoluteThreshold (line 550) | public void compareWithAbsoluteThreshold(Run<?, ?> run, TaskListener l...
    method analyzeErrorThreshold (line 568) | private void analyzeErrorThreshold(Run<?, ?> run, PerformanceReport pe...
    method checkAverageResponseTime (line 593) | private Result checkAverageResponseTime(PerformanceReport performanceR...
    method writeStandardResultsToXML (line 613) | private void writeStandardResultsToXML(Run<?, ?> run, Collection<Perfo...
    method appendStandardResultsStatsToXml (line 628) | private String appendStandardResultsStatsToXml(Collection<PerformanceR...
    method writeErrorThresholdReportInXML (line 650) | private void writeErrorThresholdReportInXML(Run<?, ?> run, Performance...
    method appendStatsToXml (line 675) | private String appendStatsToXml(List<UriReport> reports) {
    method getResponseTimeThresholdMap (line 711) | private HashMap<String, String> getResponseTimeThresholdMap(PrintStrea...
    method compareWithRelativeThreshold (line 731) | public void compareWithRelativeThreshold(Run<?, ?> run, FilePath works...
    method compareUriReports (line 790) | private void compareUriReports(Run<?, ?> run, List<UriReport> currentU...
    method calculateBuildStatus (line 811) | private void calculateBuildStatus(Run<?, ?> run, PrintStream logger, S...
    method calculateDiffInPercents (line 838) | private double calculateDiffInPercents(double value1, double value2) {
    method calculateRelativeFailedThresholdNegative (line 842) | private boolean calculateRelativeFailedThresholdNegative(double relati...
    method calculateRelativeUnstableThresholdNegative (line 847) | private boolean calculateRelativeUnstableThresholdNegative(double rela...
    method calculateRelativeFailedThresholdPositive (line 852) | private boolean calculateRelativeFailedThresholdPositive(double relati...
    method calculateRelativeUnstableThresholdPositive (line 857) | private boolean calculateRelativeUnstableThresholdPositive(double rela...
    method calculateRelativeDiffInPercent (line 862) | private double calculateRelativeDiffInPercent(UriReport currentReport,...
    method writeRelativeThresholdReportInXML (line 893) | private void writeRelativeThresholdReportInXML(Run<?, ?> run, StringBu...
    method createArchiveDirectoryIfMissing (line 937) | private File createArchiveDirectoryIfMissing(Run<?, ?> run) {
    method appendRelativeInfoAboutAverage (line 946) | private void appendRelativeInfoAboutAverage(UriReport currentReport, U...
    method appendRelativeInfoAboutMedian (line 958) | private void appendRelativeInfoAboutMedian(UriReport currentReport, Ur...
    method appendRelativeInfoAbout90Line (line 970) | private void appendRelativeInfoAbout90Line(UriReport currentReport, Ur...
    method printInfoAboutErrorThreshold (line 983) | private void printInfoAboutErrorThreshold(PrintStream logger) {
    method printInfoAboutRelativeThreshold (line 1000) | private void printInfoAboutRelativeThreshold(PrintStream logger) {
    method printInfoAboutCompareBasedOn (line 1023) | private void printInfoAboutCompareBasedOn(PrintStream logger, String l...
    method evaluateInExpertMode (line 1042) | public void evaluateInExpertMode(Run<?, ?> run, FilePath workspace, Ta...
    method copyReportsToMaster (line 1091) | private List<File> copyReportsToMaster(Run<?, ?> build, PrintStream lo...
    method getErrorFailedThreshold (line 1107) | public int getErrorFailedThreshold() {
    method setErrorFailedThreshold (line 1111) | @DataBoundSetter
    method getErrorUnstableThreshold (line 1116) | public int getErrorUnstableThreshold() {
    method setErrorUnstableThreshold (line 1120) | @DataBoundSetter
    method getErrorUnstableResponseTimeThreshold (line 1125) | public String getErrorUnstableResponseTimeThreshold() {
    method setErrorUnstableResponseTimeThreshold (line 1129) | @DataBoundSetter
    method isModePerformancePerTestCase (line 1134) | public boolean isModePerformancePerTestCase() {
    method setModePerformancePerTestCase (line 1138) | @DataBoundSetter
    method getFilename (line 1143) | public String getFilename() {
    method setFilename (line 1147) | public void setFilename(String filename) {
    method isFailBuildIfNoResultFile (line 1151) | public boolean isFailBuildIfNoResultFile() {
    method setFailBuildIfNoResultFile (line 1155) | @DataBoundSetter
    method isART (line 1160) | public boolean isART() {
    method isMRT (line 1164) | public boolean isMRT() {
    method isPRT (line 1168) | public boolean isPRT() {
    method getPerformanceReportDirectory (line 1172) | public static File[] getPerformanceReportDirectory(Run<?, ?> build, St...
    method getnthBuild (line 1186) | public Run<?, ?> getnthBuild(Run<?, ?> build) {
    method getExistingReports (line 1199) | private List<File> getExistingReports(Run<?, ?> build, PrintStream log...
    method getRelativeFailedThresholdPositive (line 1217) | public double getRelativeFailedThresholdPositive() {
    method getRelativeFailedThresholdNegative (line 1221) | public double getRelativeFailedThresholdNegative() {
    method setRelativeFailedThresholdPositive (line 1225) | @DataBoundSetter
    method setRelativeFailedThresholdNegative (line 1230) | @DataBoundSetter
    method getRelativeUnstableThresholdPositive (line 1235) | public double getRelativeUnstableThresholdPositive() {
    method getRelativeUnstableThresholdNegative (line 1239) | public double getRelativeUnstableThresholdNegative() {
    method setRelativeUnstableThresholdPositive (line 1243) | @DataBoundSetter
    method setRelativeUnstableThresholdNegative (line 1248) | @DataBoundSetter
    method getNthBuildNumber (line 1253) | public int getNthBuildNumber() {
    method setNthBuildNumber (line 1257) | @DataBoundSetter
    method getConfigType (line 1262) | public String getConfigType() {
    method setConfigType (line 1266) | @DataBoundSetter
    method getGraphType (line 1271) | public String getGraphType() {
    method setGraphType (line 1275) | @DataBoundSetter
    method getModeOfThreshold (line 1280) | public boolean getModeOfThreshold() {
    method setModeOfThreshold (line 1284) | @DataBoundSetter
    method getCompareBuildPrevious (line 1289) | public boolean getCompareBuildPrevious() {
    method setCompareBuildPrevious (line 1293) | @DataBoundSetter
    method isModeThroughput (line 1298) | public boolean isModeThroughput() {
    method setModeThroughput (line 1302) | @DataBoundSetter
    method getConstraints (line 1307) | public List<? extends AbstractConstraint> getConstraints() {
    method setConstraints (line 1311) | @DataBoundSetter
    method setIgnoreFailedBuilds (line 1316) | @DataBoundSetter
    method isIgnoreFailedBuilds (line 1321) | public boolean isIgnoreFailedBuilds() {
    method setIgnoreUnstableBuilds (line 1325) | @DataBoundSetter
    method isIgnoreUnstableBuilds (line 1330) | public boolean isIgnoreUnstableBuilds() {
    method isPersistConstraintLog (line 1334) | public boolean isPersistConstraintLog() {
    method setPersistConstraintLog (line 1338) | @DataBoundSetter
    method isModeEvaluation (line 1343) | public boolean isModeEvaluation() {
    method setModeEvaluation (line 1347) | @DataBoundSetter
    method setShowTrendGraphs (line 1352) | @DataBoundSetter
    method isShowTrendGraphs (line 1357) | public boolean isShowTrendGraphs() {
    method getShowTrendGraphs (line 1361) | public boolean getShowTrendGraphs() {
    method getSourceDataFiles (line 1365) | public String getSourceDataFiles() {
    method setSourceDataFiles (line 1369) | public void setSourceDataFiles(String sourceDataFiles) {
    method getParsers (line 1373) | public List<PerformanceReportParser> getParsers() {
    method setParsers (line 1377) | @DataBoundSetter
    method isExcludeResponseTime (line 1383) | public boolean isExcludeResponseTime() {
    method setExcludeResponseTime (line 1387) | @DataBoundSetter
    method getJunitOutput (line 1392) | public String getJunitOutput() {
    method setJunitOutput (line 1396) | @DataBoundSetter
    method getPercentiles (line 1401) | public String getPercentiles() {
    method setPercentiles (line 1405) | @DataBoundSetter
    method getBaselineBuild (line 1411) | public int getBaselineBuild() {
    method setBaselineBuild (line 1415) | @DataBoundSetter
    method addAliases (line 1423) | @Initializer(before = InitMilestone.PLUGINS_STARTED)
    class DescriptorImpl (line 1505) | @Symbol({"perfReport", "performanceReport"})
      method getDisplayName (line 1508) | @Override
      method getHelpFile (line 1513) | @Override
      method getParserDescriptors (line 1518) | public List<PerformanceReportParserDescriptor> getParserDescriptors() {
      method getConstraintDescriptors (line 1522) | public List<ConstraintDescriptor> getConstraintDescriptors() {
      method isApplicable (line 1526) | @Override
      method doFillConfigTypeItems (line 1537) | public ListBoxModel doFillConfigTypeItems() {
      method doFillGraphTypeItems (line 1541) | public ListBoxModel doFillGraphTypeItems() {
      method getResponseTimeOptions (line 1545) | private ListBoxModel getResponseTimeOptions() {
    method getFilterRegex (line 1557) | public String getFilterRegex() {
    method setFilterRegex (line 1564) | @DataBoundSetter

FILE: src/main/java/hudson/plugins/performance/PerformanceReportMap.java
  class PerformanceReportMap (line 48) | public class PerformanceReportMap implements ModelObject {
    method PerformanceReportMap (line 66) | public PerformanceReportMap(final PerformanceBuildAction buildAction,
    method PerformanceReportMap (line 76) | public PerformanceReportMap(final PerformanceBuildAction buildAction,
    method addAll (line 96) | private void addAll(Collection<PerformanceReport> reports) {
    method getBuild (line 103) | public Run<?, ?> getBuild() {
    method getBuildAction (line 107) | PerformanceBuildAction getBuildAction() {
    method getDisplayName (line 111) | public String getDisplayName() {
    method getPerformanceListOrdered (line 115) | public List<PerformanceReport> getPerformanceListOrdered() {
    method getPublisher (line 122) | protected PerformancePublisher getPublisher() {
    method ifModeThroughputUsed (line 137) | public boolean ifModeThroughputUsed() {
    method ifShowTrendGraphsUsed (line 142) | public boolean ifShowTrendGraphsUsed() {
    method ifModePerformancePerTestCaseUsed (line 147) | public boolean ifModePerformancePerTestCaseUsed() {
    method getPerformanceReportMap (line 152) | public Map<String, PerformanceReport> getPerformanceReportMap() {
    method getPerformanceReport (line 164) | public PerformanceReport getPerformanceReport(String performanceReport...
    method getUriReport (line 174) | public UriReport getUriReport(String uriReport) {
    method getUrlName (line 194) | public String getUrlName() {
    method setBuildAction (line 198) | public void setBuildAction(PerformanceBuildAction buildAction) {
    method setPerformanceReportMap (line 202) | public void setPerformanceReportMap(
    method getPerformanceReportFileRelativePath (line 207) | public static String getPerformanceReportFileRelativePath(
    method getPerformanceReportDirRelativePath (line 212) | public static String getPerformanceReportDirRelativePath() {
    method getRelativePath (line 216) | private static String getRelativePath(String... suffixes) {
    method isFailed (line 234) | public boolean isFailed(String performanceReportName) {
    method doRespondingTimeGraph (line 238) | public void doRespondingTimeGraph(StaplerRequest request,
    method doThroughputGraph (line 263) | public void doThroughputGraph(StaplerRequest request, StaplerResponse ...
    method createThroughputChart (line 303) | protected JFreeChart createThroughputChart(CategoryDataset dataset) {
    method doRespondingTimeGraphPerTestCaseMode (line 308) | public void doRespondingTimeGraphPerTestCaseMode(
    method doErrorsGraph (line 357) | public void doErrorsGraph(StaplerRequest request, StaplerResponse resp...
    method createErrorsChart (line 398) | protected JFreeChart createErrorsChart(CategoryDataset dataset) {
    method createRespondingTimeChart (line 403) | protected JFreeChart createRespondingTimeChart(CategoryDataset dataset...
    method getKeyLabel (line 407) | private String getKeyLabel(String configType) {
    method getBuildReports (line 415) | private Map<Run<?, ?>, Map<String, PerformanceReport>> getBuildReports...
    method doSummarizerGraph (line 439) | public void doSummarizerGraph(StaplerRequest request, StaplerResponse ...
    method createSummarizerChart (line 465) | protected JFreeChart createSummarizerChart(CategoryDataset dataset) {
    method parseReports (line 469) | protected void parseReports(Run<?, ?> build, TaskListener listener,
    method addPreviousBuildReports (line 530) | private void addPreviousBuildReports() {
    method getReportMap (line 543) | protected PerformanceReportMap getReportMap(Run<?, ?> build) {
    method getPerformanceReportForBuild (line 556) | protected PerformanceReport getPerformanceReportForBuild(Run<?, ?> bui...
    method getBuild (line 565) | protected Run<?, ?> getBuild(int buildNumber) {
    type PerformanceReportCollector (line 573) | protected interface PerformanceReportCollector {
      method addAll (line 575) | void addAll(Collection<PerformanceReport> parse);
    method getDynamic (line 578) | public Object getDynamic(final String link, final StaplerRequest request,
    method createTrendReportGraphs (line 587) | public Object createTrendReportGraphs(final StaplerRequest request) {
    method getTrendReportFilename (line 602) | private String getTrendReportFilename(final StaplerRequest request) {

FILE: src/main/java/hudson/plugins/performance/TrendReportGraphs.java
  class TrendReportGraphs (line 16) | public class TrendReportGraphs implements ModelObject {
    method TrendReportGraphs (line 23) | public TrendReportGraphs(final Job<?, ?> project,
    method getUriReportForRequest (line 32) | private UriReport getUriReportForRequest(StaplerRequest request) {
    method doRespondingTimeGraph (line 49) | public void doRespondingTimeGraph(StaplerRequest request,
    method doPercentileGraph (line 57) | public void doPercentileGraph(StaplerRequest request,
    method doThroughputGraph (line 65) | public void doThroughputGraph(StaplerRequest request,
    method doErrorGraph (line 73) | public void doErrorGraph(StaplerRequest request,
    method getUris (line 81) | public ArrayList<String> getUris() {
    method getUriReport (line 91) | public UriReport getUriReport(String uri) {
    method getDisplayName (line 100) | public String getDisplayName() {
    method getFilename (line 104) | public String getFilename() {
    method getProject (line 108) | public Job<?, ?> getProject() {
    method getBuild (line 112) | public Run<?, ?> getBuild() {
    method hasSamples (line 116) | public boolean hasSamples(String uri) {
    method getPerformanceReport (line 121) | public PerformanceReport getPerformanceReport() {

FILE: src/main/java/hudson/plugins/performance/actions/ExternalBuildReportAction.java
  class ExternalBuildReportAction (line 7) | public class ExternalBuildReportAction implements Action, StaplerProxy {
    method ExternalBuildReportAction (line 10) | public ExternalBuildReportAction(String reportURL) {
    method getIconFileName (line 14) | @Override
    method getDisplayName (line 19) | @Override
    method getUrlName (line 24) | @Override
    method getTarget (line 29) | @Override

FILE: src/main/java/hudson/plugins/performance/actions/PerformanceBuildAction.java
  class PerformanceBuildAction (line 18) | public class PerformanceBuildAction implements Action, StaplerProxy {
    method PerformanceBuildAction (line 34) | public PerformanceBuildAction(Run<?, ?> pBuild, PrintStream logger,
    method getParserByDisplayName (line 41) | public PerformanceReportParser getParserByDisplayName(String displayNa...
    method getDisplayName (line 49) | public String getDisplayName() {
    method getIconFileName (line 53) | public String getIconFileName() {
    method getUrlName (line 57) | public String getUrlName() {
    method getTarget (line 61) | public PerformanceReportMap getTarget() {
    method getBuild (line 65) | public Run<?, ?> getBuild() {
    method getHudsonConsoleWriter (line 69) | public PrintStream getHudsonConsoleWriter() {
    method getPerformanceReportMap (line 73) | public synchronized PerformanceReportMap getPerformanceReportMap() {
    method getPerformanceReportMap (line 77) | public synchronized PerformanceReportMap getPerformanceReportMap(boole...
    method setPerformanceReportMap (line 97) | public synchronized void setPerformanceReportMap(WeakReference<Perform...

FILE: src/main/java/hudson/plugins/performance/actions/PerformanceProjectAction.java
  class PerformanceProjectAction (line 66) | public class PerformanceProjectAction implements Action {
    method getDisplayName (line 87) | public String getDisplayName() {
    method getIconFileName (line 91) | public String getIconFileName() {
    method getUrlName (line 95) | public String getUrlName() {
    method PerformanceProjectAction (line 99) | public PerformanceProjectAction(Job<?, ?> job) {
    method createErrorsChart (line 103) | public static JFreeChart createErrorsChart(CategoryDataset dataset) {
    method doCreateRespondingTimeChart (line 154) | public static JFreeChart doCreateRespondingTimeChart(CategoryDataset d...
    method createThroughputChart (line 203) | public static JFreeChart createThroughputChart(final CategoryDataset d...
    method doCreateSummarizerChart (line 248) | public static JFreeChart doCreateSummarizerChart(CategoryDataset dataset,
    method createSummarizerTrend (line 282) | public static JFreeChart createSummarizerTrend(
    method createUriPercentileChart (line 317) | public static JFreeChart createUriPercentileChart(XYDataset dataset, S...
    method createUriThroughputChart (line 342) | public static JFreeChart createUriThroughputChart(IntervalXYDataset da...
    method getPerformanceReportNameFile (line 368) | private String getPerformanceReportNameFile(StaplerRequest request) {
    method getPerformanceReportNameFile (line 374) | private String getPerformanceReportNameFile(final PerformanceReportPos...
    method doErrorsGraph (line 382) | public void doErrorsGraph(StaplerRequest request, StaplerResponse resp...
    method createErrorsGraph (line 433) | protected JFreeChart createErrorsGraph(CategoryDataset dataset) {
    method doRespondingTimeGraphPerTestCaseMode (line 437) | public void doRespondingTimeGraphPerTestCaseMode(
    method getPerformanceReport (line 487) | protected PerformanceReport getPerformanceReport(Run<?, ?> build, Stri...
    method createRespondingTimeChart (line 497) | protected JFreeChart createRespondingTimeChart(CategoryDataset dataset...
    method doRespondingTimeGraph (line 501) | public void doRespondingTimeGraph(StaplerRequest request, StaplerRespo...
    method doThroughputGraph (line 560) | public void doThroughputGraph(final StaplerRequest request, final Stap...
    method createThroughputGraph (line 611) | protected JFreeChart createThroughputGraph(CategoryDataset dataset) {
    method doSummarizerGraph (line 615) | public void doSummarizerGraph(StaplerRequest request, StaplerResponse ...
    method createSummarizerChart (line 676) | protected JFreeChart createSummarizerChart(CategoryDataset dataset, St...
    method getFirstAndLastBuild (line 689) | private Range getFirstAndLastBuild(StaplerRequest request, List<?> bui...
    method all (line 749) | public Range all(List<?> builds) {
    method getJob (line 753) | public Job<?, ?> getJob() {
    method getSomeBuildWithWorkspace (line 757) | public final Run<?, ?> getSomeBuildWithWorkspace() {
    method getPerformanceReportList (line 775) | @NonNull
    method setPerformanceReportList (line 822) | public void setPerformanceReportList(List<String> performanceReportLis...
    method isTrendVisibleOnProjectDashboard (line 826) | public boolean isTrendVisibleOnProjectDashboard() {
    method getDynamic (line 838) | public Object getDynamic(final String link, final StaplerRequest request,
    method createUserConfiguration (line 857) | private Object createUserConfiguration(final StaplerRequest request) {
    method createTrendReport (line 867) | private Object createTrendReport(final StaplerRequest request) {
    method createTestsuiteReport (line 873) | private Object createTestsuiteReport(final StaplerRequest request) {
    method getTrendReportFilename (line 879) | private String getTrendReportFilename(final StaplerRequest request) {
    method getTestSuiteReportFilename (line 885) | private String getTestSuiteReportFilename(final StaplerRequest request) {
    method getTrendReportData (line 891) | private DataSetBuilder<String, NumberOnlyBuildLabel> getTrendReportDat...
    method ifSummarizerParserUsed (line 937) | public boolean ifSummarizerParserUsed(String filename) {
    method ifModePerformancePerTestCaseUsed (line 944) | public boolean ifModePerformancePerTestCaseUsed() {
    method ifModeThroughputUsed (line 955) | public boolean ifModeThroughputUsed() {
    class Range (line 966) | public static class Range {
      method Range (line 974) | public Range(int first, int last) {
      method Range (line 980) | public Range(int first, int last, int step) {
      method in (line 985) | public boolean in(int nbBuildsToAnalyze) {
      method includedByStep (line 989) | public boolean includedByStep(int buildNumber) {

FILE: src/main/java/hudson/plugins/performance/build/PerformanceTestBuild.java
  class PerformanceTestBuild (line 39) | public class PerformanceTestBuild extends Builder implements SimpleBuild...
    class Descriptor (line 58) | @Symbol({"bzt","performanceTest"})
      method isApplicable (line 62) | @Override
      method getDisplayName (line 67) | @Override
    method PerformanceTestBuild (line 89) | @DataBoundConstructor
    method readResolve (line 97) | public Object readResolve() {
    method getProjectAction (line 106) | @Override
    method perform (line 112) | @Override
    method addPipelineEnvVars (line 158) | private void addPipelineEnvVars(Run<?, ?> run, EnvVars envVars) {
    method addEnvVars (line 171) | private void addEnvVars(Action action, EnvVars envVars) {
    method getVirtualenvWorkspace (line 182) | private FilePath getVirtualenvWorkspace(Run<?, ?> run, FilePath worksp...
    method createTemporaryWorkspace (line 188) | private FilePath createTemporaryWorkspace(Run<?, ?> run, FilePath work...
    method configJobName (line 201) | private String configJobName(String displayName) {
    method getBztWorkingDirectory (line 205) | protected FilePath getBztWorkingDirectory(FilePath jobWorkspace) {
    method isAbsoluteFilePath (line 216) | private boolean isAbsoluteFilePath() {
    method generatePerformanceTrend (line 220) | protected void generatePerformanceTrend(String path, Run<?, ?> run, Fi...
    method installBztAndCheck (line 225) | private boolean installBztAndCheck(FilePath workspace, PrintStream log...
    method installBzt (line 230) | private boolean installBzt(FilePath workspace, PrintStream logger, Lau...
    method createVirtualenvAndInstallBzt (line 235) | private boolean createVirtualenvAndInstallBzt(FilePath workspace, Prin...
    method isGlobalBztInstalled (line 241) | private boolean isGlobalBztInstalled(FilePath workspace, PrintStream l...
    method isVirtualenvInstalled (line 252) | private boolean isVirtualenvInstalled(FilePath workspace, PrintStream ...
    method createIsolatedPython (line 267) | private boolean createIsolatedPython(FilePath workspace, PrintStream l...
    method installBztInVirtualenv (line 285) | private boolean installBztInVirtualenv(FilePath workspace, PrintStream...
    method isVirtualenvBztInstalled (line 300) | private boolean isVirtualenvBztInstalled(FilePath workspace, PrintStre...
    method runPerformanceTest (line 315) | private int runPerformanceTest(FilePath bztWorkingDirectory, FilePath ...
    method isSuccessCode (line 342) | public boolean isSuccessCode(int code) {
    method getJobResult (line 346) | public Result getJobResult(int code) {
    method getBztJobResult (line 355) | public Result getBztJobResult(int code) {
    method getVirtualenvPath (line 365) | private String getVirtualenvPath(FilePath workspace) {
    method getBztInstallCommand (line 372) | private String[] getBztInstallCommand(FilePath workspace) throws IOExc...
    method getInstallCommand (line 377) | private String getInstallCommand(FilePath workspace) throws IOExceptio...
    method isURLToFile (line 387) | private boolean isURLToFile() {
    method isPathToFile (line 400) | private boolean isPathToFile(FilePath workspace) throws IOException, I...
    method getBztCheckCommand (line 405) | private String[] getBztCheckCommand(FilePath workspace) {
    method getVirtualEnvCommand (line 409) | private String getVirtualEnvCommand(EnvVars envVars) {
    method runCmd (line 413) | public int runCmd(String[] commands, FilePath workspace, OutputStream ...
    method extractDefaultReportToWorkingDirectory (line 428) | protected String extractDefaultReportToWorkingDirectory(FilePath worki...
    method getParams (line 437) | public String getParams() {
    method setParams (line 441) | public void setParams(String params) {
    method isPrintDebugOutput (line 445) | public boolean isPrintDebugOutput() {
    method isAlwaysUseVirtualenv (line 449) | public boolean isAlwaysUseVirtualenv() {
    method setAlwaysUseVirtualenv (line 453) | @DataBoundSetter
    method setPrintDebugOutput (line 458) | @DataBoundSetter
    method isUseSystemSitePackages (line 463) | public boolean isUseSystemSitePackages() {
    method setUseSystemSitePackages (line 467) | @DataBoundSetter
    method isGeneratePerformanceTrend (line 472) | public boolean isGeneratePerformanceTrend() {
    method setGeneratePerformanceTrend (line 476) | @DataBoundSetter
    method isUseBztExitCode (line 481) | public boolean isUseBztExitCode() {
    method setUseBztExitCode (line 485) | @DataBoundSetter
    method getWorkspace (line 490) | public String getWorkspace() {
    method setWorkspace (line 494) | @DataBoundSetter
    method getBztVersion (line 500) | public String getBztVersion() {
    method setBztVersion (line 504) | @DataBoundSetter
    method getWorkingDirectory (line 509) | public String getWorkingDirectory() {
    method setWorkingDirectory (line 513) | @DataBoundSetter
    method getVirtualEnvCommand (line 518) | public String getVirtualEnvCommand() {
    method setVirtualEnvCommand (line 522) | @DataBoundSetter

FILE: src/main/java/hudson/plugins/performance/constraints/AbsoluteConstraint.java
  class AbsoluteConstraint (line 26) | public class AbsoluteConstraint extends AbstractConstraint {
    class DescriptorImpl (line 33) | @Symbol("absolute")
      method getDisplayName (line 37) | @Override
      method doCheckRelatedPerfReport (line 42) | public FormValidation doCheckRelatedPerfReport(@QueryParameter Strin...
      method doCheckTestCase (line 49) | public FormValidation doCheckTestCase(@QueryParameter String testCas...
    method AbsoluteConstraint (line 58) | @DataBoundConstructor
    method clone (line 70) | @SuppressFBWarnings("CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE")
    method evaluate (line 79) | @Override
    method check (line 108) | private ConstraintEvaluation check(double newValue) {
    method getValue (line 145) | public long getValue() {
    method setValue (line 149) | public void setValue(long value) {

FILE: src/main/java/hudson/plugins/performance/constraints/AbstractConstraint.java
  class AbstractConstraint (line 26) | public abstract class AbstractConstraint implements Describable<Abstract...
    method getDescriptor (line 70) | public ConstraintDescriptor getDescriptor() {
    method all (line 74) | public static ExtensionList<AbstractConstraint> all() {
    method AbstractConstraint (line 78) | protected AbstractConstraint(Metric meteredValue, Operator operator, S...
    method clone (line 95) | public abstract AbstractConstraint clone();
    method evaluate (line 108) | public abstract ConstraintEvaluation evaluate(List<? extends Run<?, ?>...
    method checkMetredValueforUriReport (line 118) | protected double checkMetredValueforUriReport(Metric meteredValue, Uri...
    method checkMetredValueforPerfReport (line 146) | protected double checkMetredValueforPerfReport(Metric meteredValue, Pe...
    method checkForDefectiveParams (line 173) | protected void checkForDefectiveParams(List<? extends Run<?, ?>> build...
    type Metric (line 220) | public enum Metric {
      method Metric (line 226) | private Metric(final String text, boolean isSelected) {
      method toString (line 231) | @Override
      method isSelected (line 236) | public boolean isSelected() {
    type Escalation (line 242) | public enum Escalation {
      method Escalation (line 248) | private Escalation(final String text, boolean isSelected) {
      method toString (line 253) | @Override
      method isSelected (line 258) | public boolean isSelected() {
    type Operator (line 264) | public enum Operator {
      method Operator (line 270) | private Operator(final String text, boolean isSelected) {
      method toString (line 275) | @Override
      method isSelected (line 280) | public boolean isSelected() {
    method setSuccess (line 286) | public void setSuccess(boolean success) {
    method getSuccess (line 290) | public boolean getSuccess() {
    method getResultMessage (line 294) | public String getResultMessage() {
    method setResultMessage (line 298) | public void setResultMessage(String resultMessage) {
    method getJunitResult (line 302) | public String getJunitResult() {
    method setJunitResult (line 306) | public void setJunitResult(String junitResult) {
    method getRelatedPerfReport (line 310) | public String getRelatedPerfReport() {
    method setRelatedPerfReport (line 314) | public void setRelatedPerfReport(String relatedPerfReport) {
    method getMeteredValue (line 318) | public Metric getMeteredValue() {
    method setMeteredValue (line 322) | public void setMeteredValue(Metric meteredValue) {
    method getOperator (line 326) | public Operator getOperator() {
    method setOperator (line 330) | public void setOperator(Operator operator) {
    method getEscalationLevel (line 334) | public Escalation getEscalationLevel() {
    method setEscalationLevel (line 338) | public void setEscalationLevel(Escalation escalationLevel) {
    method getTestCaseBlock (line 342) | public TestCaseBlock getTestCaseBlock() {
    method setTestCaseBlock (line 346) | public void setTestCaseBlock(TestCaseBlock testCaseBlock) {
    method isSpecifiedTestCase (line 350) | public boolean isSpecifiedTestCase() {
    method setSpecifiedTestCase (line 354) | public void setSpecifiedTestCase(boolean isSpecifiedTestCase) {
    method getSettings (line 358) | public ConstraintSettings getSettings() {
    method setSettings (line 362) | public void setSettings(ConstraintSettings settings) {
    method getTestCase (line 366) | public String getTestCase() {
    method setTestCase (line 374) | public void setTestCase(String testCase) {

FILE: src/main/java/hudson/plugins/performance/constraints/ConstraintChecker.java
  class ConstraintChecker (line 17) | public class ConstraintChecker {
    method ConstraintChecker (line 28) | public ConstraintChecker(ConstraintSettings settings, List<? extends R...
    method checkAllConstraints (line 46) | public ArrayList<ConstraintEvaluation> checkAllConstraints(List<? exte...
    method getSettings (line 61) | public ConstraintSettings getSettings() {
    method setSettings (line 65) | public void setSettings(ConstraintSettings settings) {
    method getBuilds (line 69) | public List<? extends Run<?, ?>> getBuilds() {
    method setBuilds (line 73) | public void setBuilds(List<? extends Run<?, ?>> builds) {

FILE: src/main/java/hudson/plugins/performance/constraints/ConstraintEvaluation.java
  class ConstraintEvaluation (line 8) | public class ConstraintEvaluation {
    method ConstraintEvaluation (line 14) | public ConstraintEvaluation(AbstractConstraint constraint, double resu...
    method ConstraintEvaluation (line 20) | public ConstraintEvaluation() {
    method getConstraintValue (line 23) | public double getConstraintValue() {
    method setConstraintValue (line 27) | public void setConstraintValue(double constraintValue) {
    method getMeasuredValue (line 31) | public double getMeasuredValue() {
    method setMeasuredValue (line 35) | public void setMeasuredValue(double measuredValue) {
    method getAbstractConstraint (line 39) | public AbstractConstraint getAbstractConstraint() {
    method setAbstractConstraint (line 43) | public void setAbstractConstraint(AbstractConstraint abstractConstrain...

FILE: src/main/java/hudson/plugins/performance/constraints/ConstraintFactory.java
  class ConstraintFactory (line 19) | public class ConstraintFactory {
    method createConstraintClones (line 28) | public List<? extends AbstractConstraint> createConstraintClones(Run<?...

FILE: src/main/java/hudson/plugins/performance/constraints/RelativeConstraint.java
  class RelativeConstraint (line 38) | public class RelativeConstraint extends AbstractConstraint {
    class DescriptorImpl (line 79) | @Symbol("relative")
      method getDisplayName (line 83) | @Override
      method doCheckRelatedPerfReport (line 89) | public FormValidation doCheckRelatedPerfReport(@QueryParameter Strin...
      method doCheckTestCase (line 96) | public FormValidation doCheckTestCase(@QueryParameter String testCas...
      method doCheckTimeframeStartString (line 103) | public FormValidation doCheckTimeframeStartString(@QueryParameter St...
      method doCheckTimeframeEndString (line 107) | public FormValidation doCheckTimeframeEndString(@QueryParameter Stri...
      method dateCheck (line 114) | private FormValidation dateCheck(String dateString) {
      method doCheckPreviousResultsString (line 131) | public FormValidation doCheckPreviousResultsString(@QueryParameter S...
    method RelativeConstraint (line 211) | @DataBoundConstructor
    method clone (line 263) | @SuppressFBWarnings("CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE")
    method evaluate (line 272) | @Override
    method check (line 301) | private ConstraintEvaluation check(List<? extends Run<?, ?>> builds, d...
    method calcAveOfReports (line 369) | private long calcAveOfReports(List<? extends Run<?, ?>> builds) {
    method evaluateDate (line 427) | private List<Run<?, ?>> evaluateDate(List<? extends Run<?, ?>> builds) {
    method evaluatePreviousBuilds (line 462) | private List<Run<?, ?>> evaluatePreviousBuilds(List<? extends Run<?, ?...
    method getUriValue (line 488) | private double getUriValue(PerformanceReport pr) {
    method getPreviousResults (line 498) | public int getPreviousResults() {
    method setPreviousResults (line 502) | public void setPreviousResults(int previousResults) {
    method getTolerance (line 506) | public double getTolerance() {
    method setTolerance (line 510) | public void setTolerance(double d) {
    method getChoicePreviousResults (line 514) | public boolean getChoicePreviousResults() {
    method setChoicePreviousResults (line 518) | public void setChoicePreviousResults(boolean choicePreviousResults) {
    method getTimeframeStartString (line 522) | public String getTimeframeStartString() {
    method setTimeframeStartString (line 526) | public void setTimeframeStartString(String timeframeStartString) {
    method getTimeframeEndString (line 530) | public String getTimeframeEndString() {
    method setTimeframeEndString (line 534) | public void setTimeframeEndString(String timeframeEndString) {
    method getTimeframeStart (line 538) | public Date getTimeframeStart() {
    method setTimeframeStart (line 542) | public void setTimeframeStart(Date timeframeStart) {
    method getTimeframeEnd (line 546) | public Date getTimeframeEnd() {
    method setTimeframeEnd (line 550) | public void setTimeframeEnd(Date timeframeEnd) {
    method getPreviousResultsBlock (line 554) | public PreviousResultsBlock getPreviousResultsBlock() {
    method setPreviousResultsBlock (line 558) | public void setPreviousResultsBlock(PreviousResultsBlock previousResul...
    method getPreviousResultsString (line 562) | public String getPreviousResultsString() {
    method setPreviousResultsString (line 566) | public void setPreviousResultsString(String previousResultsString) {

FILE: src/main/java/hudson/plugins/performance/constraints/blocks/PreviousResultsBlock.java
  class PreviousResultsBlock (line 15) | public class PreviousResultsBlock extends AbstractDescribableImpl<Previo...
    class DescriptorImpl (line 37) | @Symbol("previous")
      method getDisplayName (line 40) | @Override
    method PreviousResultsBlock (line 46) | @DataBoundConstructor
    method isChoicePreviousResults (line 54) | public boolean isChoicePreviousResults() {
    method setChoicePreviousResults (line 58) | public void setChoicePreviousResults(boolean choicePreviousResults) {
    method isChoiceTimeframe (line 62) | public boolean isChoiceTimeframe() {
    method isChoiceBaselineBuild (line 66) | public boolean isChoiceBaselineBuild() {
    method getValue (line 71) | public String getValue() {
    method setValue (line 75) | public void setValue(String value) {
    method getPreviousResultsString (line 79) | public String getPreviousResultsString() {
    method setPreviousResultsString (line 83) | public void setPreviousResultsString(String previousResultsString) {
    method getTimeframeStartString (line 87) | public String getTimeframeStartString() {
    method setTimeframeStartString (line 91) | public void setTimeframeStartString(String timeframeStartString) {
    method getTimeframeEndString (line 95) | public String getTimeframeEndString() {
    method setTimeframeEndString (line 99) | public void setTimeframeEndString(String timeframeEndString) {

FILE: src/main/java/hudson/plugins/performance/constraints/blocks/TestCaseBlock.java
  class TestCaseBlock (line 15) | public class TestCaseBlock extends AbstractDescribableImpl<TestCaseBlock> {
    class DescriptorImpl (line 18) | @Symbol("testCase")
      method getDisplayName (line 21) | @Override
    method TestCaseBlock (line 27) | @DataBoundConstructor
    method getTestCase (line 32) | public String getTestCase() {
    method setTestCase (line 36) | public void setTestCase(String testCase) {

FILE: src/main/java/hudson/plugins/performance/cookie/CookieHandler.java
  class CookieHandler (line 14) | public class CookieHandler {
    method CookieHandler (line 29) | public CookieHandler(final String name) {
    method create (line 40) | public Cookie create(final List<Ancestor> requestAncestors, final Stri...
    method getValue (line 56) | public String getValue(final Cookie[] cookies) {

FILE: src/main/java/hudson/plugins/performance/data/ConstraintSettings.java
  class ConstraintSettings (line 10) | public class ConstraintSettings {
    method ConstraintSettings (line 37) | public ConstraintSettings(TaskListener listener, boolean ignoreFailedB...
    method getListener (line 46) | public TaskListener getListener() {
    method setListener (line 50) | private void setListener(TaskListener listener) {
    method isIgnoreFailedBuilds (line 54) | public boolean isIgnoreFailedBuilds() {
    method setIgnoreFailedBuilds (line 58) | public void setIgnoreFailedBuilds(boolean ignoreFailedBuilds) {
    method isIgnoreUnstableBuilds (line 62) | public boolean isIgnoreUnstableBuilds() {
    method setIgnoreUnstableBuilds (line 66) | public void setIgnoreUnstableBuilds(boolean ignoreUnstableBuilds) {
    method isPersistConstraintLog (line 70) | public boolean isPersistConstraintLog() {
    method setPersistConstraintLog (line 74) | public void setPersistConstraintLog(boolean persistConstraintLog) {
    method getBaselineBuild (line 78) | public int getBaselineBuild() {
    method setBaselineBuild (line 82) | public void setBaselineBuild(int baselineBuild) {

FILE: src/main/java/hudson/plugins/performance/data/HttpSample.java
  class HttpSample (line 14) | public class HttpSample implements Serializable, Comparable<HttpSample> {
    method getDuration (line 43) | public long getDuration() {
    method getDate (line 47) | public Date getDate() {
    method getUri (line 51) | public String getUri() {
    method getHttpCode (line 55) | public String getHttpCode() {
    method getSummarizerSamples (line 59) | public long getSummarizerSamples() {
    method getSummarizerMin (line 63) | public long getSummarizerMin() {
    method getSummarizerMax (line 67) | public long getSummarizerMax() {
    method getSummarizerErrors (line 71) | public float getSummarizerErrors() {
    method isFailed (line 75) | public boolean isFailed() {
    method isSuccessful (line 79) | public boolean isSuccessful() {
    method setDuration (line 83) | public void setDuration(long duration) {
    method setSuccessful (line 87) | public void setSuccessful(boolean successful) {
    method setErrorObtained (line 91) | public void setErrorObtained(boolean errorObtained) {
    method hasError (line 95) | public boolean hasError() {
    method setDate (line 99) | public void setDate(Date time) {
    method setUri (line 103) | public void setUri(String uri) {
    method setHttpCode (line 107) | public void setHttpCode(String httpCode) {
    method setSummarizerSamples (line 111) | public void setSummarizerSamples(long summarizerSamples) {
    method setSummarizerMin (line 115) | public void setSummarizerMin(long summarizerMin) {
    method setSummarizerMax (line 119) | public void setSummarizerMax(long summarizerMax) {
    method setSummarizerErrors (line 123) | public void setSummarizerErrors(float summarizerErrors) {
    method compareTo (line 127) | public int compareTo(HttpSample o) {
    method equals (line 131) | @Override
    method hashCode (line 139) | @Override
    method getSizeInKb (line 144) | public double getSizeInKb() {
    method setSizeInKb (line 148) | public void setSizeInKb(double d) {
    method isErrorObtained (line 152) | public boolean isErrorObtained() {
    method isSummarizer (line 156) | public boolean isSummarizer() {
    method setSummarizer (line 160) | public void setSummarizer(boolean summarizer) {

FILE: src/main/java/hudson/plugins/performance/data/PerformanceReportPosition.java
  class PerformanceReportPosition (line 3) | public class PerformanceReportPosition {
    method getPerformanceReportPosition (line 8) | public String getPerformanceReportPosition() {
    method getSummarizerReportType (line 12) | public String getSummarizerReportType() {
    method getSummarizerTrendUri (line 16) | public String getSummarizerTrendUri() {
    method setPerformanceReportPosition (line 20) | public void setPerformanceReportPosition(String performanceReportPosit...
    method setSummarizerReportType (line 24) | public void setSummarizerReportType(String summarizerReportType) {
    method setSummarizerTrendUri (line 28) | public void setSummarizerTrendUri(String summarizerTrendUri) {

FILE: src/main/java/hudson/plugins/performance/data/ReportValueSelector.java
  class ReportValueSelector (line 8) | public abstract class ReportValueSelector {
    method getValue (line 10) | public abstract long getValue(AbstractReport report);
    method getGraphType (line 12) | public abstract String getGraphType();
    method get (line 14) | public static ReportValueSelector get(Job<?, ?> job) {
    method get (line 23) | public static ReportValueSelector get(PerformancePublisher publisher) {
    class SelectAverage (line 37) | private static class SelectAverage extends ReportValueSelector {
      method getValue (line 39) | @Override
      method getGraphType (line 44) | @Override
    class SelectMedian (line 50) | private static class SelectMedian extends ReportValueSelector {
      method getValue (line 52) | @Override
      method getGraphType (line 57) | @Override
    class SelectPercentile (line 63) | private static class SelectPercentile extends ReportValueSelector {
      method getValue (line 65) | @Override
      method getGraphType (line 70) | @Override

FILE: src/main/java/hudson/plugins/performance/data/TaurusFinalStats.java
  class TaurusFinalStats (line 5) | public class TaurusFinalStats implements Serializable {
    method getLabel (line 29) | public String getLabel() {
    method setLabel (line 33) | public void setLabel(String label) {
    method getSucc (line 37) | public int getSucc() {
    method setSucc (line 41) | public void setSucc(int succ) {
    method getFail (line 45) | public int getFail() {
    method setFail (line 49) | public void setFail(int fail) {
    method getAverageResponseTime (line 53) | public double getAverageResponseTime() {
    method setAverageResponseTime (line 57) | public void setAverageResponseTime(double averageResponseTime) {
    method getBytes (line 61) | public long getBytes() {
    method setBytes (line 65) | public void setBytes(long bytes) {
    method getPerc50 (line 69) | public double getPerc50() {
    method setPerc50 (line 73) | public void setPerc50(double perc50) {
    method getPerc90 (line 77) | public double getPerc90() {
    method getPerc95 (line 81) | public double getPerc95() {
    method setPerc90 (line 85) | public void setPerc90(double perc90) {
    method setPerc95 (line 89) | public void setPerc95(double perc95) {
    method getPerc0 (line 93) | public double getPerc0() {
    method setPerc0 (line 97) | public void setPerc0(double perc0) {
    method getPerc100 (line 101) | public double getPerc100() {
    method setPerc100 (line 105) | public void setPerc100(double perc100) {
    method getThroughput (line 109) | public long getThroughput() {
    method setThroughput (line 113) | public void setThroughput(long throughput) {
    method getTestDuration (line 117) | public Double getTestDuration() {
    method setTestDuration (line 121) | public void setTestDuration(Double testDuration) {

FILE: src/main/java/hudson/plugins/performance/descriptors/ConstraintDescriptor.java
  class ConstraintDescriptor (line 8) | public abstract class ConstraintDescriptor extends Descriptor<AbstractCo...
    method getId (line 10) | public final String getId() {
    method all (line 14) | public static DescriptorExtensionList<AbstractConstraint, ConstraintDe...
    method getById (line 18) | public static ConstraintDescriptor getById(String id) {

FILE: src/main/java/hudson/plugins/performance/descriptors/PerformanceReportParserDescriptor.java
  class PerformanceReportParserDescriptor (line 11) | public abstract class PerformanceReportParserDescriptor extends
    method getId (line 17) | public final String getId() {
    method all (line 24) | public static DescriptorExtensionList<PerformanceReportParser, Perform...
    method getById (line 28) | public static PerformanceReportParserDescriptor getById(String id) {

FILE: src/main/java/hudson/plugins/performance/details/GraphConfigurationDetail.java
  class GraphConfigurationDetail (line 36) | public class GraphConfigurationDetail implements ModelObject {
    method isNone (line 81) | public boolean isNone() {
    method isBuildCount (line 85) | public boolean isBuildCount() {
    method isBuildNth (line 89) | public boolean isBuildNth() {
    method isDate (line 93) | public boolean isDate() {
    method isDefaultDates (line 97) | public boolean isDefaultDates() {
    method GraphConfigurationDetail (line 102) | public GraphConfigurationDetail(final Job<?, ?> project,
    method doSave (line 129) | public void doSave(final StaplerRequest request,
    method getDisplayName (line 185) | public String getDisplayName() {
    method createCookieHandler (line 196) | private static CookieHandler createCookieHandler(final String cookieNa...
    method persistValue (line 200) | protected void persistValue(final String value, final StaplerRequest r...
    method serializeToString (line 224) | protected String serializeToString(final String configType,
    method createDefaultsFile (line 238) | protected static File createDefaultsFile(final Job<?, ?> project,
    method initializeFrom (line 254) | private List<Integer> initializeFrom(final String value) {
    method getGregorianCalendarFromString (line 362) | public static GregorianCalendar getGregorianCalendarFromString(
    method reset (line 374) | private void reset(List<Integer> initializationResult) {
    method readFromDefaultsFile (line 400) | private String readFromDefaultsFile(final File defaultsFile) {
    method getBuildCount (line 414) | public int getBuildCount() {
    method setBuildCount (line 418) | public void setBuildCount(int buildCount) {
    method getBuildStep (line 422) | public int getBuildStep() {
    method setBuildStep (line 426) | public void setBuildStep(int buildStep) {
    method getFirstDayCount (line 430) | public String getFirstDayCount() {
    method setFirstDayCount (line 434) | public void setFirstDayCount(String firstDayCount) {
    method getLastDayCount (line 438) | public String getLastDayCount() {
    method setLastDayCount (line 442) | public void setLastDayCount(String lastDayCount) {
    method getConfigType (line 446) | public String getConfigType() {
    method setConfigType (line 450) | public void setConfigType(String configType) {

FILE: src/main/java/hudson/plugins/performance/details/TestSuiteReportDetail.java
  class TestSuiteReportDetail (line 43) | public class TestSuiteReportDetail implements ModelObject {
    method TestSuiteReportDetail (line 51) | public TestSuiteReportDetail(final Job<?, ?> project, String filename,
    method doRespondingTimeGraphPerTestCaseMode (line 58) | public void doRespondingTimeGraphPerTestCaseMode(StaplerRequest request,
    method getChartDatasetBuilderForBuilds (line 76) | DataSetBuilder<String, NumberOnlyBuildLabel> getChartDatasetBuilderFor...
    method createRespondingTimeChart (line 110) | protected static JFreeChart createRespondingTimeChart(CategoryDataset ...
    method getPerformanceReportTestCaseList (line 159) | public List<String> getPerformanceReportTestCaseList() {
    method getProject (line 192) | public Job<?, ?> getProject() {
    method getFilename (line 196) | public String getFilename() {
    method getDisplayName (line 200) | public String getDisplayName() {

FILE: src/main/java/hudson/plugins/performance/details/TrendReportDetail.java
  class TrendReportDetail (line 16) | public class TrendReportDetail implements ModelObject,
    method TrendReportDetail (line 23) | public TrendReportDetail(final Job<?, ?> project,
    method getProject (line 31) | public Job<?, ?> getProject() {
    method getFilename (line 35) | public String getFilename() {
    method getDisplayName (line 39) | public String getDisplayName() {
    method iterator (line 43) | public Iterator<Row> iterator() {
    method getIterator (line 47) | public Iterator<Row> getIterator() {
    method getColumnLabels (line 51) | public List<?> getColumnLabels() {
    class RowIterator (line 55) | public class RowIterator implements Iterator<Row> {
      method hasNext (line 59) | public boolean hasNext() {
      method next (line 63) | public Row next() {
      method remove (line 67) | public void remove() {
    class Row (line 72) | public class Row {
      method Row (line 76) | public Row(int entry) {
      method getLabel (line 80) | public Object getLabel() {
      method getLabels (line 84) | public List<?> getLabels() {
      method getValues (line 88) | public List<Number> getValues() {

FILE: src/main/java/hudson/plugins/performance/parsers/AbstractParser.java
  class AbstractParser (line 40) | public abstract class AbstractParser extends PerformanceReportParser {
    method AbstractParser (line 64) | public AbstractParser(String glob, String percentiles, String filterRe...
    method parse (line 70) | @Override
    method passBaselineBuild (line 97) | private void passBaselineBuild(PerformanceReport report) {
    method parse (line 110) | abstract PerformanceReport parse(File reportFile) throws Exception;
    method loadSerializedReport (line 126) | protected static PerformanceReport loadSerializedReport(File reportFil...
    method saveSerializedReport (line 159) | protected static void saveSerializedReport(File reportFile, Performanc...
    class ObjectInputStreamWithClassMapping (line 180) | public static class ObjectInputStreamWithClassMapping extends ObjectIn...
      method ObjectInputStreamWithClassMapping (line 183) | public ObjectInputStreamWithClassMapping(InputStream in) throws IOEx...
      method resolveClass (line 190) | @Override
    method clearDateFormat (line 200) | public void clearDateFormat() {
    method parseTimestamp (line 205) | public Date parseTimestamp(String timestamp) {
    method initDateFormat (line 220) | private void initDateFormat(String timestamp) {
    method createPerformanceReport (line 247) | protected PerformanceReport createPerformanceReport() {

FILE: src/main/java/hudson/plugins/performance/parsers/IagoParser.java
  class IagoParser (line 37) | public class IagoParser extends AbstractParser {
    class DescriptorImpl (line 41) | @Extension
      method getDisplayName (line 43) | @Override
    method IagoParser (line 49) | public IagoParser(String glob, String percentiles) {
    method IagoParser (line 53) | @DataBoundConstructor
    method getDefaultGlobPattern (line 58) | @Override
    method parse (line 65) | @Override
    method getSample (line 93) | protected HttpSample getSample(String line, String key) throws ParseEx...
    class Stats (line 139) | protected static class Stats {
      method Stats (line 157) | public Stats() {
      method getClientRequestLatencyMsMinimum (line 161) | public long getClientRequestLatencyMsMinimum() {
      method setClientRequestLatencyMsMinimum (line 165) | public void setClientRequestLatencyMsMinimum(
      method getClientRequestLatencyMsMaximum (line 170) | public long getClientRequestLatencyMsMaximum() {
      method setClientRequestLatencyMsMaximum (line 174) | public void setClientRequestLatencyMsMaximum(
      method getClientRequestLatencyMsAverage (line 179) | public long getClientRequestLatencyMsAverage() {
      method setClientRequestLatencyMsAverage (line 183) | public void setClientRequestLatencyMsAverage(
      method getClientSendBytes (line 188) | public long getClientSendBytes() {
      method setClientSendBytes (line 192) | public void setClientSendBytes(long clientSendBytes) {
      method getClientRequests (line 196) | public long getClientRequests() {
      method setClientRequests (line 200) | public void setClientRequests(long clientRequests) {
      method getClientSuccess (line 204) | public long getClientSuccess() {
      method setClientSuccess (line 208) | public void setClientSuccess(long clientSuccess) {
      method addValidationError (line 212) | public void addValidationError(String name, long value) {
      method getSumValidationErrors (line 218) | public long getSumValidationErrors() {
    class StatsDeserializer (line 237) | private static class StatsDeserializer implements JsonDeserializer<Sta...
      method deserialize (line 247) | public Stats deserialize(JsonElement json, Type typeOfT,

FILE: src/main/java/hudson/plugins/performance/parsers/JMeterCsvParser.java
  class JMeterCsvParser (line 16) | public class JMeterCsvParser extends AbstractParser {
    method JMeterCsvParser (line 35) | public JMeterCsvParser(String glob, String percentiles) {
    method JMeterCsvParser (line 39) | @DataBoundConstructor
    class DescriptorImpl (line 44) | @Extension
      method getDisplayName (line 46) | @Override
    method getDefaultGlobPattern (line 52) | @Override
    method parse (line 57) | @Override
    method parseCSV (line 81) | protected void parseCSV(Reader in, String[] header, PerformanceReport ...
    method readCSVHeader (line 91) | protected String[] readCSVHeader(String line) {
    method lookingForDelimiter (line 125) | protected static char lookingForDelimiter(String line) {
    method getSample (line 140) | private HttpSample getSample(CSVRecord record) {

FILE: src/main/java/hudson/plugins/performance/parsers/JMeterParser.java
  class JMeterParser (line 27) | public class JMeterParser extends AbstractParser {
    class DescriptorImpl (line 29) | @Extension
      method getDisplayName (line 31) | @Override
    method JMeterParser (line 38) | public JMeterParser(String glob, String percentiles) {
    method JMeterParser (line 42) | @DataBoundConstructor
    method getDefaultGlobPattern (line 47) | @Override
    method parse (line 52) | PerformanceReport parse(File reportFile) throws Exception {
    method isXmlFile (line 71) | public static boolean isXmlFile(File file) throws IOException {
    method parseXml (line 92) | PerformanceReport parseXml(File reportFile) throws Exception {
    method parseCsv (line 197) | PerformanceReport parseCsv(File reportFile) throws Exception {

FILE: src/main/java/hudson/plugins/performance/parsers/JUnitParser.java
  class JUnitParser (line 24) | public class JUnitParser extends AbstractParser {
    class DescriptorImpl (line 28) | @Extension
      method getDisplayName (line 30) | @Override
    method JUnitParser (line 36) | public JUnitParser(String glob, String percentiles) {
    method JUnitParser (line 40) | @DataBoundConstructor
    method getDefaultGlobPattern (line 45) | @Override
    method parse (line 50) | @Override
    method parseDuration (line 118) | static long parseDuration(final String time) {

FILE: src/main/java/hudson/plugins/performance/parsers/JmeterSummarizerParser.java
  class JmeterSummarizerParser (line 20) | public class JmeterSummarizerParser extends AbstractParser {
    class DescriptorImpl (line 22) | @Extension
      method getDisplayName (line 24) | @Override
    method JmeterSummarizerParser (line 31) | public JmeterSummarizerParser(String glob, String percentiles) {
    method JmeterSummarizerParser (line 35) | @DataBoundConstructor
    method getDefaultGlobPattern (line 40) | @Override
    method parse (line 45) | @Override

FILE: src/main/java/hudson/plugins/performance/parsers/LoadRunnerParser.java
  class LoadRunnerParser (line 22) | public class LoadRunnerParser extends AbstractParser {
    method LoadRunnerParser (line 36) | public LoadRunnerParser(String glob, String percentiles) {
    method LoadRunnerParser (line 40) | @DataBoundConstructor
    class DescriptorImpl (line 45) | @Extension
      method getDisplayName (line 47) | @Override
    method getDefaultGlobPattern (line 53) | @Override
    method jdbcUrlForFile (line 58) | protected String jdbcUrlForFile(File reportFile) throws ClassNotFoundE...
    method getSample (line 63) | protected HttpSample getSample(ResultSet res) throws SQLException {
    method parse (line 77) | @Override
    method getResultQuery (line 95) | protected String getResultQuery() {
    method setResultQuery (line 99) | protected void setResultQuery(String resultQuery) {

FILE: src/main/java/hudson/plugins/performance/parsers/LocustParser.java
  class LocustParser (line 17) | public class LocustParser extends AbstractParser {
    type ReportColumns (line 18) | enum ReportColumns {
      method ReportColumns (line 24) | ReportColumns(final int order) {
      method getColumn (line 28) | int getColumn() {
    method LocustParser (line 33) | public LocustParser(String glob, String percentiles) {
    method LocustParser (line 37) | @DataBoundConstructor
    class DescriptorImpl (line 42) | @Extension
      method getDisplayName (line 44) | @Override
    method parse (line 50) | @Override
    method getCsvData (line 94) | List<CSVRecord> getCsvData(final File reportFile) {
    method getDefaultGlobPattern (line 106) | @Override

FILE: src/main/java/hudson/plugins/performance/parsers/ParserDetector.java
  class ParserDetector (line 20) | public class ParserDetector {
    method ParserDetector (line 22) | private ParserDetector() {
    method detect (line 29) | public static String detect(String reportPath) throws IOException {
    method isIagoFileType (line 63) | private static boolean isIagoFileType(String line) {
    method isWRKFileType (line 75) | private static boolean isWRKFileType(String line) {
    method isJMeterCSVFileType (line 88) | private static boolean isJMeterCSVFileType(String header) {
    method isJMeterSummarizerFileType (line 98) | private static boolean isJMeterSummarizerFileType(String firstLine, fi...
    method isLoadRunnerFileType (line 119) | private static boolean isLoadRunnerFileType(String line) {
    method detectXMLFileType (line 132) | private static String detectXMLFileType(String reportPath) throws IOEx...
    method detectXMLFileType (line 140) | @VisibleForTesting
    method isLocustFileType (line 173) | private static boolean isLocustFileType(String line) {

FILE: src/main/java/hudson/plugins/performance/parsers/ParserFactory.java
  class ParserFactory (line 18) | public class ParserFactory {
    method getParser (line 35) | public static List<PerformanceReportParser> getParser(Run<?, ?> build,...
    method getParserWithRelativePath (line 47) | private static List<PerformanceReportParser> getParserWithRelativePath...
    method getParserUsingAntPatternRelativePath (line 64) | private static List<PerformanceReportParser> getParserUsingAntPatternR...
    method getParserWithAbsolutePath (line 87) | private static List<PerformanceReportParser> getParserWithAbsolutePath...
    method getParserUsingAntPatternAbsolutePath (line 104) | private static List<PerformanceReportParser> getParserUsingAntPatternA...
    method getParser (line 139) | private static PerformanceReportParser getParser(String parserName, St...

FILE: src/main/java/hudson/plugins/performance/parsers/PerformanceReportParser.java
  class PerformanceReportParser (line 26) | public abstract class PerformanceReportParser implements
    method PerformanceReportParser (line 40) | protected PerformanceReportParser(String glob) {
    method getDescriptor (line 45) | public PerformanceReportParserDescriptor getDescriptor() {
    method parse (line 53) | public abstract Collection<PerformanceReport> parse(
    method getDefaultGlobPattern (line 57) | public abstract String getDefaultGlobPattern();
    method all (line 62) | public static ExtensionList<PerformanceReportParser> all() {
    method getReportName (line 66) | public String getReportName() {
    method isExcludeResponseTime (line 70) | public boolean isExcludeResponseTime() {
    method setExcludeResponseTime (line 74) | public void setExcludeResponseTime(boolean excludeResponseTime) {
    method isShowTrendGraphs (line 78) | public boolean isShowTrendGraphs() {
    method setShowTrendGraphs (line 82) | public void setShowTrendGraphs(boolean showTrendGraphs) {
    method setBaselineBuild (line 86) | public void setBaselineBuild(int baselineBuild) {

FILE: src/main/java/hudson/plugins/performance/parsers/TaurusParser.java
  class TaurusParser (line 21) | public class TaurusParser extends AbstractParser {
    class DescriptorImpl (line 23) | @Extension
      method getDisplayName (line 25) | @Override
    method TaurusParser (line 31) | public TaurusParser(String glob, String percentiles) {
    method TaurusParser (line 35) | @DataBoundConstructor
    method getDefaultGlobPattern (line 40) | @Override
    method parse (line 45) | @Override
    method readFromXML (line 50) | private PerformanceReport readFromXML(File reportFile) throws Exception {
    method getTaurusFinalStats (line 92) | @SuppressFBWarnings("DM_BOXED_PRIMITIVE_FOR_PARSING")
    method getValueAttribute (line 125) | private String getValueAttribute(String elementName, Element group) {

FILE: src/main/java/hudson/plugins/performance/parsers/WrkSummarizerParser.java
  class WrkSummarizerParser (line 24) | public class WrkSummarizerParser extends AbstractParser {
    type LineType (line 26) | private enum LineType {
    type TimeUnit (line 41) | public enum TimeUnit {
      method TimeUnit (line 49) | TimeUnit(int factor) {
      method getFactor (line 53) | public int getFactor() {
    class DescriptorImpl (line 58) | @Extension
      method getDisplayName (line 60) | @Override
    method WrkSummarizerParser (line 66) | public WrkSummarizerParser(String glob, String percentiles) {
    method WrkSummarizerParser (line 70) | @DataBoundConstructor
    method getDefaultGlobPattern (line 75) | @Override
    method parse (line 80) | @Override
    method getTime (line 188) | public long getTime(String timeString, TimeUnit tu) {
    method determineLineType (line 224) | public LineType determineLineType(String t1, String t2) {

FILE: src/main/java/hudson/plugins/performance/reports/AbstractReport.java
  class AbstractReport (line 20) | public abstract class AbstractReport {
    method countErrors (line 43) | public abstract int countErrors();
    method errorPercent (line 45) | public abstract double errorPercent();
    method calculatePercentiles (line 47) | public abstract void calculatePercentiles();
    method calculateDiffPercentiles (line 49) | public abstract void calculateDiffPercentiles();
    method AbstractReport (line 51) | public AbstractReport() {
    method errorPercentFormated (line 71) | public String errorPercentFormated() {
    method checkPercentileAndSet (line 76) | protected void checkPercentileAndSet(Double key, Long value) {
    method parsePercentiles (line 83) | protected List<Double> parsePercentiles(String percentiles) {
    method getAverage (line 98) | public abstract long getAverage();
    method getAverageFormated (line 100) | public String getAverageFormated() {
    method getMedian (line 104) | public abstract long getMedian();
    method getMeanFormated (line 106) | public String getMeanFormated() {
    method get90Line (line 110) | public abstract long get90Line();
    method get90LineFormated (line 112) | public String get90LineFormated() {
    method get95Line (line 116) | public abstract long get95Line();
    method get95LineFormated (line 118) | public String get95LineFormated() {
    method getMax (line 122) | public abstract long getMax();
    method getMaxFormated (line 124) | public String getMaxFormated() {
    method getMin (line 128) | public abstract long getMin();
    method samplesCount (line 130) | public abstract int samplesCount();
    method getHttpCode (line 132) | public abstract String getHttpCode();
    method getAverageDiff (line 134) | public abstract long getAverageDiff();
    method getMedianDiff (line 136) | public abstract long getMedianDiff();
    method get90LineDiff (line 138) | public abstract long get90LineDiff();
    method get95LineDiff (line 140) | public abstract long get95LineDiff();
    method getErrorPercentDiff (line 142) | public abstract double getErrorPercentDiff();
    method getLastBuildHttpCodeIfChanged (line 144) | public abstract String getLastBuildHttpCodeIfChanged();
    method getSamplesCountDiff (line 146) | public abstract int getSamplesCountDiff();
    method isExcludeResponseTime (line 148) | public boolean isExcludeResponseTime() {
    method setExcludeResponseTime (line 152) | public void setExcludeResponseTime(boolean excludeResponseTime) {
    method isShowTrendGraphs (line 156) | public boolean isShowTrendGraphs() {
    method setShowTrendGraphs (line 160) | public void setShowTrendGraphs(boolean showTrendGraphs) {
    method isIncludeResponseTime (line 164) | protected boolean isIncludeResponseTime(HttpSample sample) {
    method getPercentilesValues (line 168) | public Map<Double, Long> getPercentilesValues() {
    method getPercentilesDiffValues (line 176) | public Map<Double, Long> getPercentilesDiffValues() {
    method getPercentileLabel (line 184) | public String getPercentileLabel(Double perc) {

FILE: src/main/java/hudson/plugins/performance/reports/ConstraintReport.java
  class ConstraintReport (line 28) | public class ConstraintReport {
    method ConstraintReport (line 100) | public ConstraintReport(ArrayList<ConstraintEvaluation> ceList, Run<?,...
    method createMetaData (line 118) | private void createMetaData(ArrayList<ConstraintEvaluation> ceList, Ru...
    method determineBuildResult (line 188) | private Result determineBuildResult(ArrayList<ConstraintEvaluation> ce...
    method createLoggerMsg (line 212) | private void createLoggerMsg(ArrayList<ConstraintEvaluation> ceList) {
    method createLoggerMsgAdv (line 283) | private void createLoggerMsgAdv() {
    method createJunitReport (line 295) | private String createJunitReport(ArrayList<ConstraintEvaluation> ceLis...
    method writeResultsToFile (line 312) | public void writeResultsToFile() throws IOException {
    method writeResultsToEnvVar (line 334) | public void writeResultsToEnvVar() {
    method getBuildNumber (line 340) | public int getBuildNumber() {
    method getBuildDate (line 344) | public Calendar getBuildDate() {
    method getBuildResult (line 348) | public Result getBuildResult() {
    method getLinkToBuild (line 352) | public String getLinkToBuild() {
    method getAllConstraints (line 356) | public short getAllConstraints() {
    method getRelativeConstraints (line 360) | public short getRelativeConstraints() {
    method getAbsoluteConstraints (line 364) | public short getAbsoluteConstraints() {
    method getSuccessfulConstraints (line 368) | public short getSuccessfulConstraints() {
    method getViolatedConstraints (line 372) | public short getViolatedConstraints() {
    method getViolatedInformation (line 376) | public short getViolatedInformation() {
    method getViolatedUnstable (line 380) | public short getViolatedUnstable() {
    method getViolatedError (line 384) | public short getViolatedError() {
    method getLoggerMsg (line 388) | public String getLoggerMsg() {
    method getLoggerMsgAdv (line 392) | public String getLoggerMsgAdv() {
    method getJunitReport (line 396) | public String getJunitReport() {
    method getPerformanceLog (line 400) | public File getPerformanceLog() {
    method setPerformanceLog (line 404) | public void setPerformanceLog(File performanceLog) {

FILE: src/main/java/hudson/plugins/performance/reports/PerformanceReport.java
  class PerformanceReport (line 29) | public class PerformanceReport extends AbstractReport implements Seriali...
    method PerformanceReport (line 105) | public PerformanceReport() {
    method PerformanceReport (line 109) | public PerformanceReport(String percentiles, String filterRegex) {
    method PerformanceReport (line 117) | public PerformanceReport(String defaultPercentiles) {
    method readResolve (line 121) | public Object readResolve() {
    method asStaplerURI (line 145) | public static String asStaplerURI(String uri) {
    method addSample (line 149) | public void addSample(HttpSample pHttpSample) {
    method isIncluded (line 188) | private boolean isIncluded(String name) {
    method addSample (line 196) | public void addSample(TaurusFinalStats sample, boolean isSummaryReport) {
    method compareTo (line 257) | public int compareTo(PerformanceReport jmReport) {
    method equals (line 264) | @Override
    method hashCode (line 272) | @Override
    method countErrors (line 277) | public int countErrors() {
    method errorPercent (line 281) | public double errorPercent() {
    method getAverage (line 290) | public long getAverage() {
    method getAverageSizeInKb (line 297) | public double getAverageSizeInKb() {
    method getDurationAt (line 311) | public long getDurationAt(double percentage) {
    method calculatePercentiles (line 346) | @Override
    method calculateDiffPercentiles (line 355) | @Override
    method get90Line (line 371) | public long get90Line() {
    method get95Line (line 378) | public long get95Line() {
    method getMedian (line 385) | public long getMedian() {
    method getHttpCode (line 392) | public String getHttpCode() {
    method getBuild (line 396) | public Run<?, ?> getBuild() {
    method getBuildAction (line 400) | PerformanceBuildAction getBuildAction() {
    method getDisplayName (line 404) | public String getDisplayName() {
    method getDynamic (line 408) | public UriReport getDynamic(String token) throws IOException {
    method getMax (line 412) | public long getMax() {
    method getTotalTrafficInKb (line 419) | public double getTotalTrafficInKb() {
    method getMin (line 423) | public long getMin() {
    method getReportFileName (line 430) | public String getReportFileName() {
    method getUriListOrdered (line 434) | public List<UriReport> getUriListOrdered() {
    method getUriReportMap (line 444) | public Map<String, UriReport> getUriReportMap() {
    method setBuildAction (line 448) | public void setBuildAction(PerformanceBuildAction buildAction) {
    method setReportFileName (line 452) | public void setReportFileName(String reportFileName) {
    method samplesCount (line 456) | public int samplesCount() {
    method setLastBuildReport (line 460) | public void setLastBuildReport(PerformanceReport lastBuildReport) {
    method getAverageDiff (line 473) | public long getAverageDiff() {
    method getMedianDiff (line 480) | public long getMedianDiff() {
    method get90LineDiff (line 487) | public long get90LineDiff() {
    method get95LineDiff (line 494) | public long get95LineDiff() {
    method getErrorPercentDiff (line 501) | public double getErrorPercentDiff() {
    method getLastBuildHttpCodeIfChanged (line 508) | public String getLastBuildHttpCodeIfChanged() {
    method getSamplesCountDiff (line 512) | public int getSamplesCountDiff() {
    method ifSummarizerParserUsed (line 526) | public boolean ifSummarizerParserUsed(String filename) {
    method setSummarizerSize (line 541) | public void setSummarizerSize(long summarizerSize) {
    method getSummarizerSize (line 545) | public long getSummarizerSize() {
    method setSummarizerMin (line 549) | public void setSummarizerMin(long summarizerMin) {
    method getSummarizerMin (line 553) | public long getSummarizerMin() {
    method setSummarizerMax (line 557) | public void setSummarizerMax(long summarizerMax) {
    method getSummarizerMax (line 561) | public long getSummarizerMax() {
    method setSummarizerAvg (line 565) | public void setSummarizerAvg(long summarizerAvg) {
    method getSummarizerAvg (line 569) | public long getSummarizerAvg() {
    method setSummarizerErrors (line 573) | public void setSummarizerErrors(String summarizerErrorPercent) {
    method getSummarizerErrors (line 577) | public String getSummarizerErrors() {
    method getThroughput (line 581) | public Long getThroughput() {
    method getBaselineBuild (line 585) | public int getBaselineBuild() {
    method setBaselineBuild (line 589) | public void setBaselineBuild(int baselineBuild) {
    method getFilterRegex (line 596) | public String getFilterRegex() {
    method setFilterRegex (line 603) | public void setFilterRegex(String filterRegex) {

FILE: src/main/java/hudson/plugins/performance/reports/ThroughputReport.java
  class ThroughputReport (line 8) | public class ThroughputReport {
    method ThroughputReport (line 14) | public ThroughputReport(final PerformanceReport performanceReport) {
    method get (line 18) | public double get() {

FILE: src/main/java/hudson/plugins/performance/reports/UriReport.java
  class UriReport (line 45) | public class UriReport extends AbstractReport implements Serializable, M...
    method readResolve (line 137) | public Object readResolve() {
    method UriReport (line 149) | public UriReport(PerformanceReport performanceReport, String staplerUr...
    method addHttpSample (line 156) | public void addHttpSample(HttpSample sample) {
    method setFromTaurusFinalStats (line 184) | public void setFromTaurusFinalStats(TaurusFinalStats report) {
    method compareTo (line 209) | public int compareTo(UriReport uriReport) {
    method equals (line 215) | @Override
    method hashCode (line 223) | @Override
    method countErrors (line 228) | public int countErrors() {
    method errorPercent (line 232) | public double errorPercent() {
    method getAverage (line 236) | public long getAverage() {
    method getDurationAt (line 244) | private long getDurationAt(double percentage) {
    method calculatePercentiles (line 270) | @Override
    method calculateDiffPercentiles (line 279) | @Override
    method get90Line (line 295) | public long get90Line() {
    method get95Line (line 302) | public long get95Line() {
    method getHttpCode (line 309) | public String getHttpCode() {
    method getMedian (line 313) | public long getMedian() {
    method getBuild (line 320) | public Run<?, ?> getBuild() {
    method getDisplayName (line 324) | public String getDisplayName() {
    method getHttpSampleList (line 328) | public List<Sample> getHttpSampleList() {
    method getPerformanceReport (line 332) | public PerformanceReport getPerformanceReport() {
    method getSortedDuration (line 336) | protected List<Long> getSortedDuration() {
    method getDurations (line 354) | public List<Long> getDurations() {
    method getMax (line 368) | public long getMax() {
    method getMin (line 375) | public long getMin() {
    method getStaplerUri (line 382) | public String getStaplerUri() {
    method getUri (line 386) | public String getUri() {
    method getShortUri (line 390) | public String getShortUri() {
    method isFailed (line 397) | public boolean isFailed() {
    method samplesCount (line 401) | public int samplesCount() {
    method encodeUriReport (line 407) | public String encodeUriReport() throws UnsupportedEncodingException {
    method addLastBuildUriReport (line 415) | public void addLastBuildUriReport(UriReport lastBuildUriReport) {
    method getAverageDiff (line 420) | public long getAverageDiff() {
    method getMedianDiff (line 427) | public long getMedianDiff() {
    method get90LineDiff (line 434) | public long get90LineDiff() {
    method get95LineDiff (line 441) | public long get95LineDiff() {
    method getErrorPercentDiff (line 448) | public double getErrorPercentDiff() {
    method getLastBuildHttpCodeIfChanged (line 455) | public String getLastBuildHttpCodeIfChanged() {
    method getSamplesCountDiff (line 467) | public int getSamplesCountDiff() {
    method getSummarizerErrors (line 474) | public float getSummarizerErrors() {
    method doSummarizerTrendGraph (line 478) | public void doSummarizerTrendGraph(StaplerRequest request, StaplerResp...
    method doErrorGraph (line 502) | public void doErrorGraph(StaplerRequest request, StaplerResponse respo...
    method doPercentileGraph (line 523) | public void doPercentileGraph(StaplerRequest request, StaplerResponse ...
    method doThroughputGraph (line 553) | public void doThroughputGraph(StaplerRequest request, StaplerResponse ...
    method getStart (line 578) | public Date getStart() {
    method getEnd (line 582) | public Date getEnd() {
    method isIncludeResponseTime (line 587) | protected boolean isIncludeResponseTime(Sample sample) {
    class Sample (line 591) | public static class Sample implements Serializable, Comparable<Sample> {
      method Sample (line 601) | public Sample(Date date, long duration, String httpCode, boolean isS...
      method convertFromHttpSample (line 609) | public static Sample convertFromHttpSample(HttpSample httpSample) {
      method getHttpCode (line 614) | public String getHttpCode() {
      method getDate (line 618) | public Date getDate() {
      method getDuration (line 622) | public long getDuration() {
      method isSuccessful (line 626) | public boolean isSuccessful() {
      method isFailed (line 630) | public boolean isFailed() {
      method isSummarizer (line 634) | public boolean isSummarizer() {
      method compareTo (line 641) | public int compareTo(Sample other) {
      method equals (line 651) | @Override
      method hashCode (line 660) | @Override
    method setThroughput (line 668) | @Deprecated
    method getThroughput (line 673) | @Deprecated
    method hasSamples (line 678) | public boolean hasSamples() {
    method getAverageSizeInKb (line 682) | public double getAverageSizeInKb() {
    method getTotalTrafficInKb (line 686) | public double getTotalTrafficInKb() {
    method getAverageSizeInKbDiff (line 690) | public double getAverageSizeInKbDiff() {
    method getTotalTrafficInKbDiff (line 697) | public double getTotalTrafficInKbDiff() {

FILE: src/main/java/hudson/plugins/performance/tools/SafeMaths.java
  class SafeMaths (line 6) | public class SafeMaths {
    method safeDivide (line 7) | public static double safeDivide(double dividend, double divisor) {
    method roundTwoDecimals (line 29) | public static double roundTwoDecimals(double d) {

FILE: src/main/java/hudson/plugins/performance/workflow/WorkflowActionsFactory.java
  class WorkflowActionsFactory (line 16) | @Extension
    method type (line 19) | @Override
    method createFor (line 24) | @NonNull

FILE: src/test/java/hudson/plugins/performance/AbstractGraphGenerationTest.java
  class AbstractGraphGenerationTest (line 25) | public abstract class AbstractGraphGenerationTest {
    method baseSetup (line 43) | @BeforeEach
    method setGraphType (line 57) | protected void setGraphType(String graphType) {
    method toArray (line 65) | protected Number[] toArray(CategoryDataset cd) {

FILE: src/test/java/hudson/plugins/performance/BaselineComparisonTest.java
  class BaselineComparisonTest (line 22) | @ExtendWith(MockitoExtension.class)
    method setup (line 46) | @BeforeEach
    method prepareReportForBuild (line 72) | private void prepareReportForBuild(int num, int baseline, Map<String, ...
    method testBaselineBuild5 (line 89) | @Test
    method testBaselineBuild4 (line 121) | @Test
    method testBaselineBuild3 (line 153) | @Test

FILE: src/test/java/hudson/plugins/performance/PerformancePipelineTest.java
  class PerformancePipelineTest (line 16) | @WithJenkins
    method bztSmokeTests (line 19) | @Test
    method perfReportSmokeTests (line 43) | @Test

FILE: src/test/java/hudson/plugins/performance/PerformancePublisherTest.java
  class PerformancePublisherTest (line 57) | @WithJenkins
    method testBuild (line 60) | @Test
    method testBuildWithFormattedTimeStamp (line 91) | @Test
    method testStandardResultsXML (line 110) | @Test
    method testBuildWithParameters (line 166) | @Test
    method testBuildUnstableResponseThreshold (line 198) | @Test
    method testBuildStableResponseThreshold (line 229) | @Test
    method buildUnstableAverageResponseTimeRelativeThreshold (line 261) | @Issue("JENKINS-22011")
    method testEmptyReportParsersList (line 305) | @Test
    class RunExt (line 319) | private class RunExt extends Run {
      method RunExt (line 321) | protected RunExt(@NonNull Job job) throws IOException {
      method onStartBuilding (line 325) | @Override
    method testOptionMethods (line 331) | @Test
    method testErrorThresholdUnstable (line 419) | @Test
    method testErrorThresholdFailed (line 450) | @Test
    method testErrorThresholdAverageResponseTime (line 480) | @Test
    method testMigration (line 518) | @Test
    method testRelativeThresholdUnstableNegative (line 539) | @Test
    method testRelativeThresholdUnstablePositive (line 572) | @Test
    method testRelativeThresholdFailedNegative (line 606) | @Test
    method testRelativeThresholdFailedPositive (line 640) | @Test
    method testRelativeThresholds (line 674) | @Test

FILE: src/test/java/hudson/plugins/performance/PerformanceReportMapTest.java
  class PerformanceReportMapTest (line 28) | @ExtendWith(MockitoExtension.class)
    method reportMapSetup (line 36) | @BeforeEach
    method testGetters (line 50) | @Test
    method testNoPerformancePublisher (line 61) | @Test
    method testRespondingTimeGraphAverageValues (line 70) | @Test
    method testRespondingTimeGraphMedianValues (line 77) | @Test
    method testSummarizerGraphAverageValues (line 84) | @Test
    method testSummarizerGraphMedianValues (line 91) | @Test
    method testThroughputGraph (line 98) | @Test
    method testRespondingTimeGraphPerTestCaseMode (line 104) | @Test
    method testErrorsGraph (line 111) | @Test
    class TestablePerformanceReportMap (line 118) | public class TestablePerformanceReportMap extends PerformanceReportMap {
      method TestablePerformanceReportMap (line 122) | public TestablePerformanceReportMap(PerformanceBuildAction buildActi...
      method createRespondingTimeChart (line 126) | @Override
      method createSummarizerChart (line 132) | @Override
      method parseReports (line 138) | @Override
      method createThroughputChart (line 143) | @Override
      method createErrorsChart (line 149) | @Override

FILE: src/test/java/hudson/plugins/performance/TrendReportGraphsTest.java
  class TrendReportGraphsTest (line 15) | @WithJenkins
    method test (line 18) | @Test

FILE: src/test/java/hudson/plugins/performance/actions/ExternalBuildReportActionTest.java
  class ExternalBuildReportActionTest (line 8) | class ExternalBuildReportActionTest {
    method test (line 10) | @Test

FILE: src/test/java/hudson/plugins/performance/actions/PerformanceProjectActionGraphTest.java
  class PerformanceProjectActionGraphTest (line 23) | @ExtendWith(MockitoExtension.class)
    method actionSetup (line 28) | @BeforeEach
    method testRespondingTimeGraphPerTestCaseModeAverageValues (line 34) | @Test
    method testRespondingTimeGraphPerTestCaseModeMedianValues (line 41) | @Test
    method testSummarizerGraphAverageValues (line 48) | @Test
    method testSummarizerGraphMedianValues (line 55) | @Test
    method testErrorsGraph (line 62) | @Test
    method testRespondingTimeGraph (line 69) | @Test
    method testThroughputGraph (line 76) | @Test
    class TestablePerformanceProjectAction (line 82) | private class TestablePerformanceProjectAction extends PerformanceProj...
      method TestablePerformanceProjectAction (line 86) | public TestablePerformanceProjectAction(AbstractProject<?, ?> projec...
      method getPerformanceReportList (line 90) | @NonNull
      method getPerformanceReport (line 96) | @Override
      method createRespondingTimeChart (line 101) | @Override
      method createSummarizerChart (line 107) | @Override
      method createErrorsGraph (line 113) | @Override
      method createThroughputGraph (line 119) | @Override

FILE: src/test/java/hudson/plugins/performance/actions/PerformanceProjectActionTest.java
  class PerformanceProjectActionTest (line 21) | @WithJenkins
    method testDynamic (line 28) | @Test

FILE: src/test/java/hudson/plugins/performance/build/PerformanceTestBuildTest.java
  class PerformanceTestBuildTest (line 37) | @WithJenkins
    method testFlow (line 40) | @Test
    method testInstallFromGit (line 79) | @Test
    method testInstallFromURL (line 121) | @Test
    method testInstallFromPath (line 162) | @Test
    class PerformanceTestBuildExt (line 202) | public static class PerformanceTestBuildExt extends PerformanceTestBui...
      method PerformanceTestBuildExt (line 203) | public PerformanceTestBuildExt(String params) {
      method runCmd (line 209) | @Override
    class FreeStyleBuildExt (line 220) | public static class FreeStyleBuildExt extends FreeStyleBuild {
      method FreeStyleBuildExt (line 222) | public FreeStyleBuildExt(FreeStyleProject project) throws IOException {
      method setWorkspace (line 226) | @Override
      method onStartBuilding (line 231) | @Override
    method testGetters (line 237) | @Test
    method testGenerateReportInPipe (line 283) | @Test
    method testFailCriteria (line 320) | @Test
    method testResutsChecker (line 357) | @Test
    method testPWD (line 376) | @Test
    method resetVirtualEnvCommands (line 416) | private void resetVirtualEnvCommands() {
    method testDefaultVirtualEnvCommand (line 422) | @Test
    method testHardcodedVirtualEnvCommand (line 464) | @Test
    method testVariableVirtualEnvCommand (line 507) | @Test

FILE: src/test/java/hudson/plugins/performance/constraints/ConstraintCheckerTest.java
  class ConstraintCheckerTest (line 40) | @ExtendWith(MockitoExtension.class)
    method happyPathForAbsoluteConstraints (line 177) | @Test
    method happyPathForRelativeConstraints (line 211) | @Test
    method happyPathForMixedConstraints (line 248) | @Test
    method setUp (line 286) | @BeforeEach
    method test (line 704) | @Test
    method generateJunitOutput (line 717) | @Test

FILE: src/test/java/hudson/plugins/performance/constraints/ConstraintFactoryTest.java
  class ConstraintFactoryTest (line 30) | @ExtendWith(MockitoExtension.class)
    method setUp (line 52) | @BeforeEach
    method testHappyPath (line 107) | @Test
    method testOptionalBlock (line 138) | @Test

FILE: src/test/java/hudson/plugins/performance/constraints/ConstraintTest.java
  class ConstraintTest (line 25) | @WithJenkins
    method informationModeDoesntAffectBuildStatus (line 37) | @Test
    method warningModeMakesBuildUnstable (line 80) | @Test
    method errorModeMakesBuildFail (line 123) | @Test
    method equalValuesWithNotGreaterOperator (line 165) | @Test
    method calculatedValueGreaterWithNotGreaterOperator (line 208) | @Test
    method equalValuesWithNotEqualOperator (line 250) | @Test
    method notEqualValueWithNotEqualOperator (line 292) | @Test
    method equalValuesWithNotLessOperator (line 335) | @Test
    method calculatedValueLessWithNotLessOperator (line 378) | @Test

FILE: src/test/java/hudson/plugins/performance/cookie/CookieHandlerTest.java
  class CookieHandlerTest (line 13) | class CookieHandlerTest {
    method testCookieHandler (line 15) | @Test
    class AncestorImpl (line 34) | private static class AncestorImpl implements Ancestor {
      method AncestorImpl (line 37) | public AncestorImpl(String url) {
      method getObject (line 40) | public Object getObject() {
      method getUrl (line 43) | public String getUrl() {
      method getRestOfUrl (line 46) | public String getRestOfUrl() {
      method getNextToken (line 49) | public String getNextToken(int n) {
      method getFullUrl (line 52) | public String getFullUrl() {
      method getRelativePath (line 55) | public String getRelativePath() {
      method getPrev (line 58) | public Ancestor getPrev() {
      method getNext (line 61) | public Ancestor getNext() {

FILE: src/test/java/hudson/plugins/performance/data/PerformanceReportPositionTest.java
  class PerformanceReportPositionTest (line 7) | class PerformanceReportPositionTest {
    method test (line 9) | @Test

FILE: src/test/java/hudson/plugins/performance/data/ReportValueSelectorTest.java
  class ReportValueSelectorTest (line 19) | @ExtendWith(MockitoExtension.class)
    method setUp (line 31) | @BeforeEach
    method testAverageConfiguration (line 38) | @Test
    method testMedianConfiguration (line 46) | @Test
    method testPercentileConfiguration (line 54) | @Test
    method testFallbackNoPublisher (line 62) | @Test
    method testFallbackMissingGraphConfig (line 69) | @Test
    method testPublisherSearchedFromAbstractProject (line 77) | @Test

FILE: src/test/java/hudson/plugins/performance/descriptors/ConstraintDescriptorTest.java
  class ConstraintDescriptorTest (line 13) | @WithJenkins
    method name (line 16) | @Test

FILE: src/test/java/hudson/plugins/performance/descriptors/PerformanceReportParserDescriptorTest.java
  class PerformanceReportParserDescriptorTest (line 18) | @WithJenkins
    method name (line 21) | @Test

FILE: src/test/java/hudson/plugins/performance/details/GraphConfigurationDetailTest.java
  class GraphConfigurationDetailTest (line 19) | @WithJenkins
    method testDefault (line 26) | @Test
    method testCalendar (line 61) | @Test

FILE: src/test/java/hudson/plugins/performance/details/TestSuiteReportDetailTest.java
  class TestSuiteReportDetailTest (line 41) | @WithJenkins
    method setUp (line 63) | @BeforeEach
    method getUriReport (line 68) | private UriReport getUriReport() {
    method chartDatasetHasAverageOfSamples (line 83) | @Test
    method chartDatasetHasMedianOfSamples (line 89) | @Test
    method getDatasetValue (line 95) | private Number getDatasetValue() {
    method alwaysInRangeMock (line 110) | public static PerformanceProjectAction.Range alwaysInRangeMock() {
    method testFlow (line 117) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/AbstractParserTest.java
  class AbstractParserTest (line 12) | class AbstractParserTest {
    method testDeserialized (line 14) | @Test
    method testUploadOldReport (line 27) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/IagoParserTest.java
  class IagoParserTest (line 26) | @WithJenkins
    method testParseValidLine (line 29) | @Test
    method testParseInvalidLine (line 46) | @Test
    method testParseInvalidDate (line 65) | @Test
    method testParseValidFile (line 84) | @Test
    method testUserRegexNoValidationErrors (line 143) | @Test
    method testNoErrors (line 163) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/JMeterCsvParserTest.java
  class JMeterCsvParserTest (line 16) | class JMeterCsvParserTest {
    method beforeMethod (line 22) | @BeforeEach
    method canParseCsvFile (line 30) | @Test
    method testDateDateFormats (line 36) | @Test
    method parseAndVerifyResult (line 47) | private PerformanceReport parseAndVerifyResult(JMeterCsvParser parser,...
    method testLookingForDelimeter (line 55) | @Test
    method testMultiLineCSV (line 71) | @Test
    method testCSVWithRegex (line 97) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/JMeterParserTest.java
  class JMeterParserTest (line 21) | class JMeterParserTest {
    method testIsXml (line 26) | @Test
    method testIsCsv (line 42) | @Test
    method testIsEmpty (line 58) | @Test
    method testIsWhitespaceXml (line 74) | @Test
    method testParseXmlJtlFile (line 94) | @Test
    method testParseCsvJtlFile (line 116) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/JMeterTestHelper.java
  class JMeterTestHelper (line 11) | public class JMeterTestHelper {
    method parse (line 13) | public static PerformanceReport parse(String resourceName) throws Exce...

FILE: src/test/java/hudson/plugins/performance/parsers/JUnitParserTest.java
  class JUnitParserTest (line 12) | class JUnitParserTest {
    method testParseDurationLongRunningTest (line 19) | @Test
    method testCanParseFileWithoutTimeAtrribute (line 26) | @Test
    method testCanParseJunitResultFileWithSuccessErrorAndFailure (line 39) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/JmeterSummarizerParserTest.java
  class JmeterSummarizerParserTest (line 11) | class JmeterSummarizerParserTest {
    method testParse (line 13) | @Test
    method testParseNewLog (line 27) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/LoadRunnerParserTest.java
  class LoadRunnerParserTest (line 14) | class LoadRunnerParserTest {
    method test (line 29) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/LocustParserTest.java
  class LocustParserTest (line 16) | class LocustParserTest {
    method setUp (line 22) | @BeforeEach
    method shouldCreateParser (line 29) | @Test
    method parserShouldReturnGlobPattern (line 34) | @Test
    method reportShouldContainSummarizedValues (line 39) | @Test
    method reportShouldContainAllReports (line 47) | @Test
    method reportHasValuesInUriReport (line 57) | @Test
    method reportShouldContainTrafficSize (line 65) | @Test
    method reportShouldReturnProperFileName (line 70) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/ParserDetectorTest.java
  class ParserDetectorTest (line 15) | public class ParserDetectorTest {
    method testFlow (line 17) | @Test
    method testIssue44317 (line 49) | @Issue("JENKINS-44317")
    method testIssue45723 (line 56) | @Issue("JENKINS-45723")
    method testIssue (line 63) | @Issue("JENKINS-47808")
    method getHugeJMeterInputStream (line 69) | public static InputStream getHugeJMeterInputStream() {
    method getPrefixInputStream (line 73) | private static ByteArrayInputStream getPrefixInputStream() {
    method getInfiniteSampleInputStream (line 78) | private static InputStream getInfiniteSampleInputStream() {
    method repeat (line 83) | public static InputStream repeat(final byte[] sample, final int times) {

FILE: src/test/java/hudson/plugins/performance/parsers/ParserFactoryTest.java
  class ParserFactoryTest (line 21) | @WithJenkins
    method testFlow (line 24) | @Test
    method testFlowWithGlob (line 59) | @Test
    method test43503 (line 72) | @Test
    method test45119 (line 97) | @Test
    method testAntAbsolutePath (line 126) | @Test
    class FreeStyleBuildExt (line 151) | public static class FreeStyleBuildExt extends FreeStyleBuild {
      method FreeStyleBuildExt (line 153) | public FreeStyleBuildExt(FreeStyleProject project) throws IOException {
      method setWorkspace (line 157) | @Override

FILE: src/test/java/hudson/plugins/performance/parsers/TaurusParserTest.java
  class TaurusParserTest (line 15) | public class TaurusParserTest {
    method testReadXML (line 19) | @Test
    method checkUriReport1 (line 47) | private void checkUriReport1(UriReport report) {
    method checkUriReport2 (line 59) | private void checkUriReport2(UriReport report) {
    method checkPerformanceReport (line 71) | private void checkPerformanceReport(PerformanceReport report) {
    method checkReportDiff (line 83) | private void checkReportDiff(PerformanceReport report) {
    method testGlobPattern (line 92) | @Test

FILE: src/test/java/hudson/plugins/performance/parsers/WrkSummarizerParserTest.java
  class WrkSummarizerParserTest (line 21) | class WrkSummarizerParserTest {
    method before (line 26) | @BeforeEach
    method testParseResultsWithMilliSecondResponseTimes (line 32) | @Test
    method testParseResultsWithSecondResponseTimes (line 48) | @Test
    method testParseWithLatencyDistributionBuckets (line 63) | @Test
    method testParseWithErrors (line 74) | @Test
    method testParseTimeMeasurements (line 91) | @Test

FILE: src/test/java/hudson/plugins/performance/reports/ConstraintReportTest.java
  class ConstraintReportTest (line 31) | @ExtendWith(MockitoExtension.class)
    method setUp (line 104) | @BeforeEach
    method tearDown (line 159) | @AfterEach
    method happyPathWithoutConstraintLog (line 164) | @Test
    method happyPathWithConstraintLog (line 192) | @Test

FILE: src/test/java/hudson/plugins/performance/reports/PerformanceReportTest.java
  class PerformanceReportTest (line 29) | public class PerformanceReportTest {
    method setUp (line 34) | @BeforeEach
    method testAddSample (line 41) | @Test
    method testAddTaurusSample (line 72) | @Test
    method testPerformanceReport (line 86) | @Test
    method parseOneJMeter (line 106) | private PerformanceReport parseOneJMeter(File f) throws IOException {
    method parseOneJUnit (line 111) | private PerformanceReport parseOneJUnit(File f) throws IOException {
    method testPerformanceNonHTTPSamplesMultiThread (line 116) | @Test
    method testPerformanceReportJUnit (line 135) | @Test
    method testIssue5571 (line 155) | @Test
    method testPerformanceReportMultiLevel (line 172) | @Test
    method testGetUriListOrdered (line 182) | @Test
    method testCanGetCorrect90LineValue (line 189) | @Test
    method testCanGetCorrect95LineValue (line 195) | @Test
    method testCanGetCorrect90LineValueWithThreeSamples (line 201) | @Test
    method testCanGetCorrect95LineValueWithThreeSamples (line 207) | @Test
    method testCanGetCorrectMaxValueWithThreeSamples (line 213) | @Test
    method testCanGetCorrectMinValueWithThreeSamples (line 219) | @Test
    method testCanGetZeroPercentileDurationForEmptySampleFile (line 225) | @Test
    method testCanGetZeroPercentileDurationFromOneSampleFile (line 231) | @Test
    method testCanGetOneHundredPercentileDurationFromOneSampleFile (line 237) | @Test
    method testCannotGetDurationForNegativePercentile (line 243) | @Test
    method testCannotGetDurationForMoreThan100Percentile (line 250) | @Test
    method testCompare (line 257) | @Test
    method testExcludeResponseTimeOfErroredSamples (line 268) | @Test
    method testDivisionByZero (line 320) | @Test

FILE: src/test/java/hudson/plugins/performance/reports/ThroughputReportTest.java
  class ThroughputReportTest (line 23) | class ThroughputReportTest {
    method shouldReturnZeroIfNoUri (line 30) | @Test
    method shouldSummarizeThroughputByDifferentUri (line 35) | @Test
    method shouldSummarizeThroughputUnder1ByDifferentUri (line 57) | @Test
    method testThroughputJMeterReport (line 83) | @Test
    method testThroughputTaurusReport (line 122) | @Test
    method testDuration (line 134) | @Test
    method testDurationBackwardCompatibility (line 149) | @Test

FILE: src/test/java/hudson/plugins/performance/reports/UriReportTest.java
  class UriReportTest (line 18) | class UriReportTest {
    method setUp (line 26) | @BeforeEach
    method testHasSamples (line 48) | @Test
    method testCountErrors (line 53) | @Test
    method testGetAverage (line 58) | @Test
    method testGetMax (line 63) | @Test
    method testGetMin (line 68) | @Test
    method testIsFailed (line 73) | @Test
    method testCompareSameDateDifferentDuration (line 81) | @Test
    method testCompareDifferentDateSameDuration (line 100) | @Test
    method testCompareDifferentDateDifferentDuration (line 119) | @Test
    method testCompareNullDateSameDuration (line 138) | @Test

FILE: src/test/java/hudson/plugins/performance/tools/SafeMathsTest.java
  class SafeMathsTest (line 7) | class SafeMathsTest {
    method safeDivideDividendIsNaN (line 9) | @Test
    method safeDivideDivisorIsNaN (line 16) | @Test
    method safeDivideDivisorIsNullPositivePositive (line 23) | @Test
    method safeDivideDivisorIsNullNegativePositive (line 30) | @Test
    method safeDivideHappyPath (line 37) | @Test

FILE: src/test/java/hudson/plugins/performance/workflow/WorkflowActionsFactoryTest.java
  class WorkflowActionsFactoryTest (line 22) | @WithJenkins
    method testFlow (line 26) | @Test
    method testFlowWithProjectAction (line 43) | @Test
Condensed preview — 209 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,245K chars).
[
  {
    "path": ".github/dependabot.yml",
    "chars": 299,
    "preview": "# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates\n\nve"
  },
  {
    "path": ".github/workflows/cd.yaml",
    "chars": 396,
    "preview": "# Note: additional setup is required, see https://www.jenkins.io/redirect/continuous-delivery-of-plugins\n\nname: cd\non:\n "
  },
  {
    "path": ".github/workflows/jenkins-security-scan.yml",
    "chars": 602,
    "preview": "name: Jenkins Security Scan\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    types: [ opened, synchronize, "
  },
  {
    "path": ".gitignore",
    "chars": 111,
    "preview": "target\n*.iml\n*.ipr\n*.iws\n.idea/\n.classpath\n.project\n.settings/\n.vscode/\nsrc/test/resources/*.serialized\n/work/\n"
  },
  {
    "path": ".mvn/extensions.xml",
    "chars": 416,
    "preview": "<extensions xmlns=\"http://maven.apache.org/EXTENSIONS/1.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:s"
  },
  {
    "path": ".mvn/maven.config",
    "chars": 78,
    "preview": "-Pconsume-incrementals\n-Pmight-produce-incrementals\n-Dchangelist.format=%d.v%s"
  },
  {
    "path": "Jenkinsfile",
    "chars": 665,
    "preview": "properties([\n    buildDiscarder(logRotator(numToKeepStr: '5')),\n    disableConcurrentBuilds(abortPrevious: true)\n])\n\nnod"
  },
  {
    "path": "LICENSE",
    "chars": 1063,
    "preview": "MIT License\n\nCopyright (c) 2019 Jenkins\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
  },
  {
    "path": "README.md",
    "chars": 506,
    "preview": "# Performance Plugin for Jenkins CI\n\n\nLinks:\n - [Documentation](http://jenkinsci.github.io/performance-plugin/)\n   - [Ru"
  },
  {
    "path": "docs/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/Changelog.md",
    "chars": 9954,
    "preview": "<small>[<< Back to main page](./)</small>\n# Changelog\n\n## v3.20 (13th of July, 2021)\n- FIX: compatibility with Jenkins 2"
  },
  {
    "path": "docs/README.md",
    "chars": 1971,
    "preview": "# Performance Plugin for Jenkins \n\n## About\n\nPerformance Plugin allows you to [run performance tests](RunTests.md) as bu"
  },
  {
    "path": "docs/Reporting.md",
    "chars": 3729,
    "preview": "<small>[<< Back to main page](./)</small>\n# Performance Trend Reporting\n\n## Features\nPerformance Report post-build step "
  },
  {
    "path": "docs/RunTests.md",
    "chars": 6116,
    "preview": "<small>[<< Back to main page](./)</small>\n# Running Performance Tests\n\n## Features\nPerformance Plugin for Jenkins uses ["
  },
  {
    "path": "docs/_config.yml",
    "chars": 26,
    "preview": "theme: jekyll-theme-cayman"
  },
  {
    "path": "docs/stats.html",
    "chars": 6292,
    "preview": "<!DOCTYPE html>\n<html lang=\"en-us\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Statistics</title>\n    <meta name=\"view"
  },
  {
    "path": "pom.xml",
    "chars": 5921,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n    xmlns:xsi=\"http://www.w3.o"
  },
  {
    "path": "requirements.txt",
    "chars": 46,
    "preview": "virtualenv\r\nbzt\r\nurwid>=3.0.2,<4.0.0\r\napiritif"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/PerformancePublisher.java",
    "chars": 69321,
    "preview": "package hudson.plugins.performance;\n\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileOutputStream"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/PerformanceReportMap.java",
    "chars": 24449,
    "preview": "package hudson.plugins.performance;\n\nimport hudson.model.AbstractProject;\nimport hudson.model.Describable;\nimport hudson"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/TrendReportGraphs.java",
    "chars": 4136,
    "preview": "package hudson.plugins.performance;\n\nimport hudson.model.Job;\nimport hudson.model.ModelObject;\nimport hudson.model.Run;\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/actions/ExternalBuildReportAction.java",
    "chars": 666,
    "preview": "package hudson.plugins.performance.actions;\n\n\nimport hudson.model.Action;\nimport org.kohsuke.stapler.StaplerProxy;\n\npubl"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/actions/PerformanceBuildAction.java",
    "chars": 3259,
    "preview": "package hudson.plugins.performance.actions;\n\nimport hudson.model.Action;\nimport hudson.model.Run;\nimport hudson.plugins."
  },
  {
    "path": "src/main/java/hudson/plugins/performance/actions/PerformanceProjectAction.java",
    "chars": 39941,
    "preview": "package hudson.plugins.performance.actions;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.io.File;\nim"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/build/PerformanceTestBuild.java",
    "chars": 21282,
    "preview": "package hudson.plugins.performance.build;\n\nimport hudson.EnvVars;\nimport hudson.Extension;\nimport hudson.FilePath;\nimpor"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/AbsoluteConstraint.java",
    "chars": 6189,
    "preview": "package hudson.plugins.performance.constraints;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Li"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/AbstractConstraint.java",
    "chars": 12651,
    "preview": "package hudson.plugins.performance.constraints;\n\nimport hudson.AbortException;\nimport hudson.ExtensionList;\nimport hudso"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/ConstraintChecker.java",
    "chars": 2296,
    "preview": "package hudson.plugins.performance.constraints;\n\nimport hudson.AbortException;\nimport hudson.model.Run;\nimport hudson.pl"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/ConstraintEvaluation.java",
    "chars": 1193,
    "preview": "package hudson.plugins.performance.constraints;\n\n/**\n * Holds the values of a evaluated constraint.\n *\n * @author Rene K"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/ConstraintFactory.java",
    "chars": 2715,
    "preview": "package hudson.plugins.performance.constraints;\n\nimport hudson.model.Run;\nimport hudson.plugins.performance.actions.Perf"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/RelativeConstraint.java",
    "chars": 24995,
    "preview": "package hudson.plugins.performance.constraints;\n\nimport java.io.PrintStream;\nimport java.text.ParseException;\nimport jav"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/blocks/PreviousResultsBlock.java",
    "chars": 3403,
    "preview": "package hudson.plugins.performance.constraints.blocks;\n\nimport hudson.Extension;\nimport hudson.model.AbstractDescribable"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/constraints/blocks/TestCaseBlock.java",
    "chars": 920,
    "preview": "package hudson.plugins.performance.constraints.blocks;\n\nimport hudson.Extension;\nimport hudson.model.AbstractDescribable"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/cookie/CookieHandler.java",
    "chars": 1805,
    "preview": "package hudson.plugins.performance.cookie;\n\n\nimport org.kohsuke.stapler.Ancestor;\n\nimport javax.servlet.http.Cookie;\nimp"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/ConstraintSettings.java",
    "chars": 2482,
    "preview": "package hudson.plugins.performance.data;\n\nimport hudson.model.TaskListener;\n\n/**\n * Holds the global settings for constr"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/HttpSample.java",
    "chars": 3443,
    "preview": "package hudson.plugins.performance.data;\n\nimport hudson.plugins.performance.reports.UriReport;\n\nimport java.io.Serializa"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/PerformanceReportPosition.java",
    "chars": 908,
    "preview": "package hudson.plugins.performance.data;\n\npublic class PerformanceReportPosition {\n    private String performanceReportP"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/ReportValueSelector.java",
    "chars": 2235,
    "preview": "package hudson.plugins.performance.data;\n\nimport hudson.model.AbstractProject;\nimport hudson.model.Job;\nimport hudson.pl"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/data/TaurusFinalStats.java",
    "chars": 2353,
    "preview": "package hudson.plugins.performance.data;\n\nimport java.io.Serializable;\n\npublic class TaurusFinalStats implements Seriali"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/descriptors/ConstraintDescriptor.java",
    "chars": 751,
    "preview": "package hudson.plugins.performance.descriptors;\n\nimport hudson.DescriptorExtensionList;\nimport hudson.model.Descriptor;\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/descriptors/PerformanceReportParserDescriptor.java",
    "chars": 1029,
    "preview": "package hudson.plugins.performance.descriptors;\n\nimport hudson.DescriptorExtensionList;\nimport hudson.model.Descriptor;\n"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/details/GraphConfigurationDetail.java",
    "chars": 15590,
    "preview": "package hudson.plugins.performance.details;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOExcep"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/details/TestSuiteReportDetail.java",
    "chars": 7743,
    "preview": "package hudson.plugins.performance.details;\n\nimport hudson.model.Job;\nimport hudson.model.ModelObject;\nimport hudson.mod"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/details/TrendReportDetail.java",
    "chars": 2402,
    "preview": "package hudson.plugins.performance.details;\n\nimport hudson.model.Job;\nimport hudson.model.ModelObject;\nimport hudson.plu"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/AbstractParser.java",
    "chars": 9988,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nim"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/IagoParser.java",
    "chars": 20155,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileRead"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/JMeterCsvParser.java",
    "chars": 5764,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport java.io.*;\nimport java.nio.charset.StandardCharsets;\n\nimport edu.umd"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/JMeterParser.java",
    "chars": 7305,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileRead"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/JUnitParser.java",
    "chars": 4826,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/JmeterSummarizerParser.java",
    "chars": 4695,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport java.io.File;\nimport java.nio.charset.StandardCharsets;\nimport java."
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/LoadRunnerParser.java",
    "chars": 3816,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/LocustParser.java",
    "chars": 4194,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/ParserDetector.java",
    "chars": 6828,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport java.io.*;\nimport java.nio.charset.StandardCharsets;\nimport java.uti"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/ParserFactory.java",
    "chars": 8994,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.PrintStream"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/PerformanceReportParser.java",
    "chars": 2743,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.ExtensionList;\nimport hudson.ExtensionPoint;\nimport hudson.mo"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/TaurusParser.java",
    "chars": 5022,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport edu.umd.cs.findbugs.annotations.SuppressFBWarnings;\nimport hudson.Ex"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/parsers/WrkSummarizerParser.java",
    "chars": 9556,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.Extension;\nimport hudson.plugins.performance.data.HttpSample;"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/AbstractReport.java",
    "chars": 5784,
    "preview": "package hudson.plugins.performance.reports;\n\nimport hudson.plugins.performance.data.HttpSample;\n\nimport org.kohsuke.stap"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/ConstraintReport.java",
    "chars": 15140,
    "preview": "package hudson.plugins.performance.reports;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOExce"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/PerformanceReport.java",
    "chars": 19063,
    "preview": "package hudson.plugins.performance.reports;\n\nimport hudson.model.Run;\nimport hudson.plugins.performance.Messages;\nimport"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/ThroughputReport.java",
    "chars": 1658,
    "preview": "package hudson.plugins.performance.reports;\n\nimport java.util.List;\n\n/**\n * @author Artem Stasiuk (artem.stasuk@gmail.co"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/reports/UriReport.java",
    "chars": 22897,
    "preview": "package hudson.plugins.performance.reports;\n\nimport java.io.IOException;\nimport java.io.Serializable;\nimport java.io.Uns"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/tools/SafeMaths.java",
    "chars": 917,
    "preview": "package hudson.plugins.performance.tools;\n\nimport java.math.BigDecimal;\nimport java.math.RoundingMode;\n\npublic class Saf"
  },
  {
    "path": "src/main/java/hudson/plugins/performance/workflow/WorkflowActionsFactory.java",
    "chars": 1098,
    "preview": "package hudson.plugins.performance.workflow;\n\n\nimport hudson.Extension;\nimport hudson.model.Action;\nimport hudson.model."
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/Messages.properties",
    "chars": 1391,
    "preview": "ProjectAction.PercentageOfErrors=Percentage of errors\nProjectAction.RespondingTime=Response time\nProjectAction.Throughpu"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/Messages_es.properties",
    "chars": 665,
    "preview": "ProjectAction.PercentageOfErrors=Porcentaje de errores\nProjectAction.RespondingTime=Tiempo de respuesta\nProjectAction.Er"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/config.jelly",
    "chars": 7605,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:f=\"/lib/form\" xmlns:p=\"/lib/performance\">\n\n  <f:e"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/config.properties",
    "chars": 446,
    "preview": "\n\nPerformance\\ report=Performance report\n\nPerformance\\ threshold=Performance threshold\nThreshold.Description=\\\n   Specif"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/config_es.properties",
    "chars": 369,
    "preview": "\n\nPerformance\\ report=Informes de Rendimiento\n\nPerformance\\ threshold=Umbrales de rendimiento.\nThreshold.Description=\\\n "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/config_zh_TW.properties",
    "chars": 1176,
    "preview": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-errorUnstableResponseTimeThreshold.html",
    "chars": 412,
    "preview": "\n<div>\nThe thresholds settings should be delimited by a new line character \"\\n\".\n</div>\n<div style=\"margin:0 0 20px 0;\">"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-filterRegex.html",
    "chars": 216,
    "preview": "<div>\n<p>\n  If this field is not empty, its content will be considered as a regular expression to only take into \n  acco"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-modeEvaluation.html",
    "chars": 146,
    "preview": "<div>\n<p>\n  Standard Mode activates upper box and ignores lower box.\n</p>\n<p>\n  Expert Mode activates lower box and igno"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-persistPerformanceChart.html",
    "chars": 281,
    "preview": "<div>\n<p>\n  Persists the ErrorGraph and the RespondingTimePerTestCaseGraph in the workspace.\n</p>\n<p>\n  Cannot be done i"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-persistPerformanceCharts.html",
    "chars": 281,
    "preview": "<div>\n<p>\n  Persists the ErrorGraph and the RespondingTimePerTestCaseGraph in the workspace.\n</p>\n<p>\n  Cannot be done i"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformancePublisher/help-sourceDataFiles.html",
    "chars": 1423,
    "preview": "<div>\n    <p>\n        Specify the path to the Performance report files, relative to the <a href='ws/'>workspace root</a>"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/CVS/Entries",
    "chars": 44,
    "preview": "/index.jelly/1.3/Wed Nov 18 16:14:45 2009//\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/CVS/Repository",
    "chars": 90,
    "preview": "iceteaperf/hudson/plugins/jmeter/src/main/resources/hudson/plugins/jmeter/JMeterReportMap\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/CVS/Root",
    "chars": 50,
    "preview": ":extssh:aespy@cvs.venezia.dev.impots:/cvsroot/ice\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/index.jelly",
    "chars": 4311,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\" >\n  <l:l"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/index_es.properties",
    "chars": 77,
    "preview": "Performance\\ Breakdown\\ by\\ URI=Rendimiento por URI\nAll\\ URIs=Todas las URIs\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/PerformanceReportMap/index_fr.properties",
    "chars": 1209,
    "preview": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/TrendReportGraphs/index.jelly",
    "chars": 1619,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\">\n  <l:la"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/TrendReportGraphs/index_es.properties",
    "chars": 1163,
    "preview": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/floatingBox.jelly",
    "chars": 609,
    "preview": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\">\r\n  <j:if test=\"${from.isTrendVisibleOnProjectDashboar"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/floatingBox_es.properties",
    "chars": 44,
    "preview": "Performance\\ Trend=Tendencia de rendimiento\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/index.jelly",
    "chars": 4295,
    "preview": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\">\r\n  <l:"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/index_es.properties",
    "chars": 225,
    "preview": "Filter\\ trend\\ data=Filtrar los datos a mostrar en los grficos\nLast\\ Report=Visualizar el ltimo informe de rendimiento\nP"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/actions/PerformanceProjectAction/index_fr.properties",
    "chars": 1271,
    "preview": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/build/PerformanceTestBuild/config.jelly",
    "chars": 1297,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:f=\"/lib/form\">\n    <f:entry title=\"${%Test params"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/build/PerformanceTestBuild/config.properties",
    "chars": 481,
    "preview": "Test\\ params=Taurus tool parameters:\nVEnv\\ path=Path to \\''virtualenv\\'' binary (if empty, it should be in $PATH):\nChang"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/build/PerformanceTestBuild/help.html",
    "chars": 271,
    "preview": "<div>\r\n\tExecute <a href=\"http://gettaurus.org/?utm_source=jenkins&utm_medium=link&utm_campaign=build_step_help\">Taurus</"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/build/jenkins-report.yml",
    "chars": 154,
    "preview": "---\nreporting:\n- module: final-stats\n  dump-xml: aggregate-results.xml\n  summary: false\n  percentiles: false\n  failed-la"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/AbsoluteConstraint/config.jelly",
    "chars": 2598,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:f=\"/lib/form\" xmlns:p=\"/lib/performance\">\n  <f:bl"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/AbsoluteConstraint/config.properties",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/AbstractConstraint/help-relatedPerfReport.html",
    "chars": 328,
    "preview": "<div>\n<p>\n  Specify a report this constraint is refered to. You defined the reports above. \n  Please use only the filena"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/AbstractConstraint/help-testCase.html",
    "chars": 317,
    "preview": "<div>\n<p>\n  Specify test case/s this constraint is refered to. Possible entries:\n</p>\n<ul>\n    <li>Comma seperated list "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/RelativeConstraint/config.jelly",
    "chars": 4165,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:f=\"/lib/form\" xmlns:p=\"/lib/performance\">\n  <f:bl"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/RelativeConstraint/config.properties",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/RelativeConstraint/help-previousResultsString.html",
    "chars": 121,
    "preview": "<div>\n<p>\n  Specify a number of builds this constraint will include.\n  '*' will include all available builds.\n</p>\n</div"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/RelativeConstraint/help-timeframeEndString.html",
    "chars": 242,
    "preview": "<div>\n<p>\n  Specify a end date for the time frame. <br>\n  Supported date formats:\n <ul>\n    <li>yyyy-MM-dd HH:mm\n    <li"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/constraints/RelativeConstraint/help-timeframeStartString.html",
    "chars": 176,
    "preview": "<div>\n<p>\n  Specify a start date for the time frame. <br>\n  Supported date formats:\n <ul>\n    <li>yyyy-MM-dd HH:mm\n    <"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/CVS/Entries",
    "chars": 44,
    "preview": "/index.jelly/1.1/Fri Nov 13 11:18:05 2009//\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/CVS/Repository",
    "chars": 99,
    "preview": "iceteaperf/hudson/plugins/jmeter/src/main/resources/hudson/plugins/jmeter/GraphConfigurationDetail\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/CVS/Root",
    "chars": 50,
    "preview": ":extssh:aespy@cvs.venezia.dev.impots:/cvsroot/ice\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/index.jelly",
    "chars": 2623,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\" xmlns:f="
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/index.properties",
    "chars": 700,
    "preview": "Configure=Configure the trend graph\nConfigure.description=\\\n  Configure the trend graph of this plug-in for the current "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/GraphConfigurationDetail/index_es.properties",
    "chars": 598,
    "preview": "Configure=Configurar el grfico\nConfigure.description=\\\n  Configurar el grfico de tendencia de rendimiento para la tarea "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/TestSuiteReportDetail/index.jelly",
    "chars": 1063,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:l=\"/lib/layout\">\n  <l:layout css=\"/plugin/perform"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/TrendReportDetail/index.jelly",
    "chars": 816,
    "preview": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\" xmlns:l=\"/lib/layout\">\r\n  <l:layout css=\"/plugin/perfo"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/details/TrendReportDetail/index_es.properties",
    "chars": 1163,
    "preview": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/reports/UriReport/index.jelly",
    "chars": 3787,
    "preview": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:l=\"/lib/layout\">\r\n  <l:"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/reports/UriReport/index_es.properties",
    "chars": 102,
    "preview": "Performance\\ Summary=Resumen\r\nPerformance\\ samples=Peticiones\r\nURI=URI\r\nTime=Fecha\r\nDuration=Duracin\r\n"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/reports/UriReport/index_fr.properties",
    "chars": 1277,
    "preview": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/captionLine.jelly",
    "chars": 846,
    "preview": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\">\r\n <j:choose>\r\n <j:when test=\"${it.ifSummarizerParserU"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/captionLine_es.properties",
    "chars": 299,
    "preview": "Max=M\\u00e1x\nsamples=Peticiones\nsamples\\ diff=Diferencia peticiones\nMedian=Mediana\nMedian\\ diff=Variaci\\u00f3n de la med"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/captionLine_fr.properties",
    "chars": 1209,
    "preview": "# The MIT License\n#\n# Copyright (c) 2004-2010, Sun Microsystems, Inc.\n#\n# Permission is hereby granted, free of charge, "
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/summaryTable.jelly",
    "chars": 1930,
    "preview": "<?jelly escape-by-default='true'?>\r\n<j:jelly xmlns:j=\"jelly:core\">\r\n    <td>\r\n        ${it.samplesCount()}\r\n        <sup"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/summaryTableSummarizer.jelly",
    "chars": 289,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\">\n\n        <td>${it.getSummarizerSize()}</td>\n        <t"
  },
  {
    "path": "src/main/resources/hudson/plugins/performance/tags/taglib",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/main/resources/index.jelly",
    "chars": 436,
    "preview": "<?jelly escape-by-default='true'?>\n<!--\n  This view is used to render the plugin list page.\n\n  Since we don't really hav"
  },
  {
    "path": "src/main/resources/lib/performance/blockWrapper.jelly",
    "chars": 1192,
    "preview": "<?jelly escape-by-default='true'?>\n<j:jelly xmlns:j=\"jelly:core\" xmlns:st=\"jelly:stapler\" xmlns:d=\"jelly:define\" xmlns:l"
  },
  {
    "path": "src/main/resources/lib/performance/taglib",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/main/tools/checkstyle.xml",
    "chars": 11303,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    This configuration file was written by the eclipse-cs plugin configurati"
  },
  {
    "path": "src/main/tools/format.xml",
    "chars": 32098,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<profiles version=\"11\">\n    <profile kind=\"CodeFormatterProfile\" name=\"GWT Format"
  },
  {
    "path": "src/main/webapp/css/style.css",
    "chars": 855,
    "preview": "table.source {\n    border-style: solid;\n    border-color: #bbb;\n    border-spacing: 0;\n    border-collapse: collapse;\n  "
  },
  {
    "path": "src/main/webapp/help.html",
    "chars": 1181,
    "preview": "<div>This plugin understands the <a\r\n\thref=\"http://jakarta.apache.org/jmeter/\">JMeter</a> analysis report XML\r\nformat, <"
  },
  {
    "path": "src/main/webapp/help_es.html",
    "chars": 860,
    "preview": "<div>Este plugin es capaz de analizar los informes XML de <a\r\n\thref=\"http://jakarta.apache.org/jmeter/\">JMeter</a> y de "
  },
  {
    "path": "src/test/java/hudson/plugins/performance/AbstractGraphGenerationTest.java",
    "chars": 3094,
    "preview": "package hudson.plugins.performance;\n\nimport hudson.model.AbstractProject;\nimport hudson.model.Run;\nimport hudson.plugins"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/BaselineComparisonTest.java",
    "chars": 8576,
    "preview": "package hudson.plugins.performance;\n\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.pe"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/PerformancePipelineTest.java",
    "chars": 3067,
    "preview": "package hudson.plugins.performance;\n\nimport hudson.model.Result;\nimport hudson.slaves.DumbSlave;\nimport org.apache.commo"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/PerformancePublisherTest.java",
    "chars": 34279,
    "preview": "package hudson.plugins.performance;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.EnvVars;\nimport hudso"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/PerformanceReportMapTest.java",
    "chars": 6192,
    "preview": "package hudson.plugins.performance;\n\nimport hudson.model.Run;\nimport hudson.model.TaskListener;\nimport hudson.plugins.pe"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/TrendReportGraphsTest.java",
    "chars": 1421,
    "preview": "package hudson.plugins.performance;\n\nimport hudson.model.FreeStyleBuild;\nimport hudson.model.FreeStyleProject;\nimport hu"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/actions/ExternalBuildReportActionTest.java",
    "chars": 629,
    "preview": "package hudson.plugins.performance.actions;\n\nimport org.junit.jupiter.api.Test;\n\nimport static org.junit.jupiter.api.Ass"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/actions/PerformanceProjectActionGraphTest.java",
    "chars": 4463,
    "preview": "package hudson.plugins.performance.actions;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.model.Abstrac"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/actions/PerformanceProjectActionTest.java",
    "chars": 2444,
    "preview": "package hudson.plugins.performance.actions;\n\nimport hudson.model.FreeStyleProject;\nimport hudson.plugins.performance.Per"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/build/PerformanceTestBuildTest.java",
    "chars": 25831,
    "preview": "package hudson.plugins.performance.build;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.EnvVars;\nimport"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/constraints/ConstraintCheckerTest.java",
    "chars": 38368,
    "preview": "package hudson.plugins.performance.constraints;\n\nimport hudson.model.AbstractBuild;\nimport hudson.model.BuildListener;\ni"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/constraints/ConstraintFactoryTest.java",
    "chars": 7058,
    "preview": "package hudson.plugins.performance.constraints;\n\n\nimport hudson.model.AbstractBuild;\nimport hudson.plugins.performance.P"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/constraints/ConstraintTest.java",
    "chars": 19275,
    "preview": "package hudson.plugins.performance.constraints;\n\nimport hudson.Launcher;\nimport hudson.model.AbstractBuild;\nimport hudso"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/cookie/CookieHandlerTest.java",
    "chars": 1797,
    "preview": "package hudson.plugins.performance.cookie;\n\n\nimport org.junit.jupiter.api.Test;\nimport org.kohsuke.stapler.Ancestor;\n\nim"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/data/PerformanceReportPositionTest.java",
    "chars": 671,
    "preview": "package hudson.plugins.performance.data;\n\nimport org.junit.jupiter.api.Test;\n\nimport static org.junit.jupiter.api.Assert"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/data/ReportValueSelectorTest.java",
    "chars": 3733,
    "preview": "package hudson.plugins.performance.data;\n\nimport hudson.model.AbstractProject;\nimport hudson.plugins.performance.Perform"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/descriptors/ConstraintDescriptorTest.java",
    "chars": 1151,
    "preview": "package hudson.plugins.performance.descriptors;\n\nimport hudson.plugins.performance.constraints.AbsoluteConstraint;\nimpor"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/descriptors/PerformanceReportParserDescriptorTest.java",
    "chars": 2779,
    "preview": "package hudson.plugins.performance.descriptors;\n\nimport hudson.plugins.performance.parsers.IagoParser;\nimport hudson.plu"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/details/GraphConfigurationDetailTest.java",
    "chars": 2620,
    "preview": "package hudson.plugins.performance.details;\n\nimport hudson.model.FreeStyleProject;\nimport org.junit.jupiter.api.Test;\nim"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/details/TestSuiteReportDetailTest.java",
    "chars": 5058,
    "preview": "package hudson.plugins.performance.details;\n\nimport hudson.model.Descriptor;\nimport hudson.model.FreeStyleBuild;\nimport "
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/AbstractParserTest.java",
    "chars": 2144,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport org.jun"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/IagoParserTest.java",
    "chars": 32349,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\nimport hud"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JMeterCsvParserTest.java",
    "chars": 5269,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson."
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JMeterParserTest.java",
    "chars": 4608,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson."
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JMeterTestHelper.java",
    "chars": 567,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport java.io.File;\n\nimport hudson.plugins.performance.reports.Performance"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JUnitParserTest.java",
    "chars": 2452,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson."
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/JmeterSummarizerParserTest.java",
    "chars": 1855,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson."
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/LoadRunnerParserTest.java",
    "chars": 2132,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson."
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/LocustParserTest.java",
    "chars": 2654,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson."
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/ParserDetectorTest.java",
    "chars": 3921,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport org.junit.jupiter.api.Test;\nimport org.jvnet.hudson.test.Issue;\n\nimp"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/ParserFactoryTest.java",
    "chars": 9991,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport edu.umd.cs.findbugs.annotations.NonNull;\nimport hudson.EnvVars;\nimpo"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/TaurusParserTest.java",
    "chars": 4591,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.plugins.performance.reports.PerformanceReport;\nimport hudson."
  },
  {
    "path": "src/test/java/hudson/plugins/performance/parsers/WrkSummarizerParserTest.java",
    "chars": 5011,
    "preview": "package hudson.plugins.performance.parsers;\n\nimport hudson.model.TaskListener;\nimport hudson.plugins.performance.reports"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/reports/ConstraintReportTest.java",
    "chars": 10521,
    "preview": "package hudson.plugins.performance.reports;\n\nimport hudson.FilePath;\nimport hudson.model.AbstractBuild;\nimport hudson.mo"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/reports/PerformanceReportTest.java",
    "chars": 14649,
    "preview": "package hudson.plugins.performance.reports;\n\nimport hudson.plugins.performance.actions.PerformanceBuildAction;\nimport hu"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/reports/ThroughputReportTest.java",
    "chars": 6170,
    "preview": "package hudson.plugins.performance.reports;\n\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.pe"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/reports/UriReportTest.java",
    "chars": 4747,
    "preview": "package hudson.plugins.performance.reports;\n\nimport hudson.plugins.performance.data.HttpSample;\nimport hudson.plugins.pe"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/tools/SafeMathsTest.java",
    "chars": 1125,
    "preview": "package hudson.plugins.performance.tools;\n\nimport org.junit.jupiter.api.Test;\n\nimport static org.junit.jupiter.api.Asser"
  },
  {
    "path": "src/test/java/hudson/plugins/performance/workflow/WorkflowActionsFactoryTest.java",
    "chars": 2896,
    "preview": "package hudson.plugins.performance.workflow;\n\nimport hudson.model.Action;\nimport hudson.model.Job;\nimport hudson.model.R"
  },
  {
    "path": "src/test/resources/IagoResults.log",
    "chars": 22297,
    "preview": "INF [20140611-21:34:01.224] stats: {\"400\":84,\"client\\/available\":1,\"client\\/cancelled_connects\":0,\"client\\/closechans\":8"
  },
  {
    "path": "src/test/resources/JENKINS-16627_CSV_instead_of_XML.jtl",
    "chars": 268,
    "preview": "1393227741256,1425,GET /ordermgmt/login - Login Page,200,OK,Thread Group 1-1,text,true,3478,1016\n1393227742815,59,GET /o"
  },
  {
    "path": "src/test/resources/JMeterCsvResults.csv",
    "chars": 348,
    "preview": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes\n1393227741256,1425,GET /ordermgmt"
  },
  {
    "path": "src/test/resources/JMeterCsvResults2.csv",
    "chars": 399,
    "preview": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes,sentBytes\n2001/20/20 12:05:05.123"
  },
  {
    "path": "src/test/resources/JMeterCsvResults3.csv",
    "chars": 399,
    "preview": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes,sentBytes\n2011-21-21 14:15:25.321"
  },
  {
    "path": "src/test/resources/JMeterPublisher.csv",
    "chars": 351,
    "preview": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes\n1393227741256,1300,GET /ordermgmt"
  },
  {
    "path": "src/test/resources/JMeterPublisher_formatted_timeStamp.csv",
    "chars": 381,
    "preview": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes\n2014-02-24 07:42:21.256,1300,GET "
  },
  {
    "path": "src/test/resources/JMeterResults.jtl",
    "chars": 1200,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"14720\" lt=\"9770\" ts=\"1296846793179\" s="
  },
  {
    "path": "src/test/resources/JMeterResultsMultiLevel.jtl",
    "chars": 4404,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<testResults version=\"1.2\">\r\n<httpSample t=\"645\" lt=\"644\" ts=\"1298457003722\" s=\""
  },
  {
    "path": "src/test/resources/JMeterResultsMultiThread.jtl",
    "chars": 791,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<sample t=\"894\" lt=\"0\" ts=\"1236948710884\" s=\"true\" lb"
  },
  {
    "path": "src/test/resources/JMeterResultsOneSample.jtl",
    "chars": 217,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"2\" lt=\"9770\" ts=\"1296846793179\" s=\"tru"
  },
  {
    "path": "src/test/resources/JMeterResultsRandomUri.jtl",
    "chars": 626,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"14720\" lt=\"9770\" ts=\"1296846793179\" s="
  },
  {
    "path": "src/test/resources/JMeterResultsTenSamples.jtl",
    "chars": 1419,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"1\" lt=\"9770\" ts=\"1296846793179\" s=\"tru"
  },
  {
    "path": "src/test/resources/JMeterResultsThreeSamples.jtl",
    "chars": 487,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"1\" lt=\"9770\" ts=\"1296846793179\" s=\"tru"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults-noTimeAttribute.xml",
    "chars": 646,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite failures=\"0\" time=\"0.100\" errors=\"0\" skipped=\"0\" tests=\"1\" name=\"huds"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults-relative-thrashould-2.xml",
    "chars": 293,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite failures=\"0\" time=\"0.160\" errors=\"0\" skipped=\"0\" tests=\"1\" name=\"huds"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults-relative-thrashould.xml",
    "chars": 291,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite failures=\"0\" time=\"0.100\" errors=\"0\" skipped=\"0\" tests=\"1\" name=\"huds"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults-success-failure-error.xml",
    "chars": 680,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><testsuite errors=\"1\" failures=\"1\" hostname=\"someHostname\" name=\"tests.ATest\" tes"
  },
  {
    "path": "src/test/resources/TEST-JUnitResults.xml",
    "chars": 30134,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite failures=\"0\" time=\"0.008\" errors=\"0\" skipped=\"0\" tests=\"5\" name=\"huds"
  },
  {
    "path": "src/test/resources/TEST-results.xml",
    "chars": 10985,
    "preview": "<testsuites>\n  <testsuite errors=\"0\"\n             failures=\"0\"\n             tests=\"4\"\n             time=\"0.5798499584198"
  },
  {
    "path": "src/test/resources/TaurusPreviousBuildReport.xml",
    "chars": 7320,
    "preview": "<?xml version='1.0' encoding='UTF-8'?>\n<FinalStatus>\n    <ReportURL>https://test_url.com/summary</ReportURL>\n    <Group "
  },
  {
    "path": "src/test/resources/TaurusXMLReport.xml",
    "chars": 5597,
    "preview": "<?xml version='1.0' encoding='UTF-8'?>\n<FinalStatus>\n  <ReportURL>https://link_for_report.com/aaaa/bbb/report</ReportURL"
  },
  {
    "path": "src/test/resources/TaurusXmlWithDuration.xml",
    "chars": 9048,
    "preview": "<?xml version='1.0' encoding='UTF-8'?>\n<FinalStatus>\n    <TestDuration>3.141592</TestDuration>\n    <Group label=\"\">\n    "
  },
  {
    "path": "src/test/resources/WrkResultsLong.wrk",
    "chars": 315,
    "preview": "Running 5s test @ http://www.google.com\n  8 threads and 16 connections\n  Thread Stats   Avg      Stdev     Max   +/- Std"
  },
  {
    "path": "src/test/resources/WrkResultsQuick.wrk",
    "chars": 314,
    "preview": "Running 5s test @ http://www.google.com\n  8 threads and 16 connections\n  Thread Stats   Avg      Stdev     Max   +/- Std"
  },
  {
    "path": "src/test/resources/WrkResultsWithErrors.wrk",
    "chars": 341,
    "preview": "Running 1s test @ http://httpstat.us/500\n  1 threads and 1 connections\n  Thread Stats   Avg      Stdev     Max   +/- Std"
  },
  {
    "path": "src/test/resources/WrkResultsWithLatencyFlag.wrk",
    "chars": 410,
    "preview": "Running 1s test @ http://www.google.com\n  1 threads and 1 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stde"
  },
  {
    "path": "src/test/resources/aggregate-results.xml",
    "chars": 5349,
    "preview": "<?xml version='1.0' encoding='UTF-8'?>\n<FinalStatus>\n  <Group label=\"\">\n    <avg_ct value=\"0\">\n      <name>avg_ct</name>"
  },
  {
    "path": "src/test/resources/constraint-test.xml",
    "chars": 127869,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<testResults version=\"1.2\">\n<httpSample t=\"142\" lt=\"142\" ts=\"1448547841517\" s=\"tr"
  },
  {
    "path": "src/test/resources/emptyfile.jtl",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/test/resources/filewithtransactions.csv",
    "chars": 45052,
    "preview": "timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThrea"
  },
  {
    "path": "src/test/resources/jUnitIssue5571.xml",
    "chars": 20499,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuite errors=\"0\" failures=\"0\" name=\"com.icw.ehf.training.medicinecabinet.se"
  },
  {
    "path": "src/test/resources/jmeter.log",
    "chars": 7437,
    "preview": "2017-08-18 17:23:41,964 INFO o.a.j.u.JMeterUtils: Setting Locale to en_US\n2017-08-18 17:23:41,974 INFO o.a.j.JMeter: Loa"
  }
]

// ... and 9 more files (download for full content)

About this extraction

This page contains the full source code of the jenkinsci/performance-plugin GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 209 files (1.1 MB), approximately 311.5k tokens, and a symbol index with 1223 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!